1import {
2  AndroidConfig,
3  ConfigPlugin,
4  createRunOncePlugin,
5  withInfoPlist,
6} from 'expo/config-plugins';
7
8const pkg = require('expo-location/package.json');
9const LOCATION_USAGE = 'Allow $(PRODUCT_NAME) to access your location';
10
11const withBackgroundLocation: ConfigPlugin = (config) => {
12  return withInfoPlist(config, (config) => {
13    if (!Array.isArray(config.modResults.UIBackgroundModes)) {
14      config.modResults.UIBackgroundModes = [];
15    }
16    if (!config.modResults.UIBackgroundModes.includes('location')) {
17      config.modResults.UIBackgroundModes.push('location');
18    }
19    return config;
20  });
21};
22
23const withLocation: ConfigPlugin<
24  {
25    locationAlwaysAndWhenInUsePermission?: string;
26    locationAlwaysPermission?: string;
27    locationWhenInUsePermission?: string;
28    isIosBackgroundLocationEnabled?: boolean;
29    isAndroidBackgroundLocationEnabled?: boolean;
30  } | void
31> = (
32  config,
33  {
34    locationAlwaysAndWhenInUsePermission,
35    locationAlwaysPermission,
36    locationWhenInUsePermission,
37    isIosBackgroundLocationEnabled,
38    isAndroidBackgroundLocationEnabled,
39  } = {}
40) => {
41  if (isIosBackgroundLocationEnabled) {
42    config = withBackgroundLocation(config);
43  }
44
45  config = withInfoPlist(config, (config) => {
46    config.modResults.NSLocationAlwaysAndWhenInUseUsageDescription =
47      locationAlwaysAndWhenInUsePermission ||
48      config.modResults.NSLocationAlwaysAndWhenInUseUsageDescription ||
49      LOCATION_USAGE;
50    config.modResults.NSLocationAlwaysUsageDescription =
51      locationAlwaysPermission ||
52      config.modResults.NSLocationAlwaysUsageDescription ||
53      LOCATION_USAGE;
54    config.modResults.NSLocationWhenInUseUsageDescription =
55      locationWhenInUsePermission ||
56      config.modResults.NSLocationWhenInUseUsageDescription ||
57      LOCATION_USAGE;
58
59    return config;
60  });
61
62  return AndroidConfig.Permissions.withPermissions(
63    config,
64    [
65      'android.permission.ACCESS_COARSE_LOCATION',
66      'android.permission.ACCESS_FINE_LOCATION',
67      'android.permission.FOREGROUND_SERVICE',
68      // Optional
69      isAndroidBackgroundLocationEnabled && 'android.permission.ACCESS_BACKGROUND_LOCATION',
70    ].filter(Boolean) as string[]
71  );
72};
73
74export default createRunOncePlugin(withLocation, pkg.name, pkg.version);
75