diff --git a/.gitignore b/.gitignore index 4fefd6dad62138..5621d72aac982d 100644 --- a/.gitignore +++ b/.gitignore @@ -38,6 +38,7 @@ project.xcworkspace /packages/react-native/ReactAndroid/gradlew.bat /packages/react-native/ReactAndroid/external-artifacts/build/ /packages/react-native/ReactAndroid/external-artifacts/artifacts/ +/packages/react-native/ReactAndroid/flipper-integration/build/ /packages/react-native/ReactAndroid/hermes-engine/build/ /packages/react-native/ReactAndroid/hermes-engine/.cxx/ /packages/react-native/template/android/app/build/ diff --git a/ReactAndroid/flipper-integration/.npmignore b/ReactAndroid/flipper-integration/.npmignore new file mode 100644 index 00000000000000..b1bfa20d8f87b2 --- /dev/null +++ b/ReactAndroid/flipper-integration/.npmignore @@ -0,0 +1,2 @@ +# Make sure we never publish the build folders to npm. +build/ diff --git a/ReactAndroid/flipper-integration/build.gradle b/ReactAndroid/flipper-integration/build.gradle new file mode 100644 index 00000000000000..5094bd983cfc5f --- /dev/null +++ b/ReactAndroid/flipper-integration/build.gradle @@ -0,0 +1,61 @@ +/* + * 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. + */ + +plugins { + id("com.android.library") + id("maven-publish") + id("signing") + id("org.jetbrains.kotlin.android") +} + +group = "com.facebook.react" +version = parent.publishing_version + +repositories { + // Normally RNGP will set repositories for all modules, + // but when consumed from source, we need to re-declare + // those repositories as there is no app module there. + mavenCentral() + google() +} + +android { + compileSdk 33 + buildToolsVersion = "33.0.0" + namespace "com.facebook.react.flipper" + + defaultConfig { + minSdk = 21 + } + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 + } + + kotlin { + jvmToolchain(11) + } + + dependencies { + implementation project(':packages:react-native:ReactAndroid') + debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}") + debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") { + exclude group:'com.squareup.okhttp3', module:'okhttp' + } + debugImplementation("com.facebook.flipper:flipper-fresco-plugin:${FLIPPER_VERSION}") + } + + publishing { + multipleVariants { + withSourcesJar() + allVariants() + } + } +} + +apply from: "../publish.gradle" diff --git a/ReactAndroid/flipper-integration/gradle.properties b/ReactAndroid/flipper-integration/gradle.properties new file mode 100644 index 00000000000000..637bb4b57cce3d --- /dev/null +++ b/ReactAndroid/flipper-integration/gradle.properties @@ -0,0 +1,2 @@ +# Version of flipper SDK to use for this integration +FLIPPER_VERSION=0.182.0 \ No newline at end of file diff --git a/ReactAndroid/flipper-integration/src/debug/java/com/facebook/react/flipper/ReactNativeFlipper.kt b/ReactAndroid/flipper-integration/src/debug/java/com/facebook/react/flipper/ReactNativeFlipper.kt new file mode 100644 index 00000000000000..ecbef22f773105 --- /dev/null +++ b/ReactAndroid/flipper-integration/src/debug/java/com/facebook/react/flipper/ReactNativeFlipper.kt @@ -0,0 +1,62 @@ +/* + * 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.flipper + +import android.content.Context +import com.facebook.flipper.android.AndroidFlipperClient +import com.facebook.flipper.android.utils.FlipperUtils +import com.facebook.flipper.plugins.crashreporter.CrashReporterPlugin +import com.facebook.flipper.plugins.databases.DatabasesFlipperPlugin +import com.facebook.flipper.plugins.fresco.FrescoFlipperPlugin +import com.facebook.flipper.plugins.inspector.DescriptorMapping +import com.facebook.flipper.plugins.inspector.InspectorFlipperPlugin +import com.facebook.flipper.plugins.network.FlipperOkhttpInterceptor +import com.facebook.flipper.plugins.network.NetworkFlipperPlugin +import com.facebook.flipper.plugins.sharedpreferences.SharedPreferencesFlipperPlugin +import com.facebook.react.ReactInstanceEventListener +import com.facebook.react.ReactInstanceManager +import com.facebook.react.bridge.ReactContext +import com.facebook.react.modules.network.NetworkingModule + +/** + * Class responsible of loading Flipper inside your React Native application. This is the debug + * flavor of it. Here you can add your own plugins and customize the Flipper setup. + */ +object ReactNativeFlipper { + @JvmStatic + fun initializeFlipper(context: Context, reactInstanceManager: ReactInstanceManager) { + if (FlipperUtils.shouldEnableFlipper(context)) { + val client = AndroidFlipperClient.getInstance(context) + client.addPlugin(InspectorFlipperPlugin(context, DescriptorMapping.withDefaults())) + client.addPlugin(DatabasesFlipperPlugin(context)) + client.addPlugin(SharedPreferencesFlipperPlugin(context)) + client.addPlugin(CrashReporterPlugin.getInstance()) + val networkFlipperPlugin = NetworkFlipperPlugin() + NetworkingModule.setCustomClientBuilder { builder -> + builder.addNetworkInterceptor(FlipperOkhttpInterceptor(networkFlipperPlugin)) + } + client.addPlugin(networkFlipperPlugin) + client.start() + + // Fresco Plugin needs to ensure that ImagePipelineFactory is initialized + // Hence we run if after all native modules have been initialized + val currentReactContext = reactInstanceManager.currentReactContext + if (currentReactContext == null) { + reactInstanceManager.addReactInstanceEventListener( + object : ReactInstanceEventListener { + override fun onReactContextInitialized(context: ReactContext) { + reactInstanceManager.removeReactInstanceEventListener(this) + context.runOnNativeModulesQueueThread { client.addPlugin(FrescoFlipperPlugin()) } + } + }) + } else { + client.addPlugin(FrescoFlipperPlugin()) + } + } + } +} diff --git a/packages/rn-tester/android/app/src/release/java/com/facebook/react/uiapp/ReactNativeFlipper.java b/ReactAndroid/flipper-integration/src/release/java/com/facebook/react/flipper/ReactNativeFlipper.kt similarity index 61% rename from packages/rn-tester/android/app/src/release/java/com/facebook/react/uiapp/ReactNativeFlipper.java rename to ReactAndroid/flipper-integration/src/release/java/com/facebook/react/flipper/ReactNativeFlipper.kt index 26cc2168b99867..e44f63d8d1db66 100644 --- a/packages/rn-tester/android/app/src/release/java/com/facebook/react/uiapp/ReactNativeFlipper.java +++ b/ReactAndroid/flipper-integration/src/release/java/com/facebook/react/flipper/ReactNativeFlipper.kt @@ -5,17 +5,19 @@ * LICENSE file in the root directory of this source tree. */ -package com.facebook.react.uiapp; +package com.facebook.react.flipper -import android.content.Context; -import com.facebook.react.ReactInstanceManager; +import android.content.Context +import com.facebook.react.ReactInstanceManager /** * Class responsible of loading Flipper inside your React Native application. This is the release * flavor of it so it's empty as we don't want to load Flipper. */ -public class ReactNativeFlipper { - public static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) { +object ReactNativeFlipper { + @Suppress("UNUSED_PARAMETER") + @JvmStatic + fun initializeFlipper(context: Context, reactInstanceManager: ReactInstanceManager) { // Do nothing as we don't want to initialize Flipper on Release. } } diff --git a/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/DependencyUtils.kt b/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/DependencyUtils.kt index ecf083007aace5..779247ff48b139 100644 --- a/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/DependencyUtils.kt +++ b/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/DependencyUtils.kt @@ -45,7 +45,8 @@ internal object DependencyUtils { /** * This method takes care of configuring the resolution strategy for both the app and all the 3rd * party libraries which are auto-linked. Specifically it takes care of: - * - Forcing the react-android/hermes-android version to the one specified in the package.json + * - Forcing the react-android/hermes-android/flipper-integration version to the one specified in + * the package.json * - Substituting `react-native` with `react-android` and `hermes-engine` with `hermes-android`. */ fun configureDependencies( @@ -83,6 +84,7 @@ internal object DependencyUtils { configuration.resolutionStrategy.force( "${groupString}:react-android:${versionString}", "${groupString}:hermes-android:${versionString}", + "${groupString}:flipper-integration:${versionString}", ) } } diff --git a/packages/rn-tester/android/app/build.gradle b/packages/rn-tester/android/app/build.gradle index 4b69fa54503f89..ef4f725792d28d 100644 --- a/packages/rn-tester/android/app/build.gradle +++ b/packages/rn-tester/android/app/build.gradle @@ -156,14 +156,11 @@ android { dependencies { // Build React Native from source implementation project(':packages:react-native:ReactAndroid') + implementation project(':packages:react-native:ReactAndroid:flipper-integration') // Consume Hermes as built from source only for the Hermes variant. hermesImplementation(project(":packages:react-native:ReactAndroid:hermes-engine")) - debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}") - debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") - debugImplementation("com.facebook.flipper:flipper-fresco-plugin:${FLIPPER_VERSION}") - jscImplementation jscFlavor androidTestImplementation 'junit:junit:4.12' diff --git a/packages/rn-tester/android/app/gradle.properties b/packages/rn-tester/android/app/gradle.properties index 1d6bf9759649a1..afa8164ce4cf34 100644 --- a/packages/rn-tester/android/app/gradle.properties +++ b/packages/rn-tester/android/app/gradle.properties @@ -4,9 +4,6 @@ org.gradle.parallel=true android.useAndroidX=true android.enableJetifier=true -# Version of flipper SDK to use with React Native -FLIPPER_VERSION=0.182.0 - # RN-Tester is building with NewArch always enabled newArchEnabled=true # RN-Tester is running with Hermes enabled and filtering variants with enableHermesOnlyInVariants diff --git a/packages/rn-tester/android/app/src/debug/java/com/facebook/react/uiapp/ReactNativeFlipper.java b/packages/rn-tester/android/app/src/debug/java/com/facebook/react/uiapp/ReactNativeFlipper.java deleted file mode 100644 index 28579c8450d8ef..00000000000000 --- a/packages/rn-tester/android/app/src/debug/java/com/facebook/react/uiapp/ReactNativeFlipper.java +++ /dev/null @@ -1,74 +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.uiapp; - -import android.content.Context; -import com.facebook.flipper.android.AndroidFlipperClient; -import com.facebook.flipper.android.utils.FlipperUtils; -import com.facebook.flipper.core.FlipperClient; -import com.facebook.flipper.plugins.crashreporter.CrashReporterPlugin; -import com.facebook.flipper.plugins.databases.DatabasesFlipperPlugin; -import com.facebook.flipper.plugins.fresco.FrescoFlipperPlugin; -import com.facebook.flipper.plugins.inspector.DescriptorMapping; -import com.facebook.flipper.plugins.inspector.InspectorFlipperPlugin; -import com.facebook.flipper.plugins.network.FlipperOkhttpInterceptor; -import com.facebook.flipper.plugins.network.NetworkFlipperPlugin; -import com.facebook.flipper.plugins.react.ReactFlipperPlugin; -import com.facebook.flipper.plugins.sharedpreferences.SharedPreferencesFlipperPlugin; -import com.facebook.react.ReactInstanceEventListener; -import com.facebook.react.ReactInstanceManager; -import com.facebook.react.bridge.ReactContext; -import com.facebook.react.modules.network.NetworkingModule; -import okhttp3.OkHttpClient; - -public class ReactNativeFlipper { - public static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) { - if (FlipperUtils.shouldEnableFlipper(context)) { - final FlipperClient client = AndroidFlipperClient.getInstance(context); - - client.addPlugin(new InspectorFlipperPlugin(context, DescriptorMapping.withDefaults())); - client.addPlugin(new ReactFlipperPlugin()); - client.addPlugin(new DatabasesFlipperPlugin(context)); - client.addPlugin(new SharedPreferencesFlipperPlugin(context)); - client.addPlugin(CrashReporterPlugin.getInstance()); - - NetworkFlipperPlugin networkFlipperPlugin = new NetworkFlipperPlugin(); - NetworkingModule.setCustomClientBuilder( - new NetworkingModule.CustomClientBuilder() { - @Override - public void apply(OkHttpClient.Builder builder) { - builder.addNetworkInterceptor(new FlipperOkhttpInterceptor(networkFlipperPlugin)); - } - }); - client.addPlugin(networkFlipperPlugin); - client.start(); - - // Fresco Plugin needs to ensure that ImagePipelineFactory is initialized - // Hence we run if after all native modules have been initialized - ReactContext reactContext = reactInstanceManager.getCurrentReactContext(); - if (reactContext == null) { - reactInstanceManager.addReactInstanceEventListener( - new ReactInstanceEventListener() { - @Override - public void onReactContextInitialized(ReactContext reactContext) { - reactInstanceManager.removeReactInstanceEventListener(this); - reactContext.runOnNativeModulesQueueThread( - new Runnable() { - @Override - public void run() { - client.addPlugin(new FrescoFlipperPlugin()); - } - }); - } - }); - } else { - client.addPlugin(new FrescoFlipperPlugin()); - } - } - } -} diff --git a/packages/rn-tester/android/app/src/main/java/com/facebook/react/uiapp/RNTesterApplication.java b/packages/rn-tester/android/app/src/main/java/com/facebook/react/uiapp/RNTesterApplication.java index 1657cdc08894fb..4516720db9a72c 100644 --- a/packages/rn-tester/android/app/src/main/java/com/facebook/react/uiapp/RNTesterApplication.java +++ b/packages/rn-tester/android/app/src/main/java/com/facebook/react/uiapp/RNTesterApplication.java @@ -19,6 +19,7 @@ import com.facebook.react.config.ReactFeatureFlags; import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint; import com.facebook.react.defaults.DefaultReactNativeHost; +import com.facebook.react.flipper.ReactNativeFlipper; import com.facebook.react.module.model.ReactModuleInfo; import com.facebook.react.module.model.ReactModuleInfoProvider; import com.facebook.react.shell.MainReactPackage; diff --git a/settings.gradle.kts b/settings.gradle.kts index f717425c5652c8..c45ff9f6403010 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -30,5 +30,10 @@ include(":packages:react-native:ReactAndroid:hermes-engine") project(":packages:react-native:ReactAndroid:hermes-engine").projectDir = file("ReactAndroid/hermes-engine/") +include(":packages:react-native:ReactAndroid:flipper-integration") + +project(":packages:react-native:ReactAndroid:flipper-integration").projectDir = + file("ReactAndroid/flipper-integration/") + // Include this so the build can recognize plugins {id("com.facebook.react")} includeBuild("packages/react-native-gradle-plugin/") diff --git a/template/android/app/build.gradle b/template/android/app/build.gradle index 55ffbed186c73f..3e65f4230fe8d8 100644 --- a/template/android/app/build.gradle +++ b/template/android/app/build.gradle @@ -106,13 +106,8 @@ android { dependencies { // The version of react-native is set by the React Native Gradle Plugin implementation("com.facebook.react:react-android") + implementation("com.facebook.react:flipper-integration") - debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}") - debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") { - exclude group:'com.squareup.okhttp3', module:'okhttp' - } - - debugImplementation("com.facebook.flipper:flipper-fresco-plugin:${FLIPPER_VERSION}") if (hermesEnabled.toBoolean()) { implementation("com.facebook.react:hermes-android") } else { diff --git a/template/android/gradle.properties b/template/android/gradle.properties index a3b2fa12490544..a46a5b90fad015 100644 --- a/template/android/gradle.properties +++ b/template/android/gradle.properties @@ -24,9 +24,6 @@ android.useAndroidX=true # Automatically convert third-party libraries to use AndroidX android.enableJetifier=true -# Version of flipper SDK to use with React Native -FLIPPER_VERSION=0.182.0 - # Use this property to specify which architecture you want to build. # You can also override it from the CLI using # ./gradlew -PreactNativeArchitectures=x86_64