Move Geolocation JS code to FB internal

Summary: This removes the JS parts of Geolocation from React Native open source.

Reviewed By: yungsters

Differential Revision: D14693179

fbshipit-source-id: 1da5b7ec0e3e9d21d2019b7ee43e5f85661795b4
This commit is contained in:
Christoph Nakazawa
2019-04-01 15:21:59 -07:00
committed by Facebook Github Bot
parent 1b51cd488a
commit 9834c580af
5 changed files with 0 additions and 371 deletions
-182
View File
@@ -1,182 +0,0 @@
/**
* 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';
const NativeEventEmitter = require('NativeEventEmitter');
const RCTLocationObserver = require('NativeModules').LocationObserver;
const invariant = require('invariant');
const logError = require('logError');
const warning = require('fbjs/lib/warning');
const LocationEventEmitter = new NativeEventEmitter(RCTLocationObserver);
const Platform = require('Platform');
const PermissionsAndroid = require('PermissionsAndroid');
let subscriptions = [];
let updatesEnabled = false;
type GeoConfiguration = {
skipPermissionRequests: boolean,
};
export type GeoOptions = {
timeout?: number,
maximumAge?: number,
enableHighAccuracy?: boolean,
distanceFilter?: number,
useSignificantChanges?: boolean,
};
/**
* The Geolocation API extends the web spec:
* https://developer.mozilla.org/en-US/docs/Web/API/Geolocation
*
* See https://facebook.github.io/react-native/docs/geolocation.html
*/
const Geolocation = {
/*
* Sets configuration options that will be used in all location requests.
*
* See https://facebook.github.io/react-native/docs/geolocation.html#setrnconfiguration
*
*/
setRNConfiguration: function(config: GeoConfiguration) {
if (RCTLocationObserver.setConfiguration) {
RCTLocationObserver.setConfiguration(config);
}
},
/*
* Requests Location permissions based on the key configured on pList.
*
* See https://facebook.github.io/react-native/docs/geolocation.html#requestauthorization
*/
requestAuthorization: function() {
RCTLocationObserver.requestAuthorization();
},
/*
* Invokes the success callback once with the latest location info.
*
* See https://facebook.github.io/react-native/docs/geolocation.html#getcurrentposition
*/
getCurrentPosition: async function(
geo_success: Function,
geo_error?: Function,
geo_options?: GeoOptions,
) {
invariant(
typeof geo_success === 'function',
'Must provide a valid geo_success callback.',
);
let hasPermission = true;
// Supports Android's new permission model. For Android older devices,
// it's always on.
if (Platform.OS === 'android' && Platform.Version >= 23) {
hasPermission = await PermissionsAndroid.check(
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
);
if (!hasPermission) {
const status = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
);
hasPermission = status === PermissionsAndroid.RESULTS.GRANTED;
}
}
if (hasPermission) {
RCTLocationObserver.getCurrentPosition(
geo_options || {},
geo_success,
geo_error || logError,
);
}
},
/*
* Invokes the success callback whenever the location changes.
*
* See https://facebook.github.io/react-native/docs/geolocation.html#watchposition
*/
watchPosition: function(
success: Function,
error?: Function,
options?: GeoOptions,
): number {
if (!updatesEnabled) {
RCTLocationObserver.startObserving(options || {});
updatesEnabled = true;
}
const watchID = subscriptions.length;
subscriptions.push([
LocationEventEmitter.addListener('geolocationDidChange', success),
error
? LocationEventEmitter.addListener('geolocationError', error)
: null,
]);
return watchID;
},
/*
* Unsubscribes the watcher with the given watchID.
*
* See https://facebook.github.io/react-native/docs/geolocation.html#clearwatch
*/
clearWatch: function(watchID: number) {
const sub = subscriptions[watchID];
if (!sub) {
// Silently exit when the watchID is invalid or already cleared
// This is consistent with timers
return;
}
sub[0].remove();
// array element refinements not yet enabled in Flow
const sub1 = sub[1];
sub1 && sub1.remove();
subscriptions[watchID] = undefined;
let noWatchers = true;
for (let ii = 0; ii < subscriptions.length; ii++) {
if (subscriptions[ii]) {
noWatchers = false; // still valid subscriptions
}
}
if (noWatchers) {
Geolocation.stopObserving();
}
},
/*
* Stops observing for device location changes and removes all registered listeners.
*
* See https://facebook.github.io/react-native/docs/geolocation.html#stopobserving
*/
stopObserving: function() {
if (updatesEnabled) {
RCTLocationObserver.stopObserving();
updatesEnabled = false;
for (let ii = 0; ii < subscriptions.length; ii++) {
const sub = subscriptions[ii];
if (sub) {
warning(false, 'Called stopObserving with existing subscriptions.');
sub[0].remove();
// array element refinements not yet enabled in Flow
const sub1 = sub[1];
sub1 && sub1.remove();
}
}
subscriptions = [];
}
},
};
module.exports = Geolocation;
@@ -1,102 +0,0 @@
/**
* 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
* @emails oncall+react_native
*/
'use strict';
describe('Geolocation', () => {
let Geolocation;
const NativeModules = require('NativeModules');
beforeEach(() => {
jest.resetModules();
Geolocation = jest.requireActual('Geolocation');
});
afterEach(() => {
jest.clearAllMocks();
});
it('should set the location observer configuration', () => {
Geolocation.setRNConfiguration({skipPermissionRequests: true});
expect(
NativeModules.LocationObserver.setConfiguration.mock.calls.length,
).toEqual(1);
});
it('should request authorization for location requests', () => {
Geolocation.requestAuthorization();
expect(
NativeModules.LocationObserver.requestAuthorization.mock.calls.length,
).toEqual(1);
});
it('should get the current position and pass it to the given callback', () => {
const callback = () => {};
Geolocation.getCurrentPosition(callback);
expect(
NativeModules.LocationObserver.getCurrentPosition.mock.calls.length,
).toEqual(1);
expect(
NativeModules.LocationObserver.getCurrentPosition.mock.calls[0][1],
).toBe(callback);
});
it('should add a success listener to the geolocation', () => {
const watchID = Geolocation.watchPosition(() => {});
expect(watchID).toEqual(0);
expect(NativeModules.LocationObserver.addListener.mock.calls[0][0]).toBe(
'geolocationDidChange',
);
});
it('should add an error listener to the geolocation', () => {
const watchID = Geolocation.watchPosition(() => {}, () => {});
expect(watchID).toEqual(0);
expect(NativeModules.LocationObserver.addListener.mock.calls[1][0]).toBe(
'geolocationError',
);
});
it('should clear the listeners associated with a watchID', () => {
const watchID = Geolocation.watchPosition(() => {}, () => {});
Geolocation.clearWatch(watchID);
expect(NativeModules.LocationObserver.stopObserving.mock.calls.length).toBe(
1,
);
});
it('should correctly assess if all listeners have been cleared', () => {
const watchID = Geolocation.watchPosition(() => {}, () => {});
Geolocation.watchPosition(() => {}, () => {});
Geolocation.clearWatch(watchID);
expect(NativeModules.LocationObserver.stopObserving.mock.calls.length).toBe(
0,
);
});
it('should not fail if the watchID one wants to clear does not exist', () => {
Geolocation.watchPosition(() => {}, () => {});
Geolocation.clearWatch(42);
expect(NativeModules.LocationObserver.stopObserving.mock.calls.length).toBe(
0,
);
});
it('should stop observing and warn about removing existing subscriptions', () => {
const warningCallback = jest.fn();
jest.mock('fbjs/lib/warning', () => warningCallback);
Geolocation.watchPosition(() => {}, () => {});
Geolocation.stopObserving();
expect(NativeModules.LocationObserver.stopObserving.mock.calls.length).toBe(
1,
);
expect(warningCallback.mock.calls.length).toBeGreaterThanOrEqual(1);
});
});
-78
View File
@@ -1,78 +0,0 @@
/**
* 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 Geolocation from 'Geolocation';
const React = require('react');
const ReactNative = require('react-native');
const {StyleSheet, Text, View, Alert} = ReactNative;
class GeolocationExample extends React.Component<{}, $FlowFixMeState> {
state = {
initialPosition: 'unknown',
lastPosition: 'unknown',
};
watchID: ?number = null;
componentDidMount() {
Geolocation.getCurrentPosition(
position => {
const initialPosition = JSON.stringify(position);
this.setState({initialPosition});
},
error => Alert.alert('Error', JSON.stringify(error)),
{enableHighAccuracy: true, timeout: 20000, maximumAge: 1000},
);
this.watchID = Geolocation.watchPosition(position => {
const lastPosition = JSON.stringify(position);
this.setState({lastPosition});
});
}
componentWillUnmount() {
this.watchID != null && Geolocation.clearWatch(this.watchID);
}
render() {
return (
<View>
<Text>
<Text style={styles.title}>Initial position: </Text>
{this.state.initialPosition}
</Text>
<Text>
<Text style={styles.title}>Current position: </Text>
{this.state.lastPosition}
</Text>
</View>
);
}
}
const styles = StyleSheet.create({
title: {
fontWeight: '500',
},
});
exports.framework = 'React';
exports.title = 'Geolocation';
exports.description = 'Examples of using the Geolocation API.';
exports.examples = [
{
title: 'Geolocation',
render: function(): React.Element<any> {
return <GeolocationExample />;
},
},
];
-4
View File
@@ -156,10 +156,6 @@ const APIExamples: Array<RNTesterExample> = [
key: 'Dimensions',
module: require('./DimensionsExample'),
},
{
key: 'GeolocationExample',
module: require('./GeolocationExample'),
},
{
key: 'ImageEditingExample',
module: require('./ImageEditingExample'),
-5
View File
@@ -231,11 +231,6 @@ const APIExamples: Array<RNTesterExample> = [
module: require('./DimensionsExample'),
supportsTVOS: true,
},
{
key: 'GeolocationExample',
module: require('./GeolocationExample'),
supportsTVOS: false,
},
{
key: 'ImageEditingExample',
module: require('./ImageEditingExample'),