1import { UnavailabilityError } from '@unimodules/core';
2import { PermissionResponse, PermissionStatus, PermissionExpiration } from 'expo-modules-core';
3import { Platform } from 'react-native';
4
5import ExpoTrackingTransparency from './ExpoTrackingTransparency';
6
7const androidAndWebPermissionsResponse: PermissionResponse = {
8  granted: true,
9  expires: 'never',
10  canAskAgain: true,
11  status: PermissionStatus.GRANTED,
12};
13
14/**
15 * Requests the user to authorize or deny access to app-related data that can be used for tracking
16 * the user or the device. Examples of data used for tracking include email address, device ID,
17 * advertising ID, etc. On iOS 14.5 and above, if the user denies this permission, any attempt to
18 * collect the IDFA will return a string of 0s.
19 *
20 * The system remembers the user’s choice and doesn’t prompt again unless a user uninstalls and then
21 * reinstalls the app on the device.
22 *
23 * On Android, web, and iOS 13 and below, this method always returns that the permission was
24 * granted.
25 * @example
26 * ```typescript
27 * const { granted } = await requestTrackingPermissionsAsync();
28 *
29 * if (granted) {
30 *   // Your app is authorized to track the user or their device
31 * }
32 * ```
33 */
34export async function requestTrackingPermissionsAsync(): Promise<PermissionResponse> {
35  if (Platform.OS !== 'ios') {
36    return Promise.resolve(androidAndWebPermissionsResponse);
37  }
38
39  if (!ExpoTrackingTransparency.requestPermissionsAsync) {
40    throw new UnavailabilityError('TrackingTransparency', 'requestPermissionsAsync');
41  }
42  return await ExpoTrackingTransparency.requestPermissionsAsync();
43}
44
45/**
46 * Checks whether or not the user has authorized the app to access app-related data that can be used
47 * for tracking the user or the device. See `requestPermissionsAsync` for more details.
48 *
49 * On Android, web, and iOS 13 and below, this method always returns that the permission was
50 * granted.
51 *
52 * @example
53 * ```typescript
54 * const { granted } = await getTrackingPermissionsAsync();
55 *
56 * if (granted) {
57 *   // Your app is authorized to track the user or their device
58 * }
59 * ```
60 */
61export async function getTrackingPermissionsAsync(): Promise<PermissionResponse> {
62  if (Platform.OS !== 'ios') {
63    return Promise.resolve(androidAndWebPermissionsResponse);
64  }
65
66  if (!ExpoTrackingTransparency.getPermissionsAsync) {
67    throw new UnavailabilityError('TrackingTransparency', 'getPermissionsAsync');
68  }
69  return await ExpoTrackingTransparency.getPermissionsAsync();
70}
71
72/**
73 * Returns whether the TrackingTransparency API is available on the current device.
74 *
75 * @returns Currently this is `true` on iOS 14 and above only. On devices where the
76 * Tracking Transparency API is unavailable, the get and request permissions methods will always
77 * resolve to `granted`.
78 */
79export function isAvailable(): boolean {
80  return (
81    Platform.OS === 'ios' &&
82    parseInt(Platform.Version.toString(), 10) >= 14 &&
83    ExpoTrackingTransparency
84  );
85}
86
87export { PermissionResponse, PermissionStatus, PermissionExpiration };
88