Files
native/src/lib/platform-capabilities.ts
Linus Rath 341cdb0e61 feat: build a Google Play bundle alongside the GitHub APK
The app now has two product flavors. `github` is the sideloaded APK as
before, with the same package name and its in-app updater. `play` is a
bundle for Google Play as `org.bulwarkmail.mobile`, without the updater
or the installer permission, since Play forbids apps updating themselves.

- `release-android.yml` builds the Play bundle in a second job, checks
  its signer, package name and permissions, and keeps it as an artifact.
  With `PLAY_SERVICE_ACCOUNT_JSON` set it uploads it to internal testing.
- The Play flavor uses the new Firebase project; the GitHub flavor keeps
  the old one until the app re-registers its token when it changes.
- Widget clicks and the device-sync account type follow the package name.
- Photos come from the system picker without asking for media access,
  and the unused microphone permission from expo-camera is removed.
- A manual workflow run without a tag no longer replaces the APK of the
  latest release.
2026-10-20 12:56:44 +02:00

38 lines
1.7 KiB
TypeScript

// Single source of truth for "this feature only exists on some platforms", so
// the UI, the stores and the native bridges all agree on what is reachable.
import { NativeModules, Platform } from 'react-native';
/**
* Where this Android build is distributed: the product flavor in
* android/app/build.gradle, read from the BulwarkBuild native module. A build
* without the module (older native code) is the sideloaded GitHub APK.
*/
export const androidDistribution: 'github' | 'play' =
Platform.OS === 'android' && NativeModules.BulwarkBuild?.distribution === 'play' ? 'play' : 'github';
/**
* In-app sideload updates: download the release APK from GitHub and hand it to
* the system package installer (see `lib/install-update`).
*
* Only the GitHub build on Android. App Store Review guideline 2.5.2 forbids an
* iOS app from downloading and installing executable code, and Google Play
* forbids an app updating itself outside Play; the Play build also lacks the
* installer permission. iOS builds are updated through TestFlight or the App
* Store, the Play build through Play. The whole updater surface (banner,
* settings pane, launch-time check) is hidden when this is false.
*/
export const supportsSideloadUpdates = Platform.OS === 'android' && androidDistribution === 'github';
/**
* Device sync: address books and calendars in Android's Contacts and Calendar
* providers, under an account of the app's own type (#34,
* docs/device-sync.md).
*
* Android only: iOS has no third-party sync-provider API for either. The UI
* also needs the native module (`isDeviceSyncAvailable()` in
* `device-sync/native`), so a build without it hides the feature instead of
* failing.
*/
export const supportsDeviceSync = Platform.OS === 'android';