Skip to content
Closed
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
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ abstract class GenerateEntryPointTask : DefaultTask() {

import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint;
import com.facebook.react.common.annotations.internal.LegacyArchitectureLogger;
import com.facebook.react.views.view.WindowUtilKt;
import com.facebook.react.soloader.OpenSourceMergedSoMapping;
import com.facebook.soloader.SoLoader;

Expand All @@ -93,6 +94,10 @@ abstract class GenerateEntryPointTask : DefaultTask() {
if ({{packageName}}.BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
DefaultNewArchitectureEntryPoint.load();
}

if ({{packageName}}.BuildConfig.IS_EDGE_TO_EDGE_ENABLED) {
WindowUtilKt.setEdgeToEdgeFeatureFlagOn();
}
}
}
"""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import com.android.build.api.variant.ApplicationAndroidComponentsExtension
import com.android.build.api.variant.LibraryAndroidComponentsExtension
import com.android.build.gradle.LibraryExtension
import com.facebook.react.ReactExtension
import com.facebook.react.utils.ProjectUtils.isEdgeToEdgeEnabled
import com.facebook.react.utils.ProjectUtils.isHermesEnabled
import com.facebook.react.utils.ProjectUtils.isNewArchEnabled
import java.io.File
Expand Down Expand Up @@ -39,6 +40,10 @@ internal object AgpConfiguratorUtils {
project.isNewArchEnabled(extension).toString())
ext.defaultConfig.buildConfigField(
"boolean", "IS_HERMES_ENABLED", project.isHermesEnabled.toString())
ext.defaultConfig.buildConfigField(
"boolean",
"IS_EDGE_TO_EDGE_ENABLED",
project.isEdgeToEdgeEnabled.toString())
}
}
project.pluginManager.withPlugin("com.android.application", action)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@ import com.facebook.react.ReactExtension
import com.facebook.react.model.ModelPackageJson
import com.facebook.react.utils.KotlinStdlibCompatUtils.lowercaseCompat
import com.facebook.react.utils.KotlinStdlibCompatUtils.toBooleanStrictOrNullCompat
import com.facebook.react.utils.PropertyUtils.EDGE_TO_EDGE_ENABLED
import com.facebook.react.utils.PropertyUtils.HERMES_ENABLED
import com.facebook.react.utils.PropertyUtils.NEW_ARCH_ENABLED
import com.facebook.react.utils.PropertyUtils.REACT_NATIVE_ARCHITECTURES
import com.facebook.react.utils.PropertyUtils.SCOPED_EDGE_TO_EDGE_ENABLED
import com.facebook.react.utils.PropertyUtils.SCOPED_HERMES_ENABLED
import com.facebook.react.utils.PropertyUtils.SCOPED_NEW_ARCH_ENABLED
import com.facebook.react.utils.PropertyUtils.SCOPED_REACT_NATIVE_ARCHITECTURES
Expand Down Expand Up @@ -59,6 +61,13 @@ internal object ProjectUtils {
HERMES_FALLBACK
}

internal val Project.isEdgeToEdgeEnabled: Boolean
Comment thread
zoontek marked this conversation as resolved.
Outdated
get() =
(project.hasProperty(EDGE_TO_EDGE_ENABLED) &&
project.property(EDGE_TO_EDGE_ENABLED).toString().toBoolean()) ||
Comment thread
zoontek marked this conversation as resolved.
Outdated
(project.hasProperty(SCOPED_EDGE_TO_EDGE_ENABLED) &&
project.property(SCOPED_EDGE_TO_EDGE_ENABLED).toString().toBoolean())

internal val Project.useThirdPartyJSC: Boolean
get() =
(project.hasProperty(USE_THIRD_PARTY_JSC) &&
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,14 @@ object PropertyUtils {
const val NEW_ARCH_ENABLED = "newArchEnabled"
const val SCOPED_NEW_ARCH_ENABLED = "react.newArchEnabled"

/** Public property that toggles the New Architecture */
/** Public property that toggles Hermes */
Comment thread
zoontek marked this conversation as resolved.
Outdated
const val HERMES_ENABLED = "hermesEnabled"
const val SCOPED_HERMES_ENABLED = "react.hermesEnabled"

/** Public property that toggles edge-to-edge */
const val EDGE_TO_EDGE_ENABLED = "edgeToEdgeEnabled"
const val SCOPED_EDGE_TO_EDGE_ENABLED = "react.edgeToEdgeEnabled"

/** Public property that excludes jsctooling from core */
const val USE_THIRD_PARTY_JSC = "useThirdPartyJSC"
const val SCOPED_USE_THIRD_PARTY_JSC = "react.useThirdPartyJSC"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ class GenerateEntryPointTaskTest {

import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint;
import com.facebook.react.common.annotations.internal.LegacyArchitectureLogger;
import com.facebook.react.views.view.WindowUtilKt;
import com.facebook.react.soloader.OpenSourceMergedSoMapping;
import com.facebook.soloader.SoLoader;

Expand All @@ -78,6 +79,10 @@ class GenerateEntryPointTaskTest {
if (com.facebook.react.BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
DefaultNewArchitectureEntryPoint.load();
}

if (com.facebook.react.BuildConfig.IS_EDGE_TO_EDGE_ENABLED) {
WindowUtilKt.setEdgeToEdgeFeatureFlagOn();
}
}
}
"""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import com.facebook.react.model.ModelCodegenConfig
import com.facebook.react.model.ModelPackageJson
import com.facebook.react.tests.createProject
import com.facebook.react.utils.ProjectUtils.getReactNativeArchitectures
import com.facebook.react.utils.ProjectUtils.isEdgeToEdgeEnabled
import com.facebook.react.utils.ProjectUtils.isHermesEnabled
import com.facebook.react.utils.ProjectUtils.isNewArchEnabled
import com.facebook.react.utils.ProjectUtils.needsCodegenFromPackageJson
Expand Down Expand Up @@ -98,7 +99,7 @@ class ProjectUtilsTest {
}

@Test
fun isNewArchEnabled_withDisabledViaProperty_returnsFalse() {
fun isHermesEnabled_withDisabledViaProperty_returnsFalse() {
val project = createProject()
project.extensions.extraProperties.set("hermesEnabled", "false")
assertThat(project.isHermesEnabled).isFalse()
Expand Down Expand Up @@ -150,6 +151,32 @@ class ProjectUtilsTest {
assertThat(project.isHermesEnabled).isTrue()
}

@Test
fun isEdgeToEdgeEnabled_returnsFalseByDefault() {
assertThat(createProject().isEdgeToEdgeEnabled).isFalse()
}

@Test
fun isEdgeToEdgeEnabled_withDisabledViaProperty_returnsFalse() {
val project = createProject()
project.extensions.extraProperties.set("edgeToEdgeEnabled", "false")
assertThat(project.isEdgeToEdgeEnabled).isFalse()
}

@Test
fun isEdgeToEdgeEnabled_withEnabledViaProperty_returnsTrue() {
val project = createProject()
project.extensions.extraProperties.set("edgeToEdgeEnabled", "true")
assertThat(project.isEdgeToEdgeEnabled).isTrue()
}

@Test
fun isEdgeToEdgeEnabled_withInvalidViaProperty_returnsFalse() {
val project = createProject()
project.extensions.extraProperties.set("edgeToEdgeEnabled", "¯\\_(ツ)_/¯")
assertThat(project.isEdgeToEdgeEnabled).isFalse()
}

@Test
fun needsCodegenFromPackageJson_withCodegenConfigInPackageJson_returnsTrue() {
val project = createProject()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import android.os.Build;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.Window;
import androidx.annotation.Nullable;
import com.facebook.infer.annotation.Assertions;
import com.facebook.react.bridge.Callback;
Expand All @@ -23,6 +24,7 @@
import com.facebook.react.interfaces.fabric.ReactSurface;
import com.facebook.react.internal.featureflags.ReactNativeNewArchitectureFeatureFlags;
import com.facebook.react.modules.core.PermissionListener;
import com.facebook.react.views.view.WindowUtilKt;
import com.facebook.systrace.Systrace;

/**
Expand Down Expand Up @@ -121,8 +123,16 @@ public void onCreate(Bundle savedInstanceState) {
() -> {
String mainComponentName = getMainComponentName();
final Bundle launchOptions = composeLaunchOptions();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && isWideColorGamutEnabled()) {
mActivity.getWindow().setColorMode(ActivityInfo.COLOR_MODE_WIDE_COLOR_GAMUT);
if (mActivity != null) {
Window window = mActivity.getWindow();
if (window != null) {
if (WindowUtilKt.isEdgeToEdgeFeatureFlagOn()) {
WindowUtilKt.enableEdgeToEdge(window);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && isWideColorGamutEnabled()) {
window.setColorMode(ActivityInfo.COLOR_MODE_WIDE_COLOR_GAMUT);
}
}
}
if (ReactNativeNewArchitectureFeatureFlags.enableBridgelessArchitecture()) {
mReactDelegate =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import com.facebook.react.bridge.ReadableMap
import com.facebook.react.module.annotations.ReactModule
import com.facebook.react.uimanager.DisplayMetricsHolder.getDisplayMetricsWritableMap
import com.facebook.react.uimanager.DisplayMetricsHolder.initDisplayMetricsIfNotInitialized
import com.facebook.react.views.view.isEdgeToEdgeFeatureFlagOn

/** Module that exposes Android Constants to JS. */
@ReactModule(name = NativeDeviceInfoSpec.NAME)
Expand All @@ -34,7 +35,11 @@ internal class DeviceInfoModule(reactContext: ReactApplicationContext) :

// Cache the initial dimensions for later comparison in emitUpdateDimensionsEvent
previousDisplayMetrics = displayMetrics.copy()
return mapOf("Dimensions" to displayMetrics.toHashMap())

return mapOf(
"Dimensions" to displayMetrics.toHashMap(),
"isEdgeToEdge" to isEdgeToEdgeFeatureFlagOn,
)
}

override fun onHostResume() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import com.facebook.react.common.ReactConstants
import com.facebook.react.module.annotations.ReactModule
import com.facebook.react.uimanager.DisplayMetricsHolder.getStatusBarHeightPx
import com.facebook.react.uimanager.PixelUtil
import com.facebook.react.views.view.isEdgeToEdgeFeatureFlagOn
import com.facebook.react.views.view.setStatusBarTranslucency
import com.facebook.react.views.view.setStatusBarVisibility

Expand Down Expand Up @@ -54,6 +55,12 @@ internal class StatusBarModule(reactContext: ReactApplicationContext?) :
"StatusBarModule: Ignored status bar change, current activity is null.")
return
}
if (isEdgeToEdgeFeatureFlagOn) {
FLog.w(
ReactConstants.TAG,
"StatusBarModule: Ignored status bar change, current activity is edge-to-edge.")
return
}
UiThreadUtil.runOnUiThread(
object : GuardedRunnable(reactApplicationContext) {
override fun runGuarded() {
Expand Down Expand Up @@ -82,6 +89,12 @@ internal class StatusBarModule(reactContext: ReactApplicationContext?) :
"StatusBarModule: Ignored status bar change, current activity is null.")
return
}
if (isEdgeToEdgeFeatureFlagOn) {
FLog.w(
ReactConstants.TAG,
"StatusBarModule: Ignored status bar change, current activity is edge-to-edge.")
return
}
Comment thread
zoontek marked this conversation as resolved.
UiThreadUtil.runOnUiThread(
object : GuardedRunnable(reactApplicationContext) {
override fun runGuarded() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,10 @@ import com.facebook.react.uimanager.events.EventDispatcher
import com.facebook.react.views.common.ContextUtils
import com.facebook.react.views.modal.ReactModalHostView.DialogRootViewGroup
import com.facebook.react.views.view.ReactViewGroup
import com.facebook.react.views.view.disableEdgeToEdge
import com.facebook.react.views.view.enableEdgeToEdge
import com.facebook.react.views.view.isEdgeToEdgeFeatureFlagOn
import com.facebook.react.views.view.setStatusBarTranslucency
import com.facebook.react.views.view.setSystemBarsTranslucency
import com.facebook.yoga.annotations.DoNotStrip

/**
Expand All @@ -81,16 +83,19 @@ public class ReactModalHostView(context: ThemedReactContext) :
public var transparent: Boolean = false
public var onShowListener: DialogInterface.OnShowListener? = null
public var onRequestCloseListener: OnRequestCloseListener? = null

public var statusBarTranslucent: Boolean = false
get() = field || isEdgeToEdgeFeatureFlagOn
set(value) {
field = value
createNewDialog = true
createNewDialog = !isEdgeToEdgeFeatureFlagOn
}

public var navigationBarTranslucent: Boolean = false
get() = field || isEdgeToEdgeFeatureFlagOn
set(value) {
field = value
createNewDialog = true
createNewDialog = !isEdgeToEdgeFeatureFlagOn
}

public var animationType: String? = null
Expand Down Expand Up @@ -378,9 +383,10 @@ public class ReactModalHostView(context: ThemedReactContext) :
}

// Navigation bar cannot be translucent without status bar being translucent too
dialogWindow.setSystemBarsTranslucency(navigationBarTranslucent)

if (!navigationBarTranslucent) {
if (navigationBarTranslucent) {
dialogWindow.enableEdgeToEdge()
} else {
dialogWindow.disableEdgeToEdge()
dialogWindow.setStatusBarTranslucency(statusBarTranslucent)
}

Expand Down Expand Up @@ -416,6 +422,13 @@ public class ReactModalHostView(context: ThemedReactContext) :
val dialogWindowInsetsController =
WindowInsetsControllerCompat(dialogWindow, dialogWindow.decorView)

if (isEdgeToEdgeFeatureFlagOn) {
activityWindowInsetsController.systemBarsBehavior =
WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
dialogWindowInsetsController.systemBarsBehavior =
WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
}

dialogWindowInsetsController.isAppearanceLightStatusBars =
activityWindowInsetsController.isAppearanceLightStatusBars

Expand Down
Loading
Loading