-
Notifications
You must be signed in to change notification settings - Fork 24.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Summary: This moves into open source the PermissionsModule and the activity and listener interfaces necessary to make permissions work. It also moves the PermissionsExample into the UIExplorer. In order to make this work, the device has to be Android M and above, and the target sdk of the app has to be 23+, so I changed the uiexplorer manifest to target that API. This has the unfortunate consequence that people testing on devices with API 23+ will have to enable the `draw over other apps` setting that react needs for RedBoxing. The app will automatically send the user to that screen, so enabling the setting and resuming the app should be trivial. For testing, try requesting permission for a permission that is currently revoked. If a permission is granted, it can be revoked via adb (`adb shell pm revoke com.your.app android.permission.PERMISSION_NAME`), and then requested. Reviewed By: bestander Differential Revision: D3431324 fbshipit-source-id: 8cbaea676d2b5727cb5191cdb77a02e213bf9ba3
- Loading branch information
1 parent
4fe7a25
commit b7352b4
Showing
10 changed files
with
425 additions
and
8 deletions.
There are no files selected for viewing
155 changes: 155 additions & 0 deletions
155
Examples/UIExplorer/PermissionsExampleAndroid.android.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,155 @@ | ||
/** | ||
* Copyright (c) 2013-present, Facebook, Inc. | ||
* All rights reserved. | ||
* | ||
* This source code is licensed under the BSD-style license found in the | ||
* LICENSE file in the root directory of this source tree. An additional grant | ||
* of patent rights can be found in the PATENTS file in the same directory. | ||
* | ||
* The examples provided by Facebook are for non-commercial testing and | ||
* evaluation purposes only. | ||
* | ||
* Facebook reserves all rights not expressly granted. | ||
* | ||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | ||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL | ||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN | ||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
* | ||
* @providesModule PermissionsExampleAndroid | ||
* @flow | ||
*/ | ||
'use strict'; | ||
|
||
const React = require('react'); | ||
const ReactNative = require('react-native'); | ||
const { | ||
StyleSheet, | ||
Text, | ||
TextInput, | ||
TouchableWithoutFeedback, | ||
View, | ||
} = ReactNative; | ||
const DialogManager = require('NativeModules').DialogManagerAndroid; | ||
const Permissions = require('NativeModules').AndroidPermissions; | ||
|
||
exports.displayName = (undefined: ?string); | ||
exports.framework = 'React'; | ||
exports.title = '<Permissions>'; | ||
exports.description = 'Permissions example for API 23+.'; | ||
|
||
const PermissionsExample = React.createClass({ | ||
getInitialState: function() { | ||
return { | ||
permission: 'android.permission.WRITE_EXTERNAL_STORAGE', | ||
hasPermission: 'Not Checked', | ||
}; | ||
}, | ||
|
||
render: function() { | ||
return ( | ||
<View style={styles.container}> | ||
<Text style={styles.text}>Permission Name:</Text> | ||
<TextInput | ||
autoFocus={true} | ||
autoCorrect={false} | ||
style={styles.singleLine} | ||
onChange={this._updateText} | ||
defaultValue={this.state.permission} | ||
/> | ||
<TouchableWithoutFeedback onPress={this._checkPermission}> | ||
<View> | ||
<Text style={[styles.touchable, styles.text]}>Check Permission</Text> | ||
</View> | ||
</TouchableWithoutFeedback> | ||
<Text style={styles.text}>Permission Status: {this.state.hasPermission}</Text> | ||
<TouchableWithoutFeedback onPress={this._shouldExplainPermission}> | ||
<View> | ||
<Text style={[styles.touchable, styles.text]}>Request Permission</Text> | ||
</View> | ||
</TouchableWithoutFeedback> | ||
</View> | ||
); | ||
}, | ||
|
||
_updateText: function(event: Object) { | ||
this.setState({ | ||
permission: event.nativeEvent.text, | ||
}); | ||
}, | ||
|
||
_checkPermission: function() { | ||
Permissions.checkPermission( | ||
this.state.permission, | ||
(permission: string, result: boolean) => { | ||
this.setState({ | ||
hasPermission: (result ? 'Granted' : 'Revoked') + ' for ' + permission, | ||
}); | ||
}, | ||
this._showError); | ||
}, | ||
|
||
_shouldExplainPermission: function() { | ||
Permissions.shouldShowRequestPermissionRationale( | ||
this.state.permission, | ||
(permission: string, shouldShow: boolean) => { | ||
if (shouldShow) { | ||
DialogManager.showAlert( | ||
{ | ||
title: 'Permission Explanation', | ||
message: | ||
'The app needs the following permission ' + this.state.permission + | ||
' because of reasons. Please approve.' | ||
}, | ||
this._showError, | ||
this._requestPermission); | ||
} else { | ||
this._requestPermission(); | ||
} | ||
}, | ||
this._showError); | ||
}, | ||
|
||
_requestPermission: function() { | ||
Permissions.requestPermission( | ||
this.state.permission, | ||
(permission: string, result: boolean) => { | ||
this.setState({ | ||
hasPermission: (result ? 'Granted' : 'Revoked') + ' for ' + permission, | ||
}); | ||
}, | ||
this._showError); | ||
}, | ||
|
||
_showError: function() { | ||
DialogManager.showAlert({message: 'Error'}, {}, {}); | ||
} | ||
}); | ||
|
||
exports.examples = [ | ||
{ | ||
title: 'Permissions Example', | ||
description: 'Short example of how to use the runtime permissions API introduced in Android M.', | ||
render: () => <PermissionsExample />, | ||
}, | ||
]; | ||
|
||
var styles = StyleSheet.create({ | ||
container: { | ||
flex: 1, | ||
backgroundColor: 'white', | ||
}, | ||
singleLine: { | ||
fontSize: 16, | ||
padding: 4, | ||
}, | ||
text: { | ||
margin: 10, | ||
}, | ||
touchable: { | ||
color: '#007AFF', | ||
}, | ||
}); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
39 changes: 39 additions & 0 deletions
39
ReactAndroid/src/main/java/com/facebook/react/modules/core/PermissionAwareActivity.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
/** | ||
* Copyright (c) 2015-present, Facebook, Inc. | ||
* All rights reserved. | ||
* | ||
* This source code is licensed under the BSD-style license found in the | ||
* LICENSE file in the root directory of this source tree. An additional grant | ||
* of patent rights can be found in the PATENTS file in the same directory. | ||
*/ | ||
|
||
package com.facebook.react.modules.core; | ||
|
||
import android.app.Activity; | ||
|
||
/** | ||
* Interface used to denote activities that can forward permission requests and call | ||
* {@link PermissionListener}s with the permission request results. | ||
*/ | ||
public interface PermissionAwareActivity { | ||
|
||
/** | ||
* See {@link Activity#checkPermission}. | ||
*/ | ||
int checkPermission(String permission, int pid, int uid); | ||
|
||
/** | ||
* See {@link Activity#checkSelfPermission}. | ||
*/ | ||
int checkSelfPermission(String permission); | ||
|
||
/** | ||
* See {@link Activity#shouldShowRequestPermissionRationale}. | ||
*/ | ||
boolean shouldShowRequestPermissionRationale(String permission); | ||
|
||
/** | ||
* See {@link Activity#requestPermissions}. | ||
*/ | ||
void requestPermissions(String[] permissions, int requestCode, PermissionListener listener); | ||
} |
27 changes: 27 additions & 0 deletions
27
ReactAndroid/src/main/java/com/facebook/react/modules/core/PermissionListener.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
/** | ||
* Copyright (c) 2015-present, Facebook, Inc. | ||
* All rights reserved. | ||
* | ||
* This source code is licensed under the BSD-style license found in the | ||
* LICENSE file in the root directory of this source tree. An additional grant | ||
* of patent rights can be found in the PATENTS file in the same directory. | ||
*/ | ||
|
||
package com.facebook.react.modules.core; | ||
|
||
import android.app.Activity; | ||
|
||
/** | ||
* Interface used by activities to delegate permission request results. Classes implementing this | ||
* class will be notified whenever there's a result for a permission request. | ||
*/ | ||
public interface PermissionListener { | ||
|
||
/** | ||
* Method called whenever there's a result to a permission request. It is forwarded from | ||
* {@link Activity#onRequestPermissionsResult}. | ||
* | ||
* @return boolean Whether the PermissionListener can be removed. | ||
*/ | ||
boolean onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults); | ||
} |
20 changes: 20 additions & 0 deletions
20
ReactAndroid/src/main/java/com/facebook/react/modules/permissions/BUCK
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
include_defs('//ReactAndroid/DEFS') | ||
|
||
android_library( | ||
name = 'permissions', | ||
srcs = glob(['**/*.java']), | ||
deps = [ | ||
react_native_target('java/com/facebook/react/bridge:bridge'), | ||
react_native_target('java/com/facebook/react/common:common'), | ||
react_native_target('java/com/facebook/react/modules/core:core'), | ||
react_native_dep('third-party/java/infer-annotations:infer-annotations'), | ||
react_native_dep('third-party/java/jsr-305:jsr-305'), | ||
], | ||
visibility = [ | ||
'PUBLIC', | ||
], | ||
) | ||
|
||
project_config( | ||
src_target = ':permissions', | ||
) |
Oops, something went wrong.