1import {
2  withPlugins,
3  AndroidConfig,
4  withProjectBuildGradle,
5  ConfigPlugin,
6  createRunOncePlugin,
7} from '@expo/config-plugins';
8
9const pkg = require('expo-camera/package.json');
10
11const CAMERA_USAGE = 'Allow $(PRODUCT_NAME) to access your camera';
12const MICROPHONE_USAGE = 'Allow $(PRODUCT_NAME) to access your microphone';
13
14// Because we need the package to be added AFTER the React and Google maven packages, we create a new allprojects.
15// It's ok to have multiple allprojects.repositories, so we create a new one since it's cheaper than tokenizing
16// the existing block to find the correct place to insert our camera maven.
17const gradleMaven =
18  'allprojects { repositories { maven { url "$rootDir/../node_modules/expo-camera/android/maven" } } }';
19
20const withAndroidCameraGradle: ConfigPlugin = (config) => {
21  return withProjectBuildGradle(config, (config) => {
22    if (config.modResults.language === 'groovy') {
23      config.modResults.contents = setGradleMaven(config.modResults.contents);
24    } else {
25      throw new Error('Cannot add camera maven gradle because the build.gradle is not groovy');
26    }
27    return config;
28  });
29};
30
31export function setGradleMaven(buildGradle: string): string {
32  // If this specific line is present, skip.
33  // This also enables users in bare workflow to comment out the line to prevent expo-camera from adding it back.
34  if (buildGradle.includes('expo-camera/android/maven')) {
35    return buildGradle;
36  }
37
38  return buildGradle + `\n${gradleMaven}\n`;
39}
40
41const withCamera: ConfigPlugin<{
42  cameraPermission?: string;
43  microphonePermission?: string;
44} | void> = (config, { cameraPermission, microphonePermission } = {}) => {
45  if (!config.ios) config.ios = {};
46  if (!config.ios.infoPlist) config.ios.infoPlist = {};
47  config.ios.infoPlist.NSCameraUsageDescription =
48    cameraPermission || config.ios.infoPlist.NSCameraUsageDescription || CAMERA_USAGE;
49  config.ios.infoPlist.NSMicrophoneUsageDescription =
50    microphonePermission || config.ios.infoPlist.NSMicrophoneUsageDescription || MICROPHONE_USAGE;
51
52  return withPlugins(config, [
53    [
54      AndroidConfig.Permissions.withPermissions,
55      [
56        'android.permission.CAMERA',
57        // Optional
58        'android.permission.RECORD_AUDIO',
59      ],
60    ],
61    withAndroidCameraGradle,
62  ]);
63};
64
65export default createRunOncePlugin(withCamera, pkg.name, pkg.version);
66