Skip to content

[media-library][android] Remove promises #38301

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: @wenszel/feat/medialibrary-remove-callbacks
Choose a base branch
from

Conversation

Wenszel
Copy link
Collaborator

@Wenszel Wenszel commented Jul 24, 2025

Why

Depends on #38226, which aims to rewrite the MediaLibrary module to be coroutine-based.

How

  • Refactored runActionWithPermissions to return a value instead of just triggering an intent.
    In order to remove Promise usage from functions relying on runActionWithPermissions, it was necessary to make runActionWithPermissions return a value, instead of just running an intent.
    Was:
    save action -> run intent -> handle result and execute saved action in OnActivityResult
    Is:
    register launcher using RegisterActivityContract -> launch it as a suspendable function within runActionWithPermissions
  • Replaced all promise.reject usages with CodedException
  • Rewrote native tests, as the constructors no longer take a Promise.
  • Refactored initializeDefaultAssetsAsync in the TS tests to make the logic more verbose.
  • Removed moduleCoroutineScope, and replaced its usage with the Coroutine annotation in the AsyncFunction declarations.

Test Plan

Tested on BareExpo ✅

Screenshot_20250725_083158

@expo-bot expo-bot added the bot: suggestions ExpoBot has some suggestions label Jul 24, 2025
@expo-bot
Copy link
Collaborator

expo-bot commented Jul 24, 2025

The Pull Request introduced fingerprint changes against the base commit: 9dd9e3d

Fingerprint diff
[
  {
    "op": "changed",
    "beforeSource": {
      "type": "file",
      "filePath": "../../packages/@expo/config-plugins/build/android/Manifest.js",
      "reasons": [
        "expoConfigPlugins"
      ],
      "hash": "82b0eeba42681de6fab42cb9180325746d3dcf27"
    },
    "afterSource": {
      "type": "file",
      "filePath": "../../packages/@expo/config-plugins/build/android/Manifest.js",
      "reasons": [
        "expoConfigPlugins"
      ],
      "hash": "e313d4674ae422e378620af632e5a9a98c0ab8cf"
    }
  },
  {
    "op": "changed",
    "beforeSource": {
      "type": "dir",
      "filePath": "../../node_modules/expo",
      "reasons": [
        "rncoreAutolinkingAndroid",
        "rncoreAutolinkingIos"
      ],
      "hash": "a81ba8da3715f2cef415afe98c39373db33610cd"
    },
    "afterSource": {
      "type": "dir",
      "filePath": "../../node_modules/expo",
      "reasons": [
        "rncoreAutolinkingAndroid",
        "rncoreAutolinkingIos"
      ],
      "hash": "cb85d84020bf2e3ad90bf7cdfc2f63798f451782"
    }
  },
  {
    "op": "changed",
    "beforeSource": {
      "type": "dir",
      "filePath": "../../packages/expo",
      "reasons": [
        "expoAutolinkingIos",
        "expoAutolinkingAndroid",
        "expoConfigPlugins",
        "expoConfigPlugins"
      ],
      "hash": "aa2a73dac94fa0e384260ceb2cb7ca018ad1622e"
    },
    "afterSource": {
      "type": "dir",
      "filePath": "../../packages/expo",
      "reasons": [
        "expoAutolinkingIos",
        "expoAutolinkingAndroid",
        "expoConfigPlugins",
        "expoConfigPlugins"
      ],
      "hash": "052e87e99f480fb8f93fe8ec83e295f16e4c6189"
    }
  },
  {
    "op": "changed",
    "beforeSource": {
      "type": "dir",
      "filePath": "../../packages/expo-asset/android",
      "reasons": [
        "expoAutolinkingAndroid"
      ],
      "hash": "9564f0bc89867c544b8f159536ea72ae69e800b6"
    },
    "afterSource": {
      "type": "dir",
      "filePath": "../../packages/expo-asset/android",
      "reasons": [
        "expoAutolinkingAndroid"
      ],
      "hash": "05d1ba13b26711698f03a1b0964373d4b7abf166"
    }
  },
  {
    "op": "changed",
    "beforeSource": {
      "type": "dir",
      "filePath": "../../packages/expo-audio/ios",
      "reasons": [
        "expoAutolinkingIos"
      ],
      "hash": "b47b66f3f332856d715024e98ba56b09f0db0b5a"
    },
    "afterSource": {
      "type": "dir",
      "filePath": "../../packages/expo-audio/ios",
      "reasons": [
        "expoAutolinkingIos"
      ],
      "hash": "5305b8df99635a86e7118d6189ed8fdf329f4306"
    }
  },
  {
    "op": "changed",
    "beforeSource": {
      "type": "dir",
      "filePath": "../../packages/expo-camera/android",
      "reasons": [
        "expoAutolinkingAndroid"
      ],
      "hash": "75c55e55e3d95e4746645e4f480df88eb84d4fe3"
    },
    "afterSource": {
      "type": "dir",
      "filePath": "../../packages/expo-camera/android",
      "reasons": [
        "expoAutolinkingAndroid"
      ],
      "hash": "1d1542c3ca19644b62bd67f6868132a23798f7d4"
    }
  },
  {
    "op": "changed",
    "beforeSource": {
      "type": "dir",
      "filePath": "../../packages/expo-constants/ios",
      "reasons": [
        "expoAutolinkingIos"
      ],
      "hash": "42dd07095bfa9b04ee5b70edc65e1726db07e4e2"
    },
    "afterSource": {
      "type": "dir",
      "filePath": "../../packages/expo-constants/ios",
      "reasons": [
        "expoAutolinkingIos"
      ],
      "hash": "74a7d65eafc6605f97c45c3dc7cd32c620ce7d4f"
    }
  },
  {
    "op": "changed",
    "beforeSource": {
      "type": "dir",
      "filePath": "../../packages/expo-dev-launcher",
      "reasons": [
        "expoAutolinkingIos",
        "expoAutolinkingAndroid"
      ],
      "hash": "21734af991f86dd260e805cc80e284a0390bd5bd"
    },
    "afterSource": {
      "type": "dir",
      "filePath": "../../packages/expo-dev-launcher",
      "reasons": [
        "expoAutolinkingIos",
        "expoAutolinkingAndroid"
      ],
      "hash": "aa90664dbd20d5eaabf8d026e98b9b41db982faf"
    }
  },
  {
    "op": "changed",
    "beforeSource": {
      "type": "dir",
      "filePath": "../../packages/expo-dev-menu",
      "reasons": [
        "expoAutolinkingIos",
        "expoAutolinkingAndroid"
      ],
      "hash": "819e910887994b3f6bf7ceacf9323c38aeeac71e"
    },
    "afterSource": {
      "type": "dir",
      "filePath": "../../packages/expo-dev-menu",
      "reasons": [
        "expoAutolinkingIos",
        "expoAutolinkingAndroid"
      ],
      "hash": "999db1d10036dc6e771a49deb3a95d5822d1804b"
    }
  },
  {
    "op": "changed",
    "beforeSource": {
      "type": "dir",
      "filePath": "../../packages/expo-dev-menu-interface/android",
      "reasons": [
        "expoAutolinkingAndroid"
      ],
      "hash": "90225444bf8b4ebe1b6ae768228667621d0fe9cf"
    },
    "afterSource": {
      "type": "dir",
      "filePath": "../../packages/expo-dev-menu-interface/android",
      "reasons": [
        "expoAutolinkingAndroid"
      ],
      "hash": "51edecf73ca3944487142a6b63349d8f1c0445ce"
    }
  },
  {
    "op": "changed",
    "beforeSource": {
      "type": "dir",
      "filePath": "../../packages/expo-file-system/android",
      "reasons": [
        "expoAutolinkingAndroid"
      ],
      "hash": "1297e88eb7923fd7558d4284ee8a3146444684ee"
    },
    "afterSource": {
      "type": "dir",
      "filePath": "../../packages/expo-file-system/android",
      "reasons": [
        "expoAutolinkingAndroid"
      ],
      "hash": "d7de7a2b19ab99b77129cd8051448d2859c63c93"
    }
  },
  {
    "op": "changed",
    "beforeSource": {
      "type": "dir",
      "filePath": "../../packages/expo-file-system/ios",
      "reasons": [
        "expoAutolinkingIos"
      ],
      "hash": "160c0ed0c57cff604a27ca09d5a883beb9602003"
    },
    "afterSource": {
      "type": "dir",
      "filePath": "../../packages/expo-file-system/ios",
      "reasons": [
        "expoAutolinkingIos"
      ],
      "hash": "40647b49b63a6f531bd702fa095ada9f0c235255"
    }
  },
  {
    "op": "changed",
    "beforeSource": {
      "type": "dir",
      "filePath": "../../packages/expo-font/android",
      "reasons": [
        "expoAutolinkingAndroid"
      ],
      "hash": "4a66a1b5b2ac878f4eaf482f021cfeb9ec9f36f3"
    },
    "afterSource": {
      "type": "dir",
      "filePath": "../../packages/expo-font/android",
      "reasons": [
        "expoAutolinkingAndroid"
      ],
      "hash": "c2e452a3401e195afc849d4c6d3ac6161a8f89d4"
    }
  },
  {
    "op": "changed",
    "beforeSource": {
      "type": "dir",
      "filePath": "../../packages/expo-image/ios",
      "reasons": [
        "expoAutolinkingIos"
      ],
      "hash": "abd0b790577b1f0b1e5dbf64779b0e1334d8bc52"
    },
    "afterSource": {
      "type": "dir",
      "filePath": "../../packages/expo-image/ios",
      "reasons": [
        "expoAutolinkingIos"
      ],
      "hash": "6d4032416fb4f3ac730439f12cfeee3fdd917f74"
    }
  },
  {
    "op": "changed",
    "beforeSource": {
      "type": "dir",
      "filePath": "../../packages/expo-media-library/android",
      "reasons": [
        "expoAutolinkingAndroid"
      ],
      "hash": "ca59520deac38d70c09e575778e0b75811e9b68f"
    },
    "afterSource": {
      "type": "dir",
      "filePath": "../../packages/expo-media-library/android",
      "reasons": [
        "expoAutolinkingAndroid"
      ],
      "hash": "b99610c3994dde88100a923285a8246027edd22a"
    }
  },
  {
    "op": "changed",
    "beforeSource": {
      "type": "dir",
      "filePath": "../../packages/expo-modules-core",
      "reasons": [
        "expoAutolinkingIos",
        "expoAutolinkingAndroid"
      ],
      "hash": "e6587d9918dbabdd21f3a5d463334628089ffd87"
    },
    "afterSource": {
      "type": "dir",
      "filePath": "../../packages/expo-modules-core",
      "reasons": [
        "expoAutolinkingIos",
        "expoAutolinkingAndroid"
      ],
      "hash": "369e276ee17f2701c7f2e413a4f44a8f5f5569b3"
    }
  },
  {
    "op": "changed",
    "beforeSource": {
      "type": "dir",
      "filePath": "../../packages/expo-screen-capture/ios",
      "reasons": [
        "expoAutolinkingIos"
      ],
      "hash": "cd38f35974d492d2374a8d9c1a27b889419c07a6"
    },
    "afterSource": {
      "type": "dir",
      "filePath": "../../packages/expo-screen-capture/ios",
      "reasons": [
        "expoAutolinkingIos"
      ],
      "hash": "364c448092e7d780f69df8b9318501735764c720"
    }
  },
  {
    "op": "changed",
    "beforeSource": {
      "type": "dir",
      "filePath": "../../packages/expo-secure-store/android",
      "reasons": [
        "expoAutolinkingAndroid"
      ],
      "hash": "2b74a267b7de48cb8ee2596b3fe3f2dc01a83ec9"
    },
    "afterSource": {
      "type": "dir",
      "filePath": "../../packages/expo-secure-store/android",
      "reasons": [
        "expoAutolinkingAndroid"
      ],
      "hash": "9f1c7f07d289aec0c3df8c8a098360bbc32a6a30"
    }
  },
  {
    "op": "changed",
    "beforeSource": {
      "type": "dir",
      "filePath": "../../packages/expo-sqlite/android",
      "reasons": [
        "expoAutolinkingAndroid"
      ],
      "hash": "5b6fde144222b036d2c1fea49d5c2135ed0db413"
    },
    "afterSource": {
      "type": "dir",
      "filePath": "../../packages/expo-sqlite/android",
      "reasons": [
        "expoAutolinkingAndroid"
      ],
      "hash": "27f75d1fb5fffd4b1d7d1a8527fac8b03648edf9"
    }
  },
  {
    "op": "changed",
    "beforeSource": {
      "type": "dir",
      "filePath": "../../packages/expo-sqlite/ios",
      "reasons": [
        "expoAutolinkingIos"
      ],
      "hash": "73898131bc96d8ac9e857049ea66c43d3e099266"
    },
    "afterSource": {
      "type": "dir",
      "filePath": "../../packages/expo-sqlite/ios",
      "reasons": [
        "expoAutolinkingIos"
      ],
      "hash": "2e46affb0234aa7a590c748c2f95556b95cbf324"
    }
  },
  {
    "op": "changed",
    "beforeSource": {
      "type": "dir",
      "filePath": "../../packages/expo-ui/android",
      "reasons": [
        "expoAutolinkingAndroid"
      ],
      "hash": "d358f6a59399b7e33cc890ba36f70cb3677058db"
    },
    "afterSource": {
      "type": "dir",
      "filePath": "../../packages/expo-ui/android",
      "reasons": [
        "expoAutolinkingAndroid"
      ],
      "hash": "c01b04e03ceb669350901bf94c30bf16b95908c1"
    }
  },
  {
    "op": "changed",
    "beforeSource": {
      "type": "dir",
      "filePath": "../../packages/expo-ui/ios",
      "reasons": [
        "expoAutolinkingIos"
      ],
      "hash": "26353ff674f47f683a09342663dc9d9ee3652557"
    },
    "afterSource": {
      "type": "dir",
      "filePath": "../../packages/expo-ui/ios",
      "reasons": [
        "expoAutolinkingIos"
      ],
      "hash": "2e646756e569b6334d986f532e5365aefa731b40"
    }
  },
  {
    "op": "changed",
    "beforeSource": {
      "type": "dir",
      "filePath": "../../packages/expo-updates/android",
      "reasons": [
        "expoAutolinkingAndroid"
      ],
      "hash": "d92f7d2925fd2c754f68ffbc2af0c961f1cc8ee7"
    },
    "afterSource": {
      "type": "dir",
      "filePath": "../../packages/expo-updates/android",
      "reasons": [
        "expoAutolinkingAndroid"
      ],
      "hash": "4a52b526a3e70c61952c1c3302ed317faaef8278"
    }
  },
  {
    "op": "changed",
    "beforeSource": {
      "type": "dir",
      "filePath": "../../packages/expo-updates/ios",
      "reasons": [
        "expoAutolinkingIos"
      ],
      "hash": "790c5890f4f0a1da090789e240fea58083c576d2"
    },
    "afterSource": {
      "type": "dir",
      "filePath": "../../packages/expo-updates/ios",
      "reasons": [
        "expoAutolinkingIos"
      ],
      "hash": "60e79ec29339b8e4f572b379113ebbc016c05017"
    }
  },
  {
    "op": "changed",
    "beforeSource": {
      "type": "dir",
      "filePath": "android",
      "reasons": [
        "bareNativeDir"
      ],
      "hash": "ce5e8ef3caf46fd7f8a6a02a6dc1d6b25a73d81d"
    },
    "afterSource": {
      "type": "dir",
      "filePath": "android",
      "reasons": [
        "bareNativeDir"
      ],
      "hash": "b742bbecd997102268a057723ba8c34dde76b7ff"
    }
  },
  {
    "op": "changed",
    "beforeSource": {
      "type": "dir",
      "filePath": "ios",
      "reasons": [
        "bareNativeDir"
      ],
      "hash": "477e968879436c5c1d9acd1908432686580a7f98"
    },
    "afterSource": {
      "type": "dir",
      "filePath": "ios",
      "reasons": [
        "bareNativeDir"
      ],
      "hash": "b84b9a87221c3a6808a6aa12582266a143dc9acf"
    }
  },
  {
    "op": "changed",
    "beforeSource": {
      "type": "contents",
      "id": "expoAutolinkingConfig:android",
      "contents": "{\"extraDependencies\":[],\"coreFeatures\":[\"swiftui\",\"compose\"],\"modules\":[{\"packageName\":\"@expo/app-integrity\",\"packageVersion\":\"0.0.1\",\"projects\":[{\"name\":\"expo-app-integrity\",\"sourceDir\":\"../../packages/expo-app-integrity/android\",\"modules\":[\"expo.modules.integrity.IntegrityModule\"]}]},{\"packageName\":\"@expo/dom-webview\",\"packageVersion\":\"0.1.4\",\"projects\":[{\"name\":\"expo-dom-webview\",\"sourceDir\":\"../../packages/@expo/dom-webview/android\",\"modules\":[\"expo.modules.webview.DomWebViewModule\"]}]},{\"packageName\":\"@expo/ui\",\"packageVersion\":\"0.1.1-alpha.7\",\"projects\":[{\"name\":\"expo-ui\",\"sourceDir\":\"../../packages/expo-ui/android\",\"modules\":[\"expo.modules.ui.ExpoUIModule\"]}],\"coreFeatures\":[\"swiftui\",\"compose\"]},{\"packageName\":\"benchmarking-module\",\"packageVersion\":\"0.0.1\",\"projects\":[{\"name\":\"benchmarking-module\",\"sourceDir\":\"modules/benchmarking/android\",\"modules\":[\"expo.modules.benchmark.BenchmarkingExpoModule\"]}]},{\"packageName\":\"expo\",\"packageVersion\":\"53.0.9\",\"projects\":[{\"name\":\"expo\",\"sourceDir\":\"../../packages/expo/android\",\"modules\":[\"expo.modules.fetch.ExpoFetchModule\"]}]},{\"packageName\":\"expo-application\",\"packageVersion\":\"6.1.4\",\"projects\":[{\"name\":\"expo-application\",\"sourceDir\":\"../../packages/expo-application/android\",\"modules\":[\"expo.modules.application.ApplicationModule\"]}]},{\"packageName\":\"expo-asset\",\"packageVersion\":\"11.1.5\",\"projects\":[{\"name\":\"expo-asset\",\"sourceDir\":\"../../packages/expo-asset/android\",\"modules\":[\"expo.modules.asset.AssetModule\"]}]},{\"packageName\":\"expo-audio\",\"packageVersion\":\"0.4.5\",\"projects\":[{\"name\":\"expo-audio\",\"sourceDir\":\"../../packages/expo-audio/android\",\"modules\":[\"expo.modules.audio.AudioModule\"]}]},{\"packageName\":\"expo-av\",\"packageVersion\":\"15.1.4\",\"projects\":[{\"name\":\"expo-av\",\"sourceDir\":\"../../packages/expo-av/android\",\"modules\":[\"expo.modules.av.video.VideoViewModule\",\"expo.modules.av.AVModule\"]}]},{\"packageName\":\"expo-background-fetch\",\"packageVersion\":\"13.1.5\",\"projects\":[{\"name\":\"expo-background-fetch\",\"sourceDir\":\"../../packages/expo-background-fetch/android\",\"modules\":[\"expo.modules.backgroundfetch.BackgroundFetchModule\"]}]},{\"packageName\":\"expo-background-task\",\"packageVersion\":\"0.2.7\",\"projects\":[{\"name\":\"expo-background-task\",\"sourceDir\":\"../../packages/expo-background-task/android\",\"modules\":[\"expo.modules.backgroundtask.BackgroundTaskModule\"]}]},{\"packageName\":\"expo-battery\",\"packageVersion\":\"9.1.4\",\"projects\":[{\"name\":\"expo-battery\",\"sourceDir\":\"../../packages/expo-battery/android\",\"modules\":[\"expo.modules.battery.BatteryModule\"]}]},{\"packageName\":\"expo-blur\",\"packageVersion\":\"14.1.4\",\"projects\":[{\"name\":\"expo-blur\",\"sourceDir\":\"../../packages/expo-blur/android\",\"modules\":[\"expo.modules.blur.BlurModule\"]}]},{\"packageName\":\"expo-brightness\",\"packageVersion\":\"13.1.4\",\"projects\":[{\"name\":\"expo-brightness\",\"sourceDir\":\"../../packages/expo-brightness/android\",\"modules\":[\"expo.modules.brightness.BrightnessModule\"]}]},{\"packageName\":\"expo-calendar\",\"packageVersion\":\"14.1.4\",\"projects\":[{\"name\":\"expo-calendar\",\"sourceDir\":\"../../packages/expo-calendar/android\",\"modules\":[\"expo.modules.calendar.CalendarModule\"]}]},{\"packageName\":\"expo-camera\",\"packageVersion\":\"16.1.6\",\"projects\":[{\"name\":\"expo-camera\",\"sourceDir\":\"../../packages/expo-camera/android\",\"modules\":[\"expo.modules.camera.CameraViewModule\"]}]},{\"packageName\":\"expo-cellular\",\"packageVersion\":\"7.1.4\",\"projects\":[{\"name\":\"expo-cellular\",\"sourceDir\":\"../../packages/expo-cellular/android\",\"modules\":[\"expo.modules.cellular.CellularModule\"]}]},{\"packageName\":\"expo-clipboard\",\"packageVersion\":\"7.1.4\",\"projects\":[{\"name\":\"expo-clipboard\",\"sourceDir\":\"../../packages/expo-clipboard/android\",\"modules\":[\"expo.modules.clipboard.ClipboardModule\"]}]},{\"packageName\":\"expo-constants\",\"packageVersion\":\"17.1.6\",\"projects\":[{\"name\":\"expo-constants\",\"sourceDir\":\"../../packages/expo-constants/android\",\"modules\":[\"expo.modules.constants.ConstantsModule\"]}]},{\"packageName\":\"expo-contacts\",\"packageVersion\":\"14.2.4\",\"projects\":[{\"name\":\"expo-contacts\",\"sourceDir\":\"../../packages/expo-contacts/android\",\"modules\":[\"expo.modules.contacts.ContactsModule\"]}]},{\"packageName\":\"expo-crypto\",\"packageVersion\":\"14.1.4\",\"projects\":[{\"name\":\"expo-crypto\",\"sourceDir\":\"../../packages/expo-crypto/android\",\"modules\":[\"expo.modules.crypto.CryptoModule\"]}]},{\"packageName\":\"expo-dev-client\",\"packageVersion\":\"5.1.8\",\"projects\":[{\"name\":\"expo-dev-client\",\"sourceDir\":\"../../packages/expo-dev-client/android\",\"modules\":[]}]},{\"packageName\":\"expo-dev-launcher\",\"packageVersion\":\"5.1.11\",\"projects\":[{\"name\":\"expo-dev-launcher\",\"sourceDir\":\"../../packages/expo-dev-launcher/android\",\"modules\":[]}],\"plugins\":[{\"id\":\"expo-dev-launcher-gradle-plugin\",\"group\":\"expo.modules\",\"sourceDir\":\"../../packages/expo-dev-launcher/expo-dev-launcher-gradle-plugin\",\"applyToRootProject\":true}]},{\"packageName\":\"expo-dev-menu\",\"packageVersion\":\"6.1.10\",\"projects\":[{\"name\":\"expo-dev-menu\",\"sourceDir\":\"../../packages/expo-dev-menu/android\",\"modules\":[\"expo.modules.devmenu.modules.DevMenuModule\"]}]},{\"packageName\":\"expo-dev-menu-interface\",\"packageVersion\":\"1.10.0\",\"projects\":[{\"name\":\"expo-dev-menu-interface\",\"sourceDir\":\"../../packages/expo-dev-menu-interface/android\",\"modules\":[]}]},{\"packageName\":\"expo-device\",\"packageVersion\":\"7.1.4\",\"projects\":[{\"name\":\"expo-device\",\"sourceDir\":\"../../packages/expo-device/android\",\"modules\":[\"expo.modules.device.DeviceModule\"]}]},{\"packageName\":\"expo-document-picker\",\"packageVersion\":\"13.1.5\",\"projects\":[{\"name\":\"expo-document-picker\",\"sourceDir\":\"../../packages/expo-document-picker/android\",\"modules\":[\"expo.modules.documentpicker.DocumentPickerModule\"]}]},{\"packageName\":\"expo-eas-client\",\"packageVersion\":\"0.14.3\",\"projects\":[{\"name\":\"expo-eas-client\",\"sourceDir\":\"../../packages/expo-eas-client/android\",\"modules\":[\"expo.modules.easclient.EASClientModule\"]}]},{\"packageName\":\"expo-file-system\",\"packageVersion\":\"18.1.10\",\"projects\":[{\"name\":\"expo-file-system\",\"sourceDir\":\"../../packages/expo-file-system/android\",\"modules\":[\"expo.modules.filesystem.FileSystemModule\",\"expo.modules.filesystem.next.FileSystemNextModule\"]}]},{\"packageName\":\"expo-font\",\"packageVersion\":\"13.3.1\",\"projects\":[{\"name\":\"expo-font\",\"sourceDir\":\"../../packages/expo-font/android\",\"modules\":[\"expo.modules.font.FontLoaderModule\",\"expo.modules.font.FontUtilsModule\"]}]},{\"packageName\":\"expo-gl\",\"packageVersion\":\"15.1.5\",\"projects\":[{\"name\":\"expo-gl\",\"sourceDir\":\"../../packages/expo-gl/android\",\"modules\":[\"expo.modules.gl.GLViewModule\",\"expo.modules.gl.GLObjectManagerModule\"]}]},{\"packageName\":\"expo-haptics\",\"packageVersion\":\"14.1.4\",\"projects\":[{\"name\":\"expo-haptics\",\"sourceDir\":\"../../packages/expo-haptics/android\",\"modules\":[\"expo.modules.haptics.HapticsModule\"]}]},{\"packageName\":\"expo-image\",\"packageVersion\":\"2.3.0\",\"projects\":[{\"name\":\"expo-image\",\"sourceDir\":\"../../packages/expo-image/android\",\"modules\":[\"expo.modules.image.ExpoImageModule\"]}]},{\"packageName\":\"expo-image-loader\",\"packageVersion\":\"5.1.0\",\"projects\":[{\"name\":\"expo-image-loader\",\"sourceDir\":\"../../packages/expo-image-loader/android\",\"modules\":[]}]},{\"packageName\":\"expo-image-manipulator\",\"packageVersion\":\"13.1.7\",\"projects\":[{\"name\":\"expo-image-manipulator\",\"sourceDir\":\"../../packages/expo-image-manipulator/android\",\"modules\":[\"expo.modules.imagemanipulator.ImageManipulatorModule\"]}]},{\"packageName\":\"expo-image-picker\",\"packageVersion\":\"16.1.4\",\"projects\":[{\"name\":\"expo-image-picker\",\"sourceDir\":\"../../packages/expo-image-picker/android\",\"modules\":[\"expo.modules.imagepicker.ImagePickerModule\"]}]},{\"packageName\":\"expo-insights\",\"packageVersion\":\"0.9.3\",\"projects\":[{\"name\":\"expo-insights\",\"sourceDir\":\"../../packages/expo-insights/android\",\"modules\":[\"expo.modules.insights.ExpoInsightsModule\"]}]},{\"packageName\":\"expo-intent-launcher\",\"packageVersion\":\"12.1.4\",\"projects\":[{\"name\":\"expo-intent-launcher\",\"sourceDir\":\"../../packages/expo-intent-launcher/android\",\"modules\":[\"expo.modules.intentlauncher.IntentLauncherModule\"]}]},{\"packageName\":\"expo-json-utils\",\"packageVersion\":\"0.15.0\",\"projects\":[{\"name\":\"expo-json-utils\",\"sourceDir\":\"../../packages/expo-json-utils/android\",\"modules\":[]}]},{\"packageName\":\"expo-keep-awake\",\"packageVersion\":\"14.1.4\",\"projects\":[{\"name\":\"expo-keep-awake\",\"sourceDir\":\"../../packages/expo-keep-awake/android\",\"modules\":[\"expo.modules.keepawake.KeepAwakeModule\"]}]},{\"packageName\":\"expo-linear-gradient\",\"packageVersion\":\"14.1.4\",\"projects\":[{\"name\":\"expo-linear-gradient\",\"sourceDir\":\"../../packages/expo-linear-gradient/android\",\"modules\":[\"expo.modules.lineargradient.LinearGradientModule\"]}]},{\"packageName\":\"expo-linking\",\"packageVersion\":\"7.1.5\",\"projects\":[{\"name\":\"expo-linking\",\"sourceDir\":\"../../packages/expo-linking/android\",\"modules\":[\"expo.modules.linking.ExpoLinkingModule\"]}]},{\"packageName\":\"expo-local-authentication\",\"packageVersion\":\"16.0.4\",\"projects\":[{\"name\":\"expo-local-authentication\",\"sourceDir\":\"../../packages/expo-local-authentication/android\",\"modules\":[\"expo.modules.localauthentication.LocalAuthenticationModule\"]}]},{\"packageName\":\"expo-localization\",\"packageVersion\":\"16.1.5\",\"projects\":[{\"name\":\"expo-localization\",\"sourceDir\":\"../../packages/expo-localization/android\",\"modules\":[\"expo.modules.localization.LocalizationModule\"]}]},{\"packageName\":\"expo-location\",\"packageVersion\":\"18.1.5\",\"projects\":[{\"name\":\"expo-location\",\"sourceDir\":\"../../packages/expo-location/android\",\"modules\":[\"expo.modules.location.LocationModule\"]}]},{\"packageName\":\"expo-mail-composer\",\"packageVersion\":\"14.1.4\",\"projects\":[{\"name\":\"expo-mail-composer\",\"sourceDir\":\"../../packages/expo-mail-composer/android\",\"modules\":[\"expo.modules.mailcomposer.MailComposerModule\"]}]},{\"packageName\":\"expo-manifests\",\"packageVersion\":\"0.16.5\",\"projects\":[{\"name\":\"expo-manifests\",\"sourceDir\":\"../../packages/expo-manifests/android\",\"modules\":[]}]},{\"packageName\":\"expo-maps\",\"packageVersion\":\"0.10.0\",\"projects\":[{\"name\":\"expo-maps\",\"sourceDir\":\"../../packages/expo-maps/android\",\"modules\":[\"expo.modules.maps.MapsModule\",\"expo.modules.maps.GoogleMapsModule\",\"expo.modules.maps.StreetViewModule\"]}],\"coreFeatures\":[\"swiftui\",\"compose\"]},{\"packageName\":\"expo-media-library\",\"packageVersion\":\"17.1.6\",\"projects\":[{\"name\":\"expo-media-library\",\"sourceDir\":\"../../packages/expo-media-library/android\",\"modules\":[\"expo.modules.medialibrary.MediaLibraryModule\"]}]},{\"packageName\":\"expo-mesh-gradient\",\"packageVersion\":\"0.3.4\",\"projects\":[{\"name\":\"expo-mesh-gradient\",\"sourceDir\":\"../../packages/expo-mesh-gradient/android\",\"modules\":[\"expo.modules.meshgradient.MeshGradientModule\"]}],\"coreFeatures\":[\"swiftui\",\"compose\"]},{\"packageName\":\"expo-modules-core\",\"packageVersion\":\"2.3.13\",\"projects\":[{\"name\":\"expo-modules-core\",\"sourceDir\":\"../../packages/expo-modules-core/android\",\"modules\":[]}],\"plugins\":[{\"id\":\"expo-module-gradle-plugin\",\"group\":\"expo.modules\",\"sourceDir\":\"../../packages/expo-modules-core/expo-module-gradle-plugin\",\"applyToRootProject\":false}]},{\"packageName\":\"expo-navigation-bar\",\"packageVersion\":\"4.2.4\",\"projects\":[{\"name\":\"expo-navigation-bar\",\"sourceDir\":\"../../packages/expo-navigation-bar/android\",\"modules\":[\"expo.modules.navigationbar.NavigationBarModule\"]}]},{\"packageName\":\"expo-network\",\"packageVersion\":\"7.1.5\",\"projects\":[{\"name\":\"expo-network\",\"sourceDir\":\"../../packages/expo-network/android\",\"modules\":[\"expo.modules.network.NetworkModule\"]}]},{\"packageName\":\"expo-network-addons\",\"packageVersion\":\"0.9.3\",\"projects\":[{\"name\":\"expo-network-addons\",\"sourceDir\":\"../../packages/expo-network-addons/android\",\"modules\":[]}],\"plugins\":[{\"id\":\"expo-network-addons-gradle-plugin\",\"group\":\"expo.modules\",\"sourceDir\":\"../../packages/expo-network-addons/expo-network-addons-gradle-plugin\",\"applyToRootProject\":true}]},{\"packageName\":\"expo-notifications\",\"packageVersion\":\"0.31.2\",\"projects\":[{\"name\":\"expo-notifications\",\"sourceDir\":\"../../packages/expo-notifications/android\",\"modules\":[\"expo.modules.notifications.badge.BadgeModule\",\"expo.modules.notifications.notifications.background.ExpoBackgroundNotificationTasksModule\",\"expo.modules.notifications.notifications.categories.ExpoNotificationCategoriesModule\",\"expo.modules.notifications.notifications.channels.NotificationChannelGroupManagerModule\",\"expo.modules.notifications.notifications.channels.NotificationChannelManagerModule\",\"expo.modules.notifications.notifications.emitting.NotificationsEmitter\",\"expo.modules.notifications.notifications.handling.NotificationsHandler\",\"expo.modules.notifications.permissions.NotificationPermissionsModule\",\"expo.modules.notifications.notifications.presentation.ExpoNotificationPresentationModule\",\"expo.modules.notifications.notifications.scheduling.NotificationScheduler\",\"expo.modules.notifications.serverregistration.ServerRegistrationModule\",\"expo.modules.notifications.tokens.PushTokenModule\"]}]},{\"packageName\":\"expo-print\",\"packageVersion\":\"14.1.4\",\"projects\":[{\"name\":\"expo-print\",\"sourceDir\":\"../../packages/expo-print/android\",\"modules\":[\"expo.modules.print.PrintModule\"]}]},{\"packageName\":\"expo-screen-capture\",\"packageVersion\":\"7.1.4\",\"projects\":[{\"name\":\"expo-screen-capture\",\"sourceDir\":\"../../packages/expo-screen-capture/android\",\"modules\":[\"expo.modules.screencapture.ScreenCaptureModule\"]}]},{\"packageName\":\"expo-screen-orientation\",\"packageVersion\":\"8.1.6\",\"projects\":[{\"name\":\"expo-screen-orientation\",\"sourceDir\":\"../../packages/expo-screen-orientation/android\",\"modules\":[\"expo.modules.screenorientation.ScreenOrientationModule\"]}]},{\"packageName\":\"expo-secure-store\",\"packageVersion\":\"14.2.3\",\"projects\":[{\"name\":\"expo-secure-store\",\"sourceDir\":\"../../packages/expo-secure-store/android\",\"modules\":[\"expo.modules.securestore.SecureStoreModule\"]}]},{\"packageName\":\"expo-sensors\",\"packageVersion\":\"14.1.4\",\"projects\":[{\"name\":\"expo-sensors\",\"sourceDir\":\"../../packages/expo-sensors/android\",\"modules\":[\"expo.modules.sensors.modules.AccelerometerModule\",\"expo.modules.sensors.modules.BarometerModule\",\"expo.modules.sensors.modules.GyroscopeModule\",\"expo.modules.sensors.modules.LightSensorModule\",\"expo.modules.sensors.modules.DeviceMotionModule\",\"expo.modules.sensors.modules.MagnetometerModule\",\"expo.modules.sensors.modules.MagnetometerUncalibratedModule\",\"expo.modules.sensors.modules.PedometerModule\"]}]},{\"packageName\":\"expo-sharing\",\"packageVersion\":\"13.1.5\",\"projects\":[{\"name\":\"expo-sharing\",\"sourceDir\":\"../../packages/expo-sharing/android\",\"modules\":[\"expo.modules.sharing.SharingModule\"]}]},{\"packageName\":\"expo-sms\",\"packageVersion\":\"13.1.4\",\"projects\":[{\"name\":\"expo-sms\",\"sourceDir\":\"../../packages/expo-sms/android\",\"modules\":[\"expo.modules.sms.SMSModule\"]}]},{\"packageName\":\"expo-speech\",\"packageVersion\":\"13.1.7\",\"projects\":[{\"name\":\"expo-speech\",\"sourceDir\":\"../../packages/expo-speech/android\",\"modules\":[\"expo.modules.speech.SpeechModule\"]}]},{\"packageName\":\"expo-splash-screen\",\"packageVersion\":\"0.30.8\",\"projects\":[{\"name\":\"expo-splash-screen\",\"sourceDir\":\"../../packages/expo-splash-screen/android\",\"modules\":[\"expo.modules.splashscreen.SplashScreenModule\"]}]},{\"packageName\":\"expo-sqlite\",\"packageVersion\":\"15.2.10\",\"projects\":[{\"name\":\"expo-sqlite\",\"sourceDir\":\"../../packages/expo-sqlite/android\",\"modules\":[\"expo.modules.sqlite.SQLiteModule\"],\"shouldUsePublicationScriptPath\":\"/home/runner/work/expo/expo/packages/expo-sqlite/android/shouldUsePublication.groovy\"}]},{\"packageName\":\"expo-store-review\",\"packageVersion\":\"8.1.5\",\"projects\":[{\"name\":\"expo-store-review\",\"sourceDir\":\"../../packages/expo-store-review/android\",\"modules\":[\"expo.modules.storereview.StoreReviewModule\"]}]},{\"packageName\":\"expo-structured-headers\",\"packageVersion\":\"4.1.0\",\"projects\":[{\"name\":\"expo-structured-headers\",\"sourceDir\":\"../../packages/expo-structured-headers/android\",\"modules\":[]}]},{\"packageName\":\"expo-system-ui\",\"packageVersion\":\"5.0.7\",\"projects\":[{\"name\":\"expo-system-ui\",\"sourceDir\":\"../../packages/expo-system-ui/android\",\"modules\":[\"expo.modules.systemui.SystemUIModule\"]}]},{\"packageName\":\"expo-task-manager\",\"packageVersion\":\"13.1.5\",\"projects\":[{\"name\":\"expo-task-manager\",\"sourceDir\":\"../../packages/expo-task-manager/android\",\"modules\":[\"expo.modules.taskManager.TaskManagerModule\"]}]},{\"packageName\":\"expo-tracking-transparency\",\"packageVersion\":\"5.2.4\",\"projects\":[{\"name\":\"expo-tracking-transparency\",\"sourceDir\":\"../../packages/expo-tracking-transparency/android\",\"modules\":[\"expo.modules.trackingtransparency.TrackingTransparencyModule\"]}]},{\"packageName\":\"expo-updates\",\"packageVersion\":\"0.28.13\",\"projects\":[{\"name\":\"expo-updates\",\"sourceDir\":\"../../packages/expo-updates/android\",\"modules\":[\"expo.modules.updates.UpdatesModule\"]}],\"plugins\":[{\"id\":\"expo-updates-gradle-plugin\",\"group\":\"expo.modules\",\"sourceDir\":\"../../packages/expo-updates/expo-updates-gradle-plugin\",\"applyToRootProject\":true}]},{\"packageName\":\"expo-updates-interface\",\"packageVersion\":\"1.1.0\",\"projects\":[{\"name\":\"expo-updates-interface\",\"sourceDir\":\"../../packages/expo-updates-interface/android\",\"modules\":[]}]},{\"packageName\":\"expo-video\",\"packageVersion\":\"2.1.9\",\"projects\":[{\"name\":\"expo-video\",\"sourceDir\":\"../../packages/expo-video/android\",\"modules\":[\"expo.modules.video.VideoModule\"]}]},{\"packageName\":\"expo-video-thumbnails\",\"packageVersion\":\"9.1.3\",\"projects\":[{\"name\":\"expo-video-thumbnails\",\"sourceDir\":\"../../packages/expo-video-thumbnails/android\",\"modules\":[\"expo.modules.videothumbnails.VideoThumbnailsModule\"]}]},{\"packageName\":\"expo-web-browser\",\"packageVersion\":\"14.1.6\",\"projects\":[{\"name\":\"expo-web-browser\",\"sourceDir\":\"../../packages/expo-web-browser/android\",\"modules\":[\"expo.modules.webbrowser.WebBrowserModule\"]}]},{\"packageName\":\"unimodules-app-loader\",\"packageVersion\":\"5.1.3\",\"projects\":[{\"name\":\"unimodules-app-loader\",\"sourceDir\":\"../../packages/unimodules-app-loader/android\",\"modules\":[]}]}],\"configuration\":{\"buildFromSource\":[\".*\"]}}",
      "reasons": [
        "expoAutolinkingAndroid"
      ],
      "hash": "81280cf6f4b0c46bca317c756b9cdd45cc2b15dc"
    },
    "afterSource": {
      "type": "contents",
      "id": "expoAutolinkingConfig:android",
      "contents": "{\"extraDependencies\":[],\"coreFeatures\":[\"swiftui\",\"compose\"],\"modules\":[{\"packageName\":\"@expo/app-integrity\",\"packageVersion\":\"0.0.1\",\"projects\":[{\"name\":\"expo-app-integrity\",\"sourceDir\":\"../../packages/expo-app-integrity/android\",\"modules\":[\"expo.modules.integrity.IntegrityModule\"]}]},{\"packageName\":\"@expo/dom-webview\",\"packageVersion\":\"0.1.4\",\"projects\":[{\"name\":\"expo-dom-webview\",\"sourceDir\":\"../../packages/@expo/dom-webview/android\",\"modules\":[\"expo.modules.webview.DomWebViewModule\"]}]},{\"packageName\":\"@expo/ui\",\"packageVersion\":\"0.1.1-alpha.7\",\"projects\":[{\"name\":\"expo-ui\",\"sourceDir\":\"../../packages/expo-ui/android\",\"modules\":[\"expo.modules.ui.ExpoUIModule\"]}],\"coreFeatures\":[\"swiftui\",\"compose\"]},{\"packageName\":\"benchmarking-module\",\"packageVersion\":\"0.0.1\",\"projects\":[{\"name\":\"benchmarking-module\",\"sourceDir\":\"modules/benchmarking/android\",\"modules\":[\"expo.modules.benchmark.BenchmarkingExpoModule\"]}]},{\"packageName\":\"expo\",\"packageVersion\":\"53.0.9\",\"projects\":[{\"name\":\"expo\",\"sourceDir\":\"../../packages/expo/android\",\"modules\":[\"expo.modules.fetch.ExpoFetchModule\"]}]},{\"packageName\":\"expo-application\",\"packageVersion\":\"6.1.4\",\"projects\":[{\"name\":\"expo-application\",\"sourceDir\":\"../../packages/expo-application/android\",\"modules\":[\"expo.modules.application.ApplicationModule\"]}]},{\"packageName\":\"expo-asset\",\"packageVersion\":\"11.1.5\",\"projects\":[{\"name\":\"expo-asset\",\"sourceDir\":\"../../packages/expo-asset/android\",\"modules\":[\"expo.modules.asset.AssetModule\"]}]},{\"packageName\":\"expo-audio\",\"packageVersion\":\"0.4.5\",\"projects\":[{\"name\":\"expo-audio\",\"sourceDir\":\"../../packages/expo-audio/android\",\"modules\":[\"expo.modules.audio.AudioModule\"]}]},{\"packageName\":\"expo-av\",\"packageVersion\":\"15.1.4\",\"projects\":[{\"name\":\"expo-av\",\"sourceDir\":\"../../packages/expo-av/android\",\"modules\":[\"expo.modules.av.video.VideoViewModule\",\"expo.modules.av.AVModule\"]}]},{\"packageName\":\"expo-background-fetch\",\"packageVersion\":\"13.1.5\",\"projects\":[{\"name\":\"expo-background-fetch\",\"sourceDir\":\"../../packages/expo-background-fetch/android\",\"modules\":[\"expo.modules.backgroundfetch.BackgroundFetchModule\"]}]},{\"packageName\":\"expo-background-task\",\"packageVersion\":\"0.2.7\",\"projects\":[{\"name\":\"expo-background-task\",\"sourceDir\":\"../../packages/expo-background-task/android\",\"modules\":[\"expo.modules.backgroundtask.BackgroundTaskModule\"]}]},{\"packageName\":\"expo-battery\",\"packageVersion\":\"9.1.4\",\"projects\":[{\"name\":\"expo-battery\",\"sourceDir\":\"../../packages/expo-battery/android\",\"modules\":[\"expo.modules.battery.BatteryModule\"]}]},{\"packageName\":\"expo-blur\",\"packageVersion\":\"14.1.4\",\"projects\":[{\"name\":\"expo-blur\",\"sourceDir\":\"../../packages/expo-blur/android\",\"modules\":[\"expo.modules.blur.BlurModule\"]}]},{\"packageName\":\"expo-brightness\",\"packageVersion\":\"13.1.4\",\"projects\":[{\"name\":\"expo-brightness\",\"sourceDir\":\"../../packages/expo-brightness/android\",\"modules\":[\"expo.modules.brightness.BrightnessModule\"]}]},{\"packageName\":\"expo-calendar\",\"packageVersion\":\"14.1.4\",\"projects\":[{\"name\":\"expo-calendar\",\"sourceDir\":\"../../packages/expo-calendar/android\",\"modules\":[\"expo.modules.calendar.CalendarModule\"]}]},{\"packageName\":\"expo-camera\",\"packageVersion\":\"16.1.6\",\"projects\":[{\"name\":\"expo-camera\",\"sourceDir\":\"../../packages/expo-camera/android\",\"modules\":[\"expo.modules.camera.CameraViewModule\"]}]},{\"packageName\":\"expo-cellular\",\"packageVersion\":\"7.1.4\",\"projects\":[{\"name\":\"expo-cellular\",\"sourceDir\":\"../../packages/expo-cellular/android\",\"modules\":[\"expo.modules.cellular.CellularModule\"]}]},{\"packageName\":\"expo-clipboard\",\"packageVersion\":\"7.1.4\",\"projects\":[{\"name\":\"expo-clipboard\",\"sourceDir\":\"../../packages/expo-clipboard/android\",\"modules\":[\"expo.modules.clipboard.ClipboardModule\"]}]},{\"packageName\":\"expo-constants\",\"packageVersion\":\"17.1.6\",\"projects\":[{\"name\":\"expo-constants\",\"sourceDir\":\"../../packages/expo-constants/android\",\"modules\":[\"expo.modules.constants.ConstantsModule\"]}]},{\"packageName\":\"expo-contacts\",\"packageVersion\":\"14.2.4\",\"projects\":[{\"name\":\"expo-contacts\",\"sourceDir\":\"../../packages/expo-contacts/android\",\"modules\":[\"expo.modules.contacts.ContactsModule\"]}]},{\"packageName\":\"expo-crypto\",\"packageVersion\":\"14.1.4\",\"projects\":[{\"name\":\"expo-crypto\",\"sourceDir\":\"../../packages/expo-crypto/android\",\"modules\":[\"expo.modules.crypto.CryptoModule\"]}]},{\"packageName\":\"expo-dev-client\",\"packageVersion\":\"5.1.8\",\"projects\":[{\"name\":\"expo-dev-client\",\"sourceDir\":\"../../packages/expo-dev-client/android\",\"modules\":[]}]},{\"packageName\":\"expo-dev-launcher\",\"packageVersion\":\"5.1.11\",\"projects\":[{\"name\":\"expo-dev-launcher\",\"sourceDir\":\"../../packages/expo-dev-launcher/android\",\"modules\":[\"expo.modules.devlauncher.modules.DevLauncherInternalModule\"]}],\"plugins\":[{\"id\":\"expo-dev-launcher-gradle-plugin\",\"group\":\"expo.modules\",\"sourceDir\":\"../../packages/expo-dev-launcher/expo-dev-launcher-gradle-plugin\",\"applyToRootProject\":true}]},{\"packageName\":\"expo-dev-menu\",\"packageVersion\":\"6.1.10\",\"projects\":[{\"name\":\"expo-dev-menu\",\"sourceDir\":\"../../packages/expo-dev-menu/android\",\"modules\":[\"expo.modules.devmenu.modules.DevMenuModule\"]}]},{\"packageName\":\"expo-dev-menu-interface\",\"packageVersion\":\"1.10.0\",\"projects\":[{\"name\":\"expo-dev-menu-interface\",\"sourceDir\":\"../../packages/expo-dev-menu-interface/android\",\"modules\":[]}]},{\"packageName\":\"expo-device\",\"packageVersion\":\"7.1.4\",\"projects\":[{\"name\":\"expo-device\",\"sourceDir\":\"../../packages/expo-device/android\",\"modules\":[\"expo.modules.device.DeviceModule\"]}]},{\"packageName\":\"expo-document-picker\",\"packageVersion\":\"13.1.5\",\"projects\":[{\"name\":\"expo-document-picker\",\"sourceDir\":\"../../packages/expo-document-picker/android\",\"modules\":[\"expo.modules.documentpicker.DocumentPickerModule\"]}]},{\"packageName\":\"expo-eas-client\",\"packageVersion\":\"0.14.3\",\"projects\":[{\"name\":\"expo-eas-client\",\"sourceDir\":\"../../packages/expo-eas-client/android\",\"modules\":[\"expo.modules.easclient.EASClientModule\"]}]},{\"packageName\":\"expo-file-system\",\"packageVersion\":\"18.1.10\",\"projects\":[{\"name\":\"expo-file-system\",\"sourceDir\":\"../../packages/expo-file-system/android\",\"modules\":[\"expo.modules.filesystem.FileSystemModule\",\"expo.modules.filesystem.next.FileSystemNextModule\"]}]},{\"packageName\":\"expo-font\",\"packageVersion\":\"13.3.1\",\"projects\":[{\"name\":\"expo-font\",\"sourceDir\":\"../../packages/expo-font/android\",\"modules\":[\"expo.modules.font.FontLoaderModule\",\"expo.modules.font.FontUtilsModule\"]}]},{\"packageName\":\"expo-gl\",\"packageVersion\":\"15.1.5\",\"projects\":[{\"name\":\"expo-gl\",\"sourceDir\":\"../../packages/expo-gl/android\",\"modules\":[\"expo.modules.gl.GLViewModule\",\"expo.modules.gl.GLObjectManagerModule\"]}]},{\"packageName\":\"expo-haptics\",\"packageVersion\":\"14.1.4\",\"projects\":[{\"name\":\"expo-haptics\",\"sourceDir\":\"../../packages/expo-haptics/android\",\"modules\":[\"expo.modules.haptics.HapticsModule\"]}]},{\"packageName\":\"expo-image\",\"packageVersion\":\"2.3.0\",\"projects\":[{\"name\":\"expo-image\",\"sourceDir\":\"../../packages/expo-image/android\",\"modules\":[\"expo.modules.image.ExpoImageModule\"]}]},{\"packageName\":\"expo-image-loader\",\"packageVersion\":\"5.1.0\",\"projects\":[{\"name\":\"expo-image-loader\",\"sourceDir\":\"../../packages/expo-image-loader/android\",\"modules\":[]}]},{\"packageName\":\"expo-image-manipulator\",\"packageVersion\":\"13.1.7\",\"projects\":[{\"name\":\"expo-image-manipulator\",\"sourceDir\":\"../../packages/expo-image-manipulator/android\",\"modules\":[\"expo.modules.imagemanipulator.ImageManipulatorModule\"]}]},{\"packageName\":\"expo-image-picker\",\"packageVersion\":\"16.1.4\",\"projects\":[{\"name\":\"expo-image-picker\",\"sourceDir\":\"../../packages/expo-image-picker/android\",\"modules\":[\"expo.modules.imagepicker.ImagePickerModule\"]}]},{\"packageName\":\"expo-insights\",\"packageVersion\":\"0.9.3\",\"projects\":[{\"name\":\"expo-insights\",\"sourceDir\":\"../../packages/expo-insights/android\",\"modules\":[\"expo.modules.insights.ExpoInsightsModule\"]}]},{\"packageName\":\"expo-intent-launcher\",\"packageVersion\":\"12.1.4\",\"projects\":[{\"name\":\"expo-intent-launcher\",\"sourceDir\":\"../../packages/expo-intent-launcher/android\",\"modules\":[\"expo.modules.intentlauncher.IntentLauncherModule\"]}]},{\"packageName\":\"expo-json-utils\",\"packageVersion\":\"0.15.0\",\"projects\":[{\"name\":\"expo-json-utils\",\"sourceDir\":\"../../packages/expo-json-utils/android\",\"modules\":[]}]},{\"packageName\":\"expo-keep-awake\",\"packageVersion\":\"14.1.4\",\"projects\":[{\"name\":\"expo-keep-awake\",\"sourceDir\":\"../../packages/expo-keep-awake/android\",\"modules\":[\"expo.modules.keepawake.KeepAwakeModule\"]}]},{\"packageName\":\"expo-linear-gradient\",\"packageVersion\":\"14.1.4\",\"projects\":[{\"name\":\"expo-linear-gradient\",\"sourceDir\":\"../../packages/expo-linear-gradient/android\",\"modules\":[\"expo.modules.lineargradient.LinearGradientModule\"]}]},{\"packageName\":\"expo-linking\",\"packageVersion\":\"7.1.5\",\"projects\":[{\"name\":\"expo-linking\",\"sourceDir\":\"../../packages/expo-linking/android\",\"modules\":[\"expo.modules.linking.ExpoLinkingModule\"]}]},{\"packageName\":\"expo-local-authentication\",\"packageVersion\":\"16.0.4\",\"projects\":[{\"name\":\"expo-local-authentication\",\"sourceDir\":\"../../packages/expo-local-authentication/android\",\"modules\":[\"expo.modules.localauthentication.LocalAuthenticationModule\"]}]},{\"packageName\":\"expo-localization\",\"packageVersion\":\"16.1.5\",\"projects\":[{\"name\":\"expo-localization\",\"sourceDir\":\"../../packages/expo-localization/android\",\"modules\":[\"expo.modules.localization.LocalizationModule\"]}]},{\"packageName\":\"expo-location\",\"packageVersion\":\"18.1.5\",\"projects\":[{\"name\":\"expo-location\",\"sourceDir\":\"../../packages/expo-location/android\",\"modules\":[\"expo.modules.location.LocationModule\"]}]},{\"packageName\":\"expo-mail-composer\",\"packageVersion\":\"14.1.4\",\"projects\":[{\"name\":\"expo-mail-composer\",\"sourceDir\":\"../../packages/expo-mail-composer/android\",\"modules\":[\"expo.modules.mailcomposer.MailComposerModule\"]}]},{\"packageName\":\"expo-manifests\",\"packageVersion\":\"0.16.5\",\"projects\":[{\"name\":\"expo-manifests\",\"sourceDir\":\"../../packages/expo-manifests/android\",\"modules\":[]}]},{\"packageName\":\"expo-maps\",\"packageVersion\":\"0.10.0\",\"projects\":[{\"name\":\"expo-maps\",\"sourceDir\":\"../../packages/expo-maps/android\",\"modules\":[\"expo.modules.maps.MapsModule\",\"expo.modules.maps.GoogleMapsModule\",\"expo.modules.maps.StreetViewModule\"]}],\"coreFeatures\":[\"swiftui\",\"compose\"]},{\"packageName\":\"expo-media-library\",\"packageVersion\":\"17.1.6\",\"projects\":[{\"name\":\"expo-media-library\",\"sourceDir\":\"../../packages/expo-media-library/android\",\"modules\":[\"expo.modules.medialibrary.MediaLibraryModule\"]}]},{\"packageName\":\"expo-mesh-gradient\",\"packageVersion\":\"0.3.4\",\"projects\":[{\"name\":\"expo-mesh-gradient\",\"sourceDir\":\"../../packages/expo-mesh-gradient/android\",\"modules\":[\"expo.modules.meshgradient.MeshGradientModule\"]}],\"coreFeatures\":[\"swiftui\",\"compose\"]},{\"packageName\":\"expo-modules-core\",\"packageVersion\":\"2.3.13\",\"projects\":[{\"name\":\"expo-modules-core\",\"sourceDir\":\"../../packages/expo-modules-core/android\",\"modules\":[]}],\"plugins\":[{\"id\":\"expo-module-gradle-plugin\",\"group\":\"expo.modules\",\"sourceDir\":\"../../packages/expo-modules-core/expo-module-gradle-plugin\",\"applyToRootProject\":false}]},{\"packageName\":\"expo-navigation-bar\",\"packageVersion\":\"4.2.4\",\"projects\":[{\"name\":\"expo-navigation-bar\",\"sourceDir\":\"../../packages/expo-navigation-bar/android\",\"modules\":[\"expo.modules.navigationbar.NavigationBarModule\"]}]},{\"packageName\":\"expo-network\",\"packageVersion\":\"7.1.5\",\"projects\":[{\"name\":\"expo-network\",\"sourceDir\":\"../../packages/expo-network/android\",\"modules\":[\"expo.modules.network.NetworkModule\"]}]},{\"packageName\":\"expo-network-addons\",\"packageVersion\":\"0.9.3\",\"projects\":[{\"name\":\"expo-network-addons\",\"sourceDir\":\"../../packages/expo-network-addons/android\",\"modules\":[]}],\"plugins\":[{\"id\":\"expo-network-addons-gradle-plugin\",\"group\":\"expo.modules\",\"sourceDir\":\"../../packages/expo-network-addons/expo-network-addons-gradle-plugin\",\"applyToRootProject\":true}]},{\"packageName\":\"expo-notifications\",\"packageVersion\":\"0.31.2\",\"projects\":[{\"name\":\"expo-notifications\",\"sourceDir\":\"../../packages/expo-notifications/android\",\"modules\":[\"expo.modules.notifications.badge.BadgeModule\",\"expo.modules.notifications.notifications.background.ExpoBackgroundNotificationTasksModule\",\"expo.modules.notifications.notifications.categories.ExpoNotificationCategoriesModule\",\"expo.modules.notifications.notifications.channels.NotificationChannelGroupManagerModule\",\"expo.modules.notifications.notifications.channels.NotificationChannelManagerModule\",\"expo.modules.notifications.notifications.emitting.NotificationsEmitter\",\"expo.modules.notifications.notifications.handling.NotificationsHandler\",\"expo.modules.notifications.permissions.NotificationPermissionsModule\",\"expo.modules.notifications.notifications.presentation.ExpoNotificationPresentationModule\",\"expo.modules.notifications.notifications.scheduling.NotificationScheduler\",\"expo.modules.notifications.serverregistration.ServerRegistrationModule\",\"expo.modules.notifications.tokens.PushTokenModule\"]}]},{\"packageName\":\"expo-print\",\"packageVersion\":\"14.1.4\",\"projects\":[{\"name\":\"expo-print\",\"sourceDir\":\"../../packages/expo-print/android\",\"modules\":[\"expo.modules.print.PrintModule\"]}]},{\"packageName\":\"expo-screen-capture\",\"packageVersion\":\"7.1.4\",\"projects\":[{\"name\":\"expo-screen-capture\",\"sourceDir\":\"../../packages/expo-screen-capture/android\",\"modules\":[\"expo.modules.screencapture.ScreenCaptureModule\"]}]},{\"packageName\":\"expo-screen-orientation\",\"packageVersion\":\"8.1.6\",\"projects\":[{\"name\":\"expo-screen-orientation\",\"sourceDir\":\"../../packages/expo-screen-orientation/android\",\"modules\":[\"expo.modules.screenorientation.ScreenOrientationModule\"]}]},{\"packageName\":\"expo-secure-store\",\"packageVersion\":\"14.2.3\",\"projects\":[{\"name\":\"expo-secure-store\",\"sourceDir\":\"../../packages/expo-secure-store/android\",\"modules\":[\"expo.modules.securestore.SecureStoreModule\"]}]},{\"packageName\":\"expo-sensors\",\"packageVersion\":\"14.1.4\",\"projects\":[{\"name\":\"expo-sensors\",\"sourceDir\":\"../../packages/expo-sensors/android\",\"modules\":[\"expo.modules.sensors.modules.AccelerometerModule\",\"expo.modules.sensors.modules.BarometerModule\",\"expo.modules.sensors.modules.GyroscopeModule\",\"expo.modules.sensors.modules.LightSensorModule\",\"expo.modules.sensors.modules.DeviceMotionModule\",\"expo.modules.sensors.modules.MagnetometerModule\",\"expo.modules.sensors.modules.MagnetometerUncalibratedModule\",\"expo.modules.sensors.modules.PedometerModule\"]}]},{\"packageName\":\"expo-sharing\",\"packageVersion\":\"13.1.5\",\"projects\":[{\"name\":\"expo-sharing\",\"sourceDir\":\"../../packages/expo-sharing/android\",\"modules\":[\"expo.modules.sharing.SharingModule\"]}]},{\"packageName\":\"expo-sms\",\"packageVersion\":\"13.1.4\",\"projects\":[{\"name\":\"expo-sms\",\"sourceDir\":\"../../packages/expo-sms/android\",\"modules\":[\"expo.modules.sms.SMSModule\"]}]},{\"packageName\":\"expo-speech\",\"packageVersion\":\"13.1.7\",\"projects\":[{\"name\":\"expo-speech\",\"sourceDir\":\"../../packages/expo-speech/android\",\"modules\":[\"expo.modules.speech.SpeechModule\"]}]},{\"packageName\":\"expo-splash-screen\",\"packageVersion\":\"0.30.8\",\"projects\":[{\"name\":\"expo-splash-screen\",\"sourceDir\":\"../../packages/expo-splash-screen/android\",\"modules\":[\"expo.modules.splashscreen.SplashScreenModule\"]}]},{\"packageName\":\"expo-sqlite\",\"packageVersion\":\"15.2.10\",\"projects\":[{\"name\":\"expo-sqlite\",\"sourceDir\":\"../../packages/expo-sqlite/android\",\"modules\":[\"expo.modules.sqlite.SQLiteModule\"],\"shouldUsePublicationScriptPath\":\"/home/runner/work/expo/expo/packages/expo-sqlite/android/shouldUsePublication.groovy\"}]},{\"packageName\":\"expo-store-review\",\"packageVersion\":\"8.1.5\",\"projects\":[{\"name\":\"expo-store-review\",\"sourceDir\":\"../../packages/expo-store-review/android\",\"modules\":[\"expo.modules.storereview.StoreReviewModule\"]}]},{\"packageName\":\"expo-structured-headers\",\"packageVersion\":\"4.1.0\",\"projects\":[{\"name\":\"expo-structured-headers\",\"sourceDir\":\"../../packages/expo-structured-headers/android\",\"modules\":[]}]},{\"packageName\":\"expo-system-ui\",\"packageVersion\":\"5.0.7\",\"projects\":[{\"name\":\"expo-system-ui\",\"sourceDir\":\"../../packages/expo-system-ui/android\",\"modules\":[\"expo.modules.systemui.SystemUIModule\"]}]},{\"packageName\":\"expo-task-manager\",\"packageVersion\":\"13.1.5\",\"projects\":[{\"name\":\"expo-task-manager\",\"sourceDir\":\"../../packages/expo-task-manager/android\",\"modules\":[\"expo.modules.taskManager.TaskManagerModule\"]}]},{\"packageName\":\"expo-tracking-transparency\",\"packageVersion\":\"5.2.4\",\"projects\":[{\"name\":\"expo-tracking-transparency\",\"sourceDir\":\"../../packages/expo-tracking-transparency/android\",\"modules\":[\"expo.modules.trackingtransparency.TrackingTransparencyModule\"]}]},{\"packageName\":\"expo-updates\",\"packageVersion\":\"0.28.13\",\"projects\":[{\"name\":\"expo-updates\",\"sourceDir\":\"../../packages/expo-updates/android\",\"modules\":[\"expo.modules.updates.UpdatesModule\"]}],\"plugins\":[{\"id\":\"expo-updates-gradle-plugin\",\"group\":\"expo.modules\",\"sourceDir\":\"../../packages/expo-updates/expo-updates-gradle-plugin\",\"applyToRootProject\":true}]},{\"packageName\":\"expo-updates-interface\",\"packageVersion\":\"1.1.0\",\"projects\":[{\"name\":\"expo-updates-interface\",\"sourceDir\":\"../../packages/expo-updates-interface/android\",\"modules\":[]}]},{\"packageName\":\"expo-video\",\"packageVersion\":\"2.1.9\",\"projects\":[{\"name\":\"expo-video\",\"sourceDir\":\"../../packages/expo-video/android\",\"modules\":[\"expo.modules.video.VideoModule\"]}]},{\"packageName\":\"expo-video-thumbnails\",\"packageVersion\":\"9.1.3\",\"projects\":[{\"name\":\"expo-video-thumbnails\",\"sourceDir\":\"../../packages/expo-video-thumbnails/android\",\"modules\":[\"expo.modules.videothumbnails.VideoThumbnailsModule\"]}]},{\"packageName\":\"expo-web-browser\",\"packageVersion\":\"14.1.6\",\"projects\":[{\"name\":\"expo-web-browser\",\"sourceDir\":\"../../packages/expo-web-browser/android\",\"modules\":[\"expo.modules.webbrowser.WebBrowserModule\"]}]},{\"packageName\":\"unimodules-app-loader\",\"packageVersion\":\"5.1.3\",\"projects\":[{\"name\":\"unimodules-app-loader\",\"sourceDir\":\"../../packages/unimodules-app-loader/android\",\"modules\":[]}]}],\"configuration\":{\"buildFromSource\":[\".*\"]}}",
      "reasons": [
        "expoAutolinkingAndroid"
      ],
      "hash": "6ec038398616e78ffa8a8a4d86d8c864d23c3e8c"
    }
  }
]

Generated by PR labeler 🤖

@Wenszel Wenszel marked this pull request as ready for review July 25, 2025 07:20
@Wenszel Wenszel requested a review from lukmccall July 25, 2025 07:20
Copy link
Contributor

Subscribed to pull request

File Patterns Mentions
packages/expo-media-library/** @behenate, @alanjhughes

Generated by CodeMention

@expo-bot
Copy link
Collaborator

Hi there! 👋 I'm a bot whose goal is to ensure your contributions meet our guidelines.

I've found some issues in your pull request that should be addressed (click on them for more details) 👇

⚠️ Suggestion: Missing changelog entries


Your changes should be noted in the changelog, e.g.:
- [android] Remove promises ([#38301](https://github.com/expo/expo/pull/38301) by [@Wenszel](https://github.com/Wenszel))
Read Updating Changelogs guide and consider adding an appropriate entry to the following changelogs:


Generated by ExpoBot 🤖 against 4ecbf05

@Wenszel Wenszel requested a review from lukmccall July 28, 2025 14:43
Comment on lines +35 to +36
class UnableToLoadPermissionException(message: String, cause: Throwable? = null) :
CodedException(message, cause)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
class UnableToLoadPermissionException(message: String, cause: Throwable? = null) :
CodedException(message, cause)

Assuming UnableToLoadPermissionException is no different to PermissionsException, we can change

class PermissionsException(message: String) :
  CodedException(message)

to

class PermissionsException(message: String, cause: Throwable? = null) :
  CodedException(message, cause)

promise: Promise,
block: () -> Unit
private fun <T> actionIfUserGrantedPermission(
block: () -> T
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not 100% positive that this will work correctly, but if does should simplify the code a bit:
Step 1:

Suggested change
block: () -> T
block: suspend () -> T

Also since we we use runActionWithPermissions in the end of each function at the end anyways, do we need this actionIfUserGrantedPermission at all?

private fun interface Action {
fun runWithPermissions(permissionsWereGranted: Boolean)
private fun interface Action<out T> {
fun runWithPermissions(permissionsWereGranted: Boolean): T
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Step 2:

Suggested change
fun runWithPermissions(permissionsWereGranted: Boolean): T
suspend fun runWithPermissions(permissionsWereGranted: Boolean): T

Comment on lines +157 to +160
val action = actionIfUserGrantedPermission {
assetId?.let {
return@actionIfUserGrantedPermission runBlocking {
CreateAlbum(context, albumName, assetId, copyAsset).execute()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

step 3:
We can avoid all runBlocking blocks 😄

(also we can return the expression with ?.let instead of writing null at the end)

Suggested change
val action = actionIfUserGrantedPermission {
assetId?.let {
return@actionIfUserGrantedPermission runBlocking {
CreateAlbum(context, albumName, assetId, copyAsset).execute()
val action = actionIfUserGrantedPermission {
assetId?.let {
return@actionIfUserGrantedPermission CreateAlbum(context, albumName, assetId, copyAsset).execute()
}
return@actionIfUserGrantedPermission initialAssetUri?.let {
CreateAlbumWithInitialFileUri(context, albumName, it).execute()
}
}

"Could not delete asset: need WRITE_EXTERNAL_STORAGE permission.",
e
)
throw UnableToDeleteException("Could not delete asset: need WRITE_EXTERNAL_STORAGE permission.", e)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd consider changing this to PermissionsException it's up to you though 🫡

"Could not get albums: need READ_EXTERNAL_STORAGE permission.",
e
)
throw UnableToLoadException("Could not get albums: need READ_EXTERNAL_STORAGE permission ${e.message}", e)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe a PermissionsException would work better here?

@@ -58,23 +54,19 @@ fun queryAssetInfo(
// actually we want to return just the first item, but array.getMap returns ReadableMap
// which is not compatible with promise.resolve and there is no simple solution to convert
// ReadableMap to WritableMap so it's easier to return an array and pick the first item on JS side
promise.resolve(array)
return array
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not introduced by you, but we can clean this up a quite a bit while we are here.

      if (assetCursor == null) {
        throw AssetQueryException()
      } else {

We don't need the else block, since throwing the exception will assure assetCursor exists

      if (assetCursor == null) {
        throw AssetQueryException()
      } 
      [code from the `else` block]

Also to reduce indentation we can do

      if (assetCursor.count != null) {
        return null
      }
      [the code from inside `if (assetCursor.count == 1)`]

Feel free to introduce it in this PR or some later general cleanup PR 😄

is IOException -> UnableToLoadException("Could not read file $e")
is IllegalArgumentException -> UnableToLoadException(e.message ?: "Invalid MediaType $e")
is UnsupportedOperationException -> PermissionsException(e.message ?: "Permission denied $e")
is SecurityException -> UnableToLoadException("Could not get asset: need read_external_storage permission", e)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PermissionsException

Comment on lines +22 to +24
get() = requireNotNull(appContextProvider.appContext.reactContext) {
"React Application Context is null"
}.contentResolver
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
get() = requireNotNull(appContextProvider.appContext.reactContext) {
"React Application Context is null"
}.contentResolver
[add this import]
import import expo.modules.kotlin.exception.Exceptions
[then you can do]
get() = appContextProvider.appContext.reactContext?.contentResolver ?:
throw Exceptions.ReactContextLost()

Comment on lines +22 to +24
get() = requireNotNull(appContextProvider.appContext.reactContext) {
"React Application Context is null"
}.contentResolver
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as in DeleteContract.kt

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants