From f46046027455c35ca4a63b2e699300111591345a Mon Sep 17 00:00:00 2001 From: Chris Bobbe Date: Tue, 19 May 2020 11:21:51 -0700 Subject: [PATCH] android build: Enable "autolinking". Part of the RN v0.59 -> v0.60 upgrade [1]. (Or, at least, RN and most library maintainers assume it is done as such.) This must happen at or after the upgrade because autolinking is a new feature. "Autolinking" [2] aims to make the "react-native link" command unnecessary, so that when we add a module with native code, all we have to do for the module to be included is run `yarn add`. (Other native-code changes, such as calling functions that the module provides, may still be necessary.) So, for Android: 1. As indicated in the doc [2], unlink everything from Android. As done in rk-for-zulip/zulip-mobile@6b50b1521, we do this with a script, but here, we tell `react-native unlink` to only unlink from Android. To be as exhaustive as possible, we tell it to unlink *all dependencies* in our package.json. Thankfully, if one isn't already linked, unlinking it is a no-op: ``` for dep in `tools/deps`; do react-native unlink --platforms=android "$dep" done ``` As in rk-for-zulip/zulip-mobile@6b50b1521, it looks like a custom script in Sentry removed some setup that we want to remain intact. So, exclude these from the commit: - In `ios/ZulipMobile.xcodeproj/project.pbxproj`, removing the "Upload Debug Symbols to Sentry" PBXShellScriptBuildPhase. We don't want to touch the iOS side at all right now. - In `android/app/build.gradle`, the removal of the line: ``` apply from: "../../node_modules/@sentry/react-native/sentry.gradle" ``` Strangely, `react-native unlink`'s changes in MainApplication.java did not touch the list returned by `getPackages`, but it did remove the imports that many of these list items depend on. So, remove these list items, taking note, for a future step, that a few are left intact: - `new MainReactPackage()` - `new ZulipNativePackage()` - `new NotificationsPackage()` - `new SharingPackage()` 2. Apply the Android-side changes from facebook/react-native@261197d85. In `getPackages`, this removes `MainReactPackage` and gives a new form to put the references to `ZulipNativePackage`, `NotificationsPackage`, and `SharingPackage`. 3. Now, go back to `react-native-unimodules` [3] and follow the "react-native >= 0.60" branch of the "Configure Android" instructions. We had to make some trivial changes in `MainApplication.java`; we push to the list at the now-existing `packages` variable instead of changing the literal list that was previously returned without being stored in a variable. 4. Add a `react-native.config.js` file, as the recommended way [2] to say we don't want certain modules to be linked. For details on `react-native-vector-icons`, see a commit earlier in this series that solidified our choice not to link `VectorIconsPackage`. 5. To compare the list of linked packages before and after this commit, note that in both cases, the list to be observed is the one returned by the `getPackages` implementation in `MainApplication.java`. Autolinking introduces an auto-generated `PackageList` class in `android/app/build/generated/rncli/src/main/java/com/facebook/react/PackageList.java` with a `getPackages` method of its own, which helps compose that list of packages we're observing. The `getPackages` implementation is auto-generated when you build for Android. So, compare (by alphebetizing and diffing) the list before autolinking with the new list put together with help from that auto-generated code. They are the same, so, job done. [1]: https://react-native-community.github.io/upgrade-helper/?from=0.59.10&to=0.60.6 [2]: https://github.com/react-native-community/cli/blob/master/docs/autolinking.md [3]: https://github.com/unimodules/react-native-unimodules --- android/app/build.gradle | 16 ++---- .../java/com/zulipmobile/MainApplication.java | 52 +++++++------------ android/settings.gradle | 27 ++-------- react-native.config.js | 40 ++++++++++++++ 4 files changed, 67 insertions(+), 68 deletions(-) create mode 100644 react-native.config.js diff --git a/android/app/build.gradle b/android/app/build.gradle index c25529c5a8..535dd51138 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -230,18 +230,6 @@ repositories { } dependencies { - implementation project(':@react-native-community_async-storage') - implementation project(':@sentry_react-native') - implementation project(':@react-native-community_netinfo') - implementation project(':react-native-document-picker') - implementation project(':react-native-webview') - implementation project(':react-native-text-input-reset') - implementation project(':react-native-image-picker') - implementation project(':react-native-orientation') - implementation project(':react-native-photo-view') - implementation project(':rn-fetch-blob') - implementation project(':react-native-sound') - implementation project(':react-native-device-info') implementation fileTree(dir: "libs", include: ["*.jar"]) implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation 'androidx.appcompat:appcompat:1.0.0' @@ -279,3 +267,7 @@ tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all { jvmTarget = "1.8" } } + +// Necessary for Autolinking; see facebook/react-native@261197d85 +apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); +applyNativeModulesAppBuildGradle(project) diff --git a/android/app/src/main/java/com/zulipmobile/MainApplication.java b/android/app/src/main/java/com/zulipmobile/MainApplication.java index 9dbc188d1c..41023ffbea 100644 --- a/android/app/src/main/java/com/zulipmobile/MainApplication.java +++ b/android/app/src/main/java/com/zulipmobile/MainApplication.java @@ -3,29 +3,18 @@ import android.app.Application; import android.util.Log; +import com.facebook.react.PackageList; import com.facebook.hermes.reactexecutor.HermesExecutorFactory; import com.facebook.react.bridge.JavaScriptExecutorFactory; -import com.RNFetchBlob.RNFetchBlobPackage; import com.facebook.react.ReactApplication; import com.facebook.react.ReactNativeHost; import com.facebook.react.ReactPackage; -import com.facebook.react.shell.MainReactPackage; import com.facebook.soloader.SoLoader; -import com.github.yamill.orientation.OrientationPackage; -import com.imagepicker.ImagePickerPackage; -import com.learnium.RNDeviceInfo.RNDeviceInfo; -import com.nikolaiwarner.RNTextInputReset.RNTextInputResetPackage; -import com.reactnative.photoview.PhotoViewPackage; -import com.reactnativecommunity.asyncstorage.AsyncStoragePackage; -import com.reactnativecommunity.netinfo.NetInfoPackage; -import com.reactnativecommunity.webview.RNCWebViewPackage; -import com.zmxv.RNSound.RNSoundPackage; -import io.github.elyx0.reactnativedocumentpicker.DocumentPickerPackage; -import io.sentry.RNSentryPackage; import java.util.Arrays; import java.util.List; import org.unimodules.adapters.react.ModuleRegistryAdapter; import org.unimodules.adapters.react.ReactModuleRegistryProvider; +import org.unimodules.core.interfaces.SingletonModule; import com.zulipmobile.generated.BasePackageList; import com.zulipmobile.notifications.ConversationMap; @@ -47,25 +36,24 @@ public boolean getUseDeveloperSupport() { @Override protected List getPackages() { - return Arrays.asList( - new MainReactPackage(), - new AsyncStoragePackage(), - new NetInfoPackage(), - new DocumentPickerPackage(), - new RNCWebViewPackage(), - new RNTextInputResetPackage(), - new ImagePickerPackage(), - new OrientationPackage(), - new RNSentryPackage(), - new PhotoViewPackage(), - new RNFetchBlobPackage(), - new RNSoundPackage(), - new RNDeviceInfo(), - new ZulipNativePackage(), - new NotificationsPackage(), - new SharingPackage(), - new ModuleRegistryAdapter(mModuleRegistryProvider) - ); + // Autolinked packages. + // + // To check what's included, see the + // `getPackages` implementation, which is auto-generated + // (android/app/build/generated/rncli/src/main/java/com/facebook/react/PackageList.java): + @SuppressWarnings("UnnecessaryLocalVariable") + List packages = new PackageList(this).getPackages(); + + // Packages that should be linked, but can't be with + // autolinking: + packages.add(new ZulipNativePackage()); + packages.add(new NotificationsPackage()); + packages.add(new SharingPackage()); + + // Unimodules: + packages.add(new ModuleRegistryAdapter(mModuleRegistryProvider)); + + return packages; } @Override diff --git a/android/settings.gradle b/android/settings.gradle index 71918e60c4..5b5c834662 100644 --- a/android/settings.gradle +++ b/android/settings.gradle @@ -1,31 +1,10 @@ rootProject.name = 'ZulipMobile' +apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); +applyNativeModulesSettingsGradle(settings) + apply from: '../node_modules/react-native-unimodules/gradle.groovy' includeUnimodulesProjects() -include ':@react-native-community_async-storage' -project(':@react-native-community_async-storage').projectDir = new File(rootProject.projectDir, '../node_modules/@react-native-community/async-storage/android') -include ':@sentry_react-native' -project(':@sentry_react-native').projectDir = new File(rootProject.projectDir, '../node_modules/@sentry/react-native/android') -include ':@react-native-community_netinfo' -project(':@react-native-community_netinfo').projectDir = new File(rootProject.projectDir, '../node_modules/@react-native-community/netinfo/android') -include ':react-native-document-picker' -project(':react-native-document-picker').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-document-picker/android') -include ':react-native-webview' -project(':react-native-webview').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-webview/android') -include ':react-native-text-input-reset' -project(':react-native-text-input-reset').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-text-input-reset/android') -include ':react-native-image-picker' -project(':react-native-image-picker').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-image-picker/android') -include ':react-native-orientation' -project(':react-native-orientation').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-orientation/android') -include ':react-native-photo-view' -project(':react-native-photo-view').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-photo-view/android') -include ':rn-fetch-blob' -project(':rn-fetch-blob').projectDir = new File(rootProject.projectDir, '../node_modules/rn-fetch-blob/android') -include ':react-native-sound' -project(':react-native-sound').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-sound/android') -include ':react-native-device-info' -project(':react-native-device-info').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-device-info/android') include ':app' diff --git a/react-native.config.js b/react-native.config.js new file mode 100644 index 0000000000..fa1d2a45e4 --- /dev/null +++ b/react-native.config.js @@ -0,0 +1,40 @@ +/** + * See https://github.com/react-native-community/cli/blob/master/docs/configuration.md. + * + * To print the full config from the React Native CLI, run + * `react-native config`. + */ +module.exports = { + /** + * See https://github.com/react-native-community/cli/blob/master/docs/dependencies.md. + * + * Currently, we only use this to blacklist some native-code + * libraries, per-platform, that we don't want to be linked with + * "autolinking". + * + * For more about "autolinking", see + * https://github.com/react-native-community/cli/blob/master/docs/autolinking.md. + */ + dependencies: { + 'react-native-notifications': { + platforms: { + // We don't use this Wix library in the Android build. See 01b33ad31. + android: null, + }, + }, + 'react-native-screens': { + platforms: { + // We haven't enabled `react-native-screens` yet, that's + // #4111. + android: null, + }, + }, + 'react-native-vector-icons': { + platforms: { + // We're using a setup that doesn't involve linking + // `VectorIconsPackage` on Android. + android: null, + }, + }, + }, +};