Files
react-native/Libraries/PermissionsAndroid/PermissionsAndroid.js
T
Kevin Gozali 3b65d2c2c8 Reland "[RN] TM Spec: relax PermissionsAndroid enforcement"
Summary: Original commit changeset: cb5ce87685dc

Reviewed By: cpojer

Differential Revision: D15578851

fbshipit-source-id: ab8cb9a14f94bbf4e850d9af91133612060e1401
2019-05-31 10:58:02 -07:00

229 lines
7.1 KiB
JavaScript

/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
* @flow
*/
'use strict';
import NativeDialogManagerAndroid from '../NativeModules/specs/NativeDialogManagerAndroid';
const Platform = require('../Utilities/Platform');
import NativePermissionsAndroid from './NativePermissionsAndroid';
import invariant from 'invariant';
import type {
PermissionStatus,
PermissionType,
} from './NativePermissionsAndroid';
export type Rationale = {
title: string,
message: string,
buttonPositive?: string,
buttonNegative?: string,
buttonNeutral?: string,
};
const PERMISSION_REQUEST_RESULT = Object.freeze({
GRANTED: 'granted',
DENIED: 'denied',
NEVER_ASK_AGAIN: 'never_ask_again',
});
const PERMISSIONS = Object.freeze({
READ_CALENDAR: 'android.permission.READ_CALENDAR',
WRITE_CALENDAR: 'android.permission.WRITE_CALENDAR',
CAMERA: 'android.permission.CAMERA',
READ_CONTACTS: 'android.permission.READ_CONTACTS',
WRITE_CONTACTS: 'android.permission.WRITE_CONTACTS',
GET_ACCOUNTS: 'android.permission.GET_ACCOUNTS',
ACCESS_FINE_LOCATION: 'android.permission.ACCESS_FINE_LOCATION',
ACCESS_COARSE_LOCATION: 'android.permission.ACCESS_COARSE_LOCATION',
RECORD_AUDIO: 'android.permission.RECORD_AUDIO',
READ_PHONE_STATE: 'android.permission.READ_PHONE_STATE',
CALL_PHONE: 'android.permission.CALL_PHONE',
READ_CALL_LOG: 'android.permission.READ_CALL_LOG',
WRITE_CALL_LOG: 'android.permission.WRITE_CALL_LOG',
ADD_VOICEMAIL: 'com.android.voicemail.permission.ADD_VOICEMAIL',
USE_SIP: 'android.permission.USE_SIP',
PROCESS_OUTGOING_CALLS: 'android.permission.PROCESS_OUTGOING_CALLS',
BODY_SENSORS: 'android.permission.BODY_SENSORS',
SEND_SMS: 'android.permission.SEND_SMS',
RECEIVE_SMS: 'android.permission.RECEIVE_SMS',
READ_SMS: 'android.permission.READ_SMS',
RECEIVE_WAP_PUSH: 'android.permission.RECEIVE_WAP_PUSH',
RECEIVE_MMS: 'android.permission.RECEIVE_MMS',
READ_EXTERNAL_STORAGE: 'android.permission.READ_EXTERNAL_STORAGE',
WRITE_EXTERNAL_STORAGE: 'android.permission.WRITE_EXTERNAL_STORAGE',
});
/**
* `PermissionsAndroid` provides access to Android M's new permissions model.
*
* See https://facebook.github.io/react-native/docs/permissionsandroid.html
*/
class PermissionsAndroid {
PERMISSIONS = PERMISSIONS;
RESULTS = PERMISSION_REQUEST_RESULT;
/**
* DEPRECATED - use check
*
* Returns a promise resolving to a boolean value as to whether the specified
* permissions has been granted
*
* @deprecated
*/
checkPermission(permission: PermissionType): Promise<boolean> {
console.warn(
'"PermissionsAndroid.checkPermission" is deprecated. Use "PermissionsAndroid.check" instead',
);
if (Platform.OS !== 'android') {
console.warn(
'"PermissionsAndroid" module works only for Android platform.',
);
return Promise.resolve(false);
}
invariant(
NativePermissionsAndroid,
'PermissionsAndroid is not installed correctly.',
);
return NativePermissionsAndroid.checkPermission(permission);
}
/**
* Returns a promise resolving to a boolean value as to whether the specified
* permissions has been granted
*
* See https://facebook.github.io/react-native/docs/permissionsandroid.html#check
*/
check(permission: PermissionType): Promise<boolean> {
if (Platform.OS !== 'android') {
console.warn(
'"PermissionsAndroid" module works only for Android platform.',
);
return Promise.resolve(false);
}
invariant(
NativePermissionsAndroid,
'PermissionsAndroid is not installed correctly.',
);
return NativePermissionsAndroid.checkPermission(permission);
}
/**
* DEPRECATED - use request
*
* Prompts the user to enable a permission and returns a promise resolving to a
* boolean value indicating whether the user allowed or denied the request
*
* If the optional rationale argument is included (which is an object with a
* `title` and `message`), this function checks with the OS whether it is
* necessary to show a dialog explaining why the permission is needed
* (https://developer.android.com/training/permissions/requesting.html#explain)
* and then shows the system permission dialog
*
* @deprecated
*/
async requestPermission(
permission: PermissionType,
rationale?: Rationale,
): Promise<boolean> {
console.warn(
'"PermissionsAndroid.requestPermission" is deprecated. Use "PermissionsAndroid.request" instead',
);
if (Platform.OS !== 'android') {
console.warn(
'"PermissionsAndroid" module works only for Android platform.',
);
return Promise.resolve(false);
}
const response = await this.request(permission, rationale);
return response === this.RESULTS.GRANTED;
}
/**
* Prompts the user to enable a permission and returns a promise resolving to a
* string value indicating whether the user allowed or denied the request
*
* See https://facebook.github.io/react-native/docs/permissionsandroid.html#request
*/
async request(
permission: PermissionType,
rationale?: Rationale,
): Promise<PermissionStatus> {
if (Platform.OS !== 'android') {
console.warn(
'"PermissionsAndroid" module works only for Android platform.',
);
return Promise.resolve(this.RESULTS.DENIED);
}
invariant(
NativePermissionsAndroid,
'PermissionsAndroid is not installed correctly.',
);
if (rationale) {
const shouldShowRationale = await NativePermissionsAndroid.shouldShowRequestPermissionRationale(
permission,
);
if (shouldShowRationale && !!NativeDialogManagerAndroid) {
return new Promise((resolve, reject) => {
const options = {
...rationale,
};
NativeDialogManagerAndroid.showAlert(
options,
() => reject(new Error('Error showing rationale')),
() =>
resolve(NativePermissionsAndroid.requestPermission(permission)),
);
});
}
}
return NativePermissionsAndroid.requestPermission(permission);
}
/**
* Prompts the user to enable multiple permissions in the same dialog and
* returns an object with the permissions as keys and strings as values
* indicating whether the user allowed or denied the request
*
* See https://facebook.github.io/react-native/docs/permissionsandroid.html#requestmultiple
*/
requestMultiple(
permissions: Array<PermissionType>,
): Promise<{[permission: PermissionType]: PermissionStatus}> {
if (Platform.OS !== 'android') {
console.warn(
'"PermissionsAndroid" module works only for Android platform.',
);
return Promise.resolve({});
}
invariant(
NativePermissionsAndroid,
'PermissionsAndroid is not installed correctly.',
);
return NativePermissionsAndroid.requestMultiplePermissions(permissions);
}
}
PermissionsAndroid = new PermissionsAndroid();
module.exports = PermissionsAndroid;