xref: /expo/packages/expo-cellular/src/Cellular.ts (revision 834d6aa0)
1import {
2  createPermissionHook,
3  PermissionStatus,
4  Platform,
5  UnavailabilityError,
6} from 'expo-modules-core';
7
8import { CellularGeneration, PermissionResponse } from './Cellular.types';
9import ExpoCellular from './ExpoCellular';
10
11export { CellularGeneration };
12
13// @needsAudit
14/**
15 * Indicates if the carrier allows making VoIP calls on its network. On Android, this checks whether
16 * the system supports SIP-based VoIP API. See [here](https://developer.android.com/reference/android/net/sip/SipManager.html#isVoipSupported(android.content.Context))
17 * to view more information.
18 *
19 * On iOS, if you configure a device for a carrier and then remove the SIM card, this property
20 * retains the `boolean` value indicating the carrier’s policy regarding VoIP. If you then install
21 * a new SIM card, its VoIP policy `boolean` replaces the previous value of this property.
22 *
23 * On web, this returns `null`.
24 *
25 * @example
26 * ```ts
27 * Cellular.allowsVoip; // true or false
28 * ```
29 * @deprecated Use [`allowsVoipAsync()`](#allowsvoipasync) instead.
30 *
31 */
32export const allowsVoip: boolean | null = ExpoCellular ? ExpoCellular.allowsVoip : null;
33
34// @needsAudit
35/**
36 * The name of the user’s home cellular service provider. If the device has dual SIM cards, only the
37 * carrier for the currently active SIM card will be returned. On Android, this value is only
38 * available when the SIM state is [`SIM_STATE_READY`](https://developer.android.com/reference/android/telephony/TelephonyManager.html#SIM_STATE_READY).
39 * Otherwise, this returns `null`.
40 *
41 * On iOS, if you configure a device for a carrier and then remove the SIM card, this property
42 * retains the name of the carrier. If you then install a new SIM card, its carrier name replaces
43 * the previous value of this property. The value for this property is `null` if the user never
44 * configured a carrier for the device.
45 *
46 * On web, this returns `null`.
47 *
48 * @example
49 * ```ts
50 * Cellular.carrier; // "T-Mobile" or "Verizon"
51 * ```
52 * @deprecated Use [`getCarrierNameAsync()`](#getcarriernameasync) instead.
53 *
54 */
55export const carrier: string | null = ExpoCellular ? ExpoCellular.carrier : null;
56
57// @needsAudit
58/**
59 * The ISO country code for the user’s cellular service provider. On iOS, the value is `null` if any
60 * of the following apply:
61 * - The device is in airplane mode.
62 * - There is no SIM card in the device.
63 * - The device is outside of cellular service range.
64 *
65 * On web, this returns `null`.
66 *
67 * @example
68 * ```ts
69 * Cellular.isoCountryCode; // "us" or "au"
70 * ```
71 * @deprecated Use [`getIsoCountryCodeAsync()`](#getisocountrycodeAsync) instead.
72 *
73 */
74export const isoCountryCode: string | null = ExpoCellular ? ExpoCellular.isoCountryCode : null;
75
76// @needsAudit
77/**
78 * The mobile country code (MCC) for the user’s current registered cellular service provider.
79 * On Android, this value is only available when SIM state is [`SIM_STATE_READY`](https://developer.android.com/reference/android/telephony/TelephonyManager.html#SIM_STATE_READY). Otherwise, this
80 * returns `null`. On iOS, the value may be null on hardware prior to iPhone 4S when in airplane mode.
81 * Furthermore, the value for this property is `null` if any of the following apply:
82 * - There is no SIM card in the device.
83 * - The device is outside of cellular service range.
84 *
85 * On web, this returns `null`.
86 *
87 * @example
88 * ```ts
89 * Cellular.mobileCountryCode; // "310"
90 * ```
91 * @deprecated Use [`getMobileCountryCodeAsync()`](#getmobilecountrycodeasync) instead.
92 *
93 */
94export const mobileCountryCode: string | null = ExpoCellular
95  ? ExpoCellular.mobileCountryCode
96  : null;
97
98// @needsAudit
99/**
100 * The ISO country code for the user’s cellular service provider. On iOS, the value is `null` if
101 * any of the following apply:
102 * - The device is in airplane mode.
103 * - There is no SIM card in the device.
104 * - The device is outside of cellular service range.
105 *
106 * On web, this returns `null`.
107 *
108 * @example
109 * ```ts
110 * Cellular.mobileNetworkCode; // "260"
111 * ```
112 * @deprecated Use [`getMobileNetworkCodeAsync()`](#getmobilenetworkcodeasync) instead.
113 *
114 */
115export const mobileNetworkCode: string | null = ExpoCellular
116  ? ExpoCellular.mobileNetworkCode
117  : null;
118
119// @needsAudit
120/**
121 * @return Returns a promise which fulfils with a [`Cellular.CellularGeneration`](#cellulargeneration)
122 * enum value that represents the current cellular-generation type.
123 *
124 * You will need to check if the native permission has been accepted to obtain generation.
125 * If the permission is denied `getCellularGenerationAsync` will resolve to `Cellular.Cellular Generation.UNKNOWN`.
126
127 *
128 * On web, this method uses [`navigator.connection.effectiveType`](https://developer.mozilla.org/en-US/docs/Web/API/NetworkInformation/effectiveType)
129 * to detect the effective type of the connection using a combination of recently observed
130 * round-trip time and downlink values. See [here](https://developer.mozilla.org/en-US/docs/Web/API/Network_Information_API)
131 * to view browser compatibility.
132 *
133 * @example
134 * ```ts
135 * await Cellular.getCellularGenerationAsync();
136 * // CellularGeneration.CELLULAR_4G
137 * ```
138 */
139export async function getCellularGenerationAsync(): Promise<CellularGeneration> {
140  if (!ExpoCellular.getCellularGenerationAsync) {
141    throw new UnavailabilityError('expo-cellular', 'getCellularGenerationAsync');
142  }
143  return await ExpoCellular.getCellularGenerationAsync();
144}
145
146/**
147 * @return Returns if the carrier allows making VoIP calls on its network. On Android, this checks whether
148 * the system supports SIP-based VoIP API. See [here](https://developer.android.com/reference/android/net/sip/SipManager.html#isVoipSupported(android.content.Context))
149 * to view more information.
150 *
151 * On iOS, if you configure a device for a carrier and then remove the SIM card, this property
152 * retains the `boolean` value indicating the carrier’s policy regarding VoIP. If you then install
153 * a new SIM card, its VoIP policy `boolean` replaces the previous value of this property.
154 *
155 * On web, this returns `null`.
156 *
157 * @example
158 * ```ts
159 * await Cellular.allowsVoipAsync(); // true or false
160 * ```
161 */
162export async function allowsVoipAsync(): Promise<boolean | null> {
163  if (!ExpoCellular.allowsVoipAsync) {
164    throw new UnavailabilityError('expo-cellular', 'allowsVoipAsync');
165  }
166  return await ExpoCellular.allowsVoipAsync();
167}
168
169/**
170 * @return Returns the ISO country code for the user’s cellular service provider.
171 *
172 * On iOS, the value is `null` if any of the following apply:
173 * - The device is in airplane mode.
174 * - There is no SIM card in the device.
175 * - The device is outside of cellular service range.
176 *
177 * On web, this returns `null`.
178 *
179 * @example
180 * ```ts
181 * await Cellular.getIsoCountryCodeAsync(); // "us" or "au"
182 * ```
183 *
184 */
185export async function getIsoCountryCodeAsync(): Promise<string | null> {
186  if (!ExpoCellular.getIsoCountryCodeAsync) {
187    throw new UnavailabilityError('expo-cellular', 'getIsoCountryCodeAsync');
188  }
189  return await ExpoCellular.getIsoCountryCodeAsync();
190}
191
192/**
193 * @return Returns name of the user’s home cellular service provider. If the device has dual SIM cards, only the
194 * carrier for the currently active SIM card will be returned.
195 *
196 * On Android, this value is only available when the SIM state is [`SIM_STATE_READY`](https://developer.android.com/reference/android/telephony/TelephonyManager.html#SIM_STATE_READY).
197 * Otherwise, this returns `null`.
198 *
199 * On iOS, if you configure a device for a carrier and then remove the SIM card, this property
200 * retains the name of the carrier. If you then install a new SIM card, its carrier name replaces
201 * the previous value of this property. The value for this property is `null` if the user never
202 * configured a carrier for the device.
203 *
204 * On web, this returns `null`.
205 *
206 * @example
207 * ```ts
208 * await Cellular.getCarrierNameAsync(); // "T-Mobile" or "Verizon"
209 * ```
210 */
211export async function getCarrierNameAsync(): Promise<string | null> {
212  if (!ExpoCellular.getCarrierNameAsync) {
213    throw new UnavailabilityError('expo-cellular', 'getCarrierNameAsync');
214  }
215  return await ExpoCellular.getCarrierNameAsync();
216}
217
218/**
219 * @return Returns mobile country code (MCC) for the user’s current registered cellular service provider.
220 *
221 * On Android, this value is only available when SIM state is [`SIM_STATE_READY`](https://developer.android.com/reference/android/telephony/TelephonyManager.html#SIM_STATE_READY). Otherwise, this
222 * returns `null`. On iOS, the value may be null on hardware prior to iPhone 4S when in airplane mode.
223 * Furthermore, the value for this property is `null` if any of the following apply:
224 * - There is no SIM card in the device.
225 * - The device is outside of cellular service range.
226 *
227 * On web, this returns `null`.
228 *
229 * @example
230 * ```ts
231 * await Cellular.getMobileCountryCodeAsync(); // "310"
232 * ```
233 */
234export async function getMobileCountryCodeAsync(): Promise<string | null> {
235  if (!ExpoCellular.getMobileCountryCodeAsync) {
236    throw new UnavailabilityError('expo-cellular', 'getMobileCountryCodeAsync');
237  }
238  return await ExpoCellular.getMobileCountryCodeAsync();
239}
240
241/**
242 * @return Returns the mobile network code (MNC) for the user’s current registered cellular service provider.
243 *
244 * On Android, this value is only available when SIM state is [`SIM_STATE_READY`](https://developer.android.com/reference/android/telephony/TelephonyManager.html#SIM_STATE_READY). Otherwise, this
245 * returns `null`. On iOS, the value may be null on hardware prior to iPhone 4S when in airplane mode.
246 * Furthermore, the value for this property is `null` if any of the following apply:
247 * - There is no SIM card in the device.
248 * - The device is outside of cellular service range.
249 *
250 * On web, this returns `null`.
251 *
252 * @example
253 * ```ts
254 * await Cellular.getMobileNetworkCodeAsync(); // "310"
255 * ```
256 */
257export async function getMobileNetworkCodeAsync(): Promise<string | null> {
258  if (!ExpoCellular.getMobileNetworkCodeAsync) {
259    throw new UnavailabilityError('expo-cellular', 'getMobileNetworkCodeAsync');
260  }
261  return await ExpoCellular.getMobileNetworkCodeAsync();
262}
263
264/**
265 * Checks user's permissions for accessing phone state.
266 */
267export async function getPermissionsAsync(): Promise<PermissionResponse> {
268  if (Platform.OS === 'android') {
269    return await ExpoCellular.getPermissionsAsync();
270  }
271
272  return {
273    status: PermissionStatus.GRANTED,
274    expires: 'never',
275    granted: true,
276    canAskAgain: true,
277  };
278}
279
280/**
281 * Asks the user to grant permissions for accessing the phone state.
282 */
283export async function requestPermissionsAsync(): Promise<PermissionResponse> {
284  if (Platform.OS === 'android') {
285    return await ExpoCellular.requestPermissionsAsync();
286  }
287
288  return {
289    status: PermissionStatus.GRANTED,
290    expires: 'never',
291    granted: true,
292    canAskAgain: true,
293  };
294}
295
296/**
297 * Check or request permissions to access the phone state.
298 * This uses both `Cellular.requestPermissionsAsync` and `Cellular.getPermissionsAsync` to interact with the permissions.
299 *
300 * @example
301 * ```ts
302 * const [status, requestPermission] = Cellular.usePermissions();
303 * ```
304 */
305export const usePermissions = createPermissionHook({
306  getMethod: getPermissionsAsync,
307  requestMethod: requestPermissionsAsync,
308});
309