summaryrefslogtreecommitdiff
path: root/StoneIsland/plugins/cordova-plugin-geolocation/src
diff options
context:
space:
mode:
authorJules Laplace <jules@okfoc.us>2015-09-10 14:58:03 -0400
committerJules Laplace <jules@okfoc.us>2015-09-10 14:58:03 -0400
commitd73a4b1c5a2540077607dcc4001acbae85980ae4 (patch)
treec30089f1742f9430bb18679dc6664157a5dc66f4 /StoneIsland/plugins/cordova-plugin-geolocation/src
parent124e6c0a8d9577b4a30e0b265f5c23d637c41966 (diff)
app skeleton
Diffstat (limited to 'StoneIsland/plugins/cordova-plugin-geolocation/src')
-rw-r--r--StoneIsland/plugins/cordova-plugin-geolocation/src/firefoxos/GeolocationProxy.js67
-rw-r--r--StoneIsland/plugins/cordova-plugin-geolocation/src/ios/CDVLocation.h70
-rw-r--r--StoneIsland/plugins/cordova-plugin-geolocation/src/ios/CDVLocation.m366
-rw-r--r--StoneIsland/plugins/cordova-plugin-geolocation/src/ubuntu/geolocation.cpp119
-rw-r--r--StoneIsland/plugins/cordova-plugin-geolocation/src/ubuntu/geolocation.h69
-rw-r--r--StoneIsland/plugins/cordova-plugin-geolocation/src/windows/GeolocationProxy.js174
-rw-r--r--StoneIsland/plugins/cordova-plugin-geolocation/src/wp/GeoLocation.cs34
7 files changed, 899 insertions, 0 deletions
diff --git a/StoneIsland/plugins/cordova-plugin-geolocation/src/firefoxos/GeolocationProxy.js b/StoneIsland/plugins/cordova-plugin-geolocation/src/firefoxos/GeolocationProxy.js
new file mode 100644
index 00000000..e4b40529
--- /dev/null
+++ b/StoneIsland/plugins/cordova-plugin-geolocation/src/firefoxos/GeolocationProxy.js
@@ -0,0 +1,67 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+
+// latest geolocation spec can be found here: http://www.w3.org/TR/geolocation-API/
+
+var idsMap = {};
+
+module.exports = {
+ getLocation: function(success, error, args) {
+ var geo = cordova.require('cordova/modulemapper').getOriginalSymbol(window, 'navigator.geolocation');
+ function successCallback(position) {
+ // Cordova is creating Position object using just coords
+ success(position.coords);
+ }
+ geo.getCurrentPosition(successCallback, error, {
+ enableHighAccuracy: args[0],
+ maximumAge: args[1]
+ });
+ },
+
+ addWatch: function(success, error, args) {
+ var geo = cordova.require('cordova/modulemapper').getOriginalSymbol(window, 'navigator.geolocation');
+ var id = args[0];
+ function successCallback(position) {
+ success(position.coords);
+ }
+ var nativeId = geo.watchPosition(successCallback, error, {
+ enableHighAccuracy: args[1]
+ });
+
+ idsMap[id] = nativeId;
+ },
+
+ clearWatch: function(success, error, args) {
+ var geo = cordova.require('cordova/modulemapper').getOriginalSymbol(window, 'navigator.geolocation');
+ var id = args[0];
+
+ if(id in idsMap) {
+ geo.clearWatch(idsMap[id]);
+ delete idsMap[id];
+ }
+
+ if(success) {
+ success();
+ }
+ }
+};
+
+require("cordova/exec/proxy").add("Geolocation", module.exports);
diff --git a/StoneIsland/plugins/cordova-plugin-geolocation/src/ios/CDVLocation.h b/StoneIsland/plugins/cordova-plugin-geolocation/src/ios/CDVLocation.h
new file mode 100644
index 00000000..cce2738f
--- /dev/null
+++ b/StoneIsland/plugins/cordova-plugin-geolocation/src/ios/CDVLocation.h
@@ -0,0 +1,70 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ */
+
+#import <UIKit/UIKit.h>
+#import <CoreLocation/CoreLocation.h>
+#import <Cordova/CDVPlugin.h>
+
+enum CDVLocationStatus {
+ PERMISSIONDENIED = 1,
+ POSITIONUNAVAILABLE,
+ TIMEOUT
+};
+typedef NSUInteger CDVLocationStatus;
+
+// simple object to keep track of location information
+@interface CDVLocationData : NSObject {
+ CDVLocationStatus locationStatus;
+ NSMutableArray* locationCallbacks;
+ NSMutableDictionary* watchCallbacks;
+ CLLocation* locationInfo;
+}
+
+@property (nonatomic, assign) CDVLocationStatus locationStatus;
+@property (nonatomic, strong) CLLocation* locationInfo;
+@property (nonatomic, strong) NSMutableArray* locationCallbacks;
+@property (nonatomic, strong) NSMutableDictionary* watchCallbacks;
+
+@end
+
+@interface CDVLocation : CDVPlugin <CLLocationManagerDelegate>{
+ @private BOOL __locationStarted;
+ @private BOOL __highAccuracyEnabled;
+ CDVLocationData* locationData;
+}
+
+@property (nonatomic, strong) CLLocationManager* locationManager;
+@property (nonatomic, strong) CDVLocationData* locationData;
+
+- (void)getLocation:(CDVInvokedUrlCommand*)command;
+- (void)addWatch:(CDVInvokedUrlCommand*)command;
+- (void)clearWatch:(CDVInvokedUrlCommand*)command;
+- (void)returnLocationInfo:(NSString*)callbackId andKeepCallback:(BOOL)keepCallback;
+- (void)returnLocationError:(NSUInteger)errorCode withMessage:(NSString*)message;
+- (void)startLocation:(BOOL)enableHighAccuracy;
+
+- (void)locationManager:(CLLocationManager*)manager
+ didUpdateToLocation:(CLLocation*)newLocation
+ fromLocation:(CLLocation*)oldLocation;
+
+- (void)locationManager:(CLLocationManager*)manager
+ didFailWithError:(NSError*)error;
+
+- (BOOL)isLocationServicesEnabled;
+@end
diff --git a/StoneIsland/plugins/cordova-plugin-geolocation/src/ios/CDVLocation.m b/StoneIsland/plugins/cordova-plugin-geolocation/src/ios/CDVLocation.m
new file mode 100644
index 00000000..8b543c8e
--- /dev/null
+++ b/StoneIsland/plugins/cordova-plugin-geolocation/src/ios/CDVLocation.m
@@ -0,0 +1,366 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ */
+
+#import "CDVLocation.h"
+
+#pragma mark Constants
+
+#define kPGLocationErrorDomain @"kPGLocationErrorDomain"
+#define kPGLocationDesiredAccuracyKey @"desiredAccuracy"
+#define kPGLocationForcePromptKey @"forcePrompt"
+#define kPGLocationDistanceFilterKey @"distanceFilter"
+#define kPGLocationFrequencyKey @"frequency"
+
+#pragma mark -
+#pragma mark Categories
+
+@implementation CDVLocationData
+
+@synthesize locationStatus, locationInfo, locationCallbacks, watchCallbacks;
+- (CDVLocationData*)init
+{
+ self = (CDVLocationData*)[super init];
+ if (self) {
+ self.locationInfo = nil;
+ self.locationCallbacks = nil;
+ self.watchCallbacks = nil;
+ }
+ return self;
+}
+
+@end
+
+#pragma mark -
+#pragma mark CDVLocation
+
+@implementation CDVLocation
+
+@synthesize locationManager, locationData;
+
+- (void)pluginInitialize
+{
+ self.locationManager = [[CLLocationManager alloc] init];
+ self.locationManager.delegate = self; // Tells the location manager to send updates to this object
+ __locationStarted = NO;
+ __highAccuracyEnabled = NO;
+ self.locationData = nil;
+}
+
+- (BOOL)isAuthorized
+{
+ BOOL authorizationStatusClassPropertyAvailable = [CLLocationManager respondsToSelector:@selector(authorizationStatus)]; // iOS 4.2+
+
+ if (authorizationStatusClassPropertyAvailable) {
+ NSUInteger authStatus = [CLLocationManager authorizationStatus];
+#ifdef __IPHONE_8_0
+ if ([self.locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) { //iOS 8.0+
+ return (authStatus == kCLAuthorizationStatusAuthorizedWhenInUse) || (authStatus == kCLAuthorizationStatusAuthorizedAlways) || (authStatus == kCLAuthorizationStatusNotDetermined);
+ }
+#endif
+ return (authStatus == kCLAuthorizationStatusAuthorized) || (authStatus == kCLAuthorizationStatusNotDetermined);
+ }
+
+ // by default, assume YES (for iOS < 4.2)
+ return YES;
+}
+
+- (BOOL)isLocationServicesEnabled
+{
+ BOOL locationServicesEnabledInstancePropertyAvailable = [self.locationManager respondsToSelector:@selector(locationServicesEnabled)]; // iOS 3.x
+ BOOL locationServicesEnabledClassPropertyAvailable = [CLLocationManager respondsToSelector:@selector(locationServicesEnabled)]; // iOS 4.x
+
+ if (locationServicesEnabledClassPropertyAvailable) { // iOS 4.x
+ return [CLLocationManager locationServicesEnabled];
+ } else if (locationServicesEnabledInstancePropertyAvailable) { // iOS 2.x, iOS 3.x
+ return [(id)self.locationManager locationServicesEnabled];
+ } else {
+ return NO;
+ }
+}
+
+- (void)startLocation:(BOOL)enableHighAccuracy
+{
+ if (![self isLocationServicesEnabled]) {
+ [self returnLocationError:PERMISSIONDENIED withMessage:@"Location services are not enabled."];
+ return;
+ }
+ if (![self isAuthorized]) {
+ NSString* message = nil;
+ BOOL authStatusAvailable = [CLLocationManager respondsToSelector:@selector(authorizationStatus)]; // iOS 4.2+
+ if (authStatusAvailable) {
+ NSUInteger code = [CLLocationManager authorizationStatus];
+ if (code == kCLAuthorizationStatusNotDetermined) {
+ // could return POSITION_UNAVAILABLE but need to coordinate with other platforms
+ message = @"User undecided on application's use of location services.";
+ } else if (code == kCLAuthorizationStatusRestricted) {
+ message = @"Application's use of location services is restricted.";
+ }
+ }
+ // PERMISSIONDENIED is only PositionError that makes sense when authorization denied
+ [self returnLocationError:PERMISSIONDENIED withMessage:message];
+
+ return;
+ }
+
+#ifdef __IPHONE_8_0
+ NSUInteger code = [CLLocationManager authorizationStatus];
+ if (code == kCLAuthorizationStatusNotDetermined && ([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)] || [self.locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)])) { //iOS8+
+ __highAccuracyEnabled = enableHighAccuracy;
+ if([[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationAlwaysUsageDescription"]){
+ [self.locationManager requestAlwaysAuthorization];
+ } else if([[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationWhenInUseUsageDescription"]) {
+ [self.locationManager requestWhenInUseAuthorization];
+ } else {
+ NSLog(@"[Warning] No NSLocationAlwaysUsageDescription or NSLocationWhenInUseUsageDescription key is defined in the Info.plist file.");
+ }
+ return;
+ }
+#endif
+
+ // Tell the location manager to start notifying us of location updates. We
+ // first stop, and then start the updating to ensure we get at least one
+ // update, even if our location did not change.
+ [self.locationManager stopUpdatingLocation];
+ [self.locationManager startUpdatingLocation];
+ __locationStarted = YES;
+ if (enableHighAccuracy) {
+ __highAccuracyEnabled = YES;
+ // Set distance filter to 5 for a high accuracy. Setting it to "kCLDistanceFilterNone" could provide a
+ // higher accuracy, but it's also just spamming the callback with useless reports which drain the battery.
+ self.locationManager.distanceFilter = 5;
+ // Set desired accuracy to Best.
+ self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
+ } else {
+ __highAccuracyEnabled = NO;
+ // TODO: Set distance filter to 10 meters? and desired accuracy to nearest ten meters? arbitrary.
+ self.locationManager.distanceFilter = 10;
+ self.locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters;
+ }
+}
+
+- (void)_stopLocation
+{
+ if (__locationStarted) {
+ if (![self isLocationServicesEnabled]) {
+ return;
+ }
+
+ [self.locationManager stopUpdatingLocation];
+ __locationStarted = NO;
+ __highAccuracyEnabled = NO;
+ }
+}
+
+- (void)locationManager:(CLLocationManager*)manager
+ didUpdateToLocation:(CLLocation*)newLocation
+ fromLocation:(CLLocation*)oldLocation
+{
+ CDVLocationData* cData = self.locationData;
+
+ cData.locationInfo = newLocation;
+ if (self.locationData.locationCallbacks.count > 0) {
+ for (NSString* callbackId in self.locationData.locationCallbacks) {
+ [self returnLocationInfo:callbackId andKeepCallback:NO];
+ }
+
+ [self.locationData.locationCallbacks removeAllObjects];
+ }
+ if (self.locationData.watchCallbacks.count > 0) {
+ for (NSString* timerId in self.locationData.watchCallbacks) {
+ [self returnLocationInfo:[self.locationData.watchCallbacks objectForKey:timerId] andKeepCallback:YES];
+ }
+ } else {
+ // No callbacks waiting on us anymore, turn off listening.
+ [self _stopLocation];
+ }
+}
+
+- (void)getLocation:(CDVInvokedUrlCommand*)command
+{
+ NSString* callbackId = command.callbackId;
+ BOOL enableHighAccuracy = [[command argumentAtIndex:0] boolValue];
+
+ if ([self isLocationServicesEnabled] == NO) {
+ NSMutableDictionary* posError = [NSMutableDictionary dictionaryWithCapacity:2];
+ [posError setObject:[NSNumber numberWithInt:PERMISSIONDENIED] forKey:@"code"];
+ [posError setObject:@"Location services are disabled." forKey:@"message"];
+ CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:posError];
+ [self.commandDelegate sendPluginResult:result callbackId:callbackId];
+ } else {
+ if (!self.locationData) {
+ self.locationData = [[CDVLocationData alloc] init];
+ }
+ CDVLocationData* lData = self.locationData;
+ if (!lData.locationCallbacks) {
+ lData.locationCallbacks = [NSMutableArray arrayWithCapacity:1];
+ }
+
+ if (!__locationStarted || (__highAccuracyEnabled != enableHighAccuracy)) {
+ // add the callbackId into the array so we can call back when get data
+ if (callbackId != nil) {
+ [lData.locationCallbacks addObject:callbackId];
+ }
+ // Tell the location manager to start notifying us of heading updates
+ [self startLocation:enableHighAccuracy];
+ } else {
+ [self returnLocationInfo:callbackId andKeepCallback:NO];
+ }
+ }
+}
+
+- (void)addWatch:(CDVInvokedUrlCommand*)command
+{
+ NSString* callbackId = command.callbackId;
+ NSString* timerId = [command argumentAtIndex:0];
+ BOOL enableHighAccuracy = [[command argumentAtIndex:1] boolValue];
+
+ if (!self.locationData) {
+ self.locationData = [[CDVLocationData alloc] init];
+ }
+ CDVLocationData* lData = self.locationData;
+
+ if (!lData.watchCallbacks) {
+ lData.watchCallbacks = [NSMutableDictionary dictionaryWithCapacity:1];
+ }
+
+ // add the callbackId into the dictionary so we can call back whenever get data
+ [lData.watchCallbacks setObject:callbackId forKey:timerId];
+
+ if ([self isLocationServicesEnabled] == NO) {
+ NSMutableDictionary* posError = [NSMutableDictionary dictionaryWithCapacity:2];
+ [posError setObject:[NSNumber numberWithInt:PERMISSIONDENIED] forKey:@"code"];
+ [posError setObject:@"Location services are disabled." forKey:@"message"];
+ CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:posError];
+ [self.commandDelegate sendPluginResult:result callbackId:callbackId];
+ } else {
+ if (!__locationStarted || (__highAccuracyEnabled != enableHighAccuracy)) {
+ // Tell the location manager to start notifying us of location updates
+ [self startLocation:enableHighAccuracy];
+ }
+ }
+}
+
+- (void)clearWatch:(CDVInvokedUrlCommand*)command
+{
+ NSString* timerId = [command argumentAtIndex:0];
+
+ if (self.locationData && self.locationData.watchCallbacks && [self.locationData.watchCallbacks objectForKey:timerId]) {
+ [self.locationData.watchCallbacks removeObjectForKey:timerId];
+ if([self.locationData.watchCallbacks count] == 0) {
+ [self _stopLocation];
+ }
+ }
+}
+
+- (void)stopLocation:(CDVInvokedUrlCommand*)command
+{
+ [self _stopLocation];
+}
+
+- (void)returnLocationInfo:(NSString*)callbackId andKeepCallback:(BOOL)keepCallback
+{
+ CDVPluginResult* result = nil;
+ CDVLocationData* lData = self.locationData;
+
+ if (lData && !lData.locationInfo) {
+ // return error
+ result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageToErrorObject:POSITIONUNAVAILABLE];
+ } else if (lData && lData.locationInfo) {
+ CLLocation* lInfo = lData.locationInfo;
+ NSMutableDictionary* returnInfo = [NSMutableDictionary dictionaryWithCapacity:8];
+ NSNumber* timestamp = [NSNumber numberWithDouble:([lInfo.timestamp timeIntervalSince1970] * 1000)];
+ [returnInfo setObject:timestamp forKey:@"timestamp"];
+ [returnInfo setObject:[NSNumber numberWithDouble:lInfo.speed] forKey:@"velocity"];
+ [returnInfo setObject:[NSNumber numberWithDouble:lInfo.verticalAccuracy] forKey:@"altitudeAccuracy"];
+ [returnInfo setObject:[NSNumber numberWithDouble:lInfo.horizontalAccuracy] forKey:@"accuracy"];
+ [returnInfo setObject:[NSNumber numberWithDouble:lInfo.course] forKey:@"heading"];
+ [returnInfo setObject:[NSNumber numberWithDouble:lInfo.altitude] forKey:@"altitude"];
+ [returnInfo setObject:[NSNumber numberWithDouble:lInfo.coordinate.latitude] forKey:@"latitude"];
+ [returnInfo setObject:[NSNumber numberWithDouble:lInfo.coordinate.longitude] forKey:@"longitude"];
+
+ result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:returnInfo];
+ [result setKeepCallbackAsBool:keepCallback];
+ }
+ if (result) {
+ [self.commandDelegate sendPluginResult:result callbackId:callbackId];
+ }
+}
+
+- (void)returnLocationError:(NSUInteger)errorCode withMessage:(NSString*)message
+{
+ NSMutableDictionary* posError = [NSMutableDictionary dictionaryWithCapacity:2];
+
+ [posError setObject:[NSNumber numberWithUnsignedInteger:errorCode] forKey:@"code"];
+ [posError setObject:message ? message:@"" forKey:@"message"];
+ CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:posError];
+
+ for (NSString* callbackId in self.locationData.locationCallbacks) {
+ [self.commandDelegate sendPluginResult:result callbackId:callbackId];
+ }
+
+ [self.locationData.locationCallbacks removeAllObjects];
+
+ for (NSString* callbackId in self.locationData.watchCallbacks) {
+ [self.commandDelegate sendPluginResult:result callbackId:callbackId];
+ }
+}
+
+- (void)locationManager:(CLLocationManager*)manager didFailWithError:(NSError*)error
+{
+ NSLog(@"locationManager::didFailWithError %@", [error localizedFailureReason]);
+
+ CDVLocationData* lData = self.locationData;
+ if (lData && __locationStarted) {
+ // TODO: probably have to once over the various error codes and return one of:
+ // PositionError.PERMISSION_DENIED = 1;
+ // PositionError.POSITION_UNAVAILABLE = 2;
+ // PositionError.TIMEOUT = 3;
+ NSUInteger positionError = POSITIONUNAVAILABLE;
+ if (error.code == kCLErrorDenied) {
+ positionError = PERMISSIONDENIED;
+ }
+ [self returnLocationError:positionError withMessage:[error localizedDescription]];
+ }
+
+ if (error.code != kCLErrorLocationUnknown) {
+ [self.locationManager stopUpdatingLocation];
+ __locationStarted = NO;
+ }
+}
+
+//iOS8+
+-(void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
+{
+ if(!__locationStarted){
+ [self startLocation:__highAccuracyEnabled];
+ }
+}
+
+- (void)dealloc
+{
+ self.locationManager.delegate = nil;
+}
+
+- (void)onReset
+{
+ [self _stopLocation];
+ [self.locationManager stopUpdatingHeading];
+}
+
+@end
diff --git a/StoneIsland/plugins/cordova-plugin-geolocation/src/ubuntu/geolocation.cpp b/StoneIsland/plugins/cordova-plugin-geolocation/src/ubuntu/geolocation.cpp
new file mode 100644
index 00000000..c820cfef
--- /dev/null
+++ b/StoneIsland/plugins/cordova-plugin-geolocation/src/ubuntu/geolocation.cpp
@@ -0,0 +1,119 @@
+/*
+ *
+ * Copyright 2013 Canonical Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+
+#include <QUuid>
+
+#include "geolocation.h"
+
+Geolocation::Geolocation(Cordova *cordova): CPlugin(cordova),
+ _geoPositionInfoSource(QGeoPositionInfoSource::createDefaultSource(this)) {
+ if (_geoPositionInfoSource.data() != 0) {
+ QObject::connect(_geoPositionInfoSource.data(), SIGNAL(positionUpdated(QGeoPositionInfo)), this, SLOT(positionUpdated(QGeoPositionInfo)));
+ QObject::connect(_geoPositionInfoSource.data(), SIGNAL(updateTimeout()), this, SLOT(updateTimeout()));
+ }
+}
+
+void Geolocation::addWatch(int scId, int ecId, const QString &id, bool enableHighAccuracy) {
+ Q_UNUSED(enableHighAccuracy);
+
+ assert(_id2sc.find(id) == _id2sc.end());
+
+ if (!_geoPositionInfoSource.data()) {
+ QVariantMap err;
+ err.insert("code", POSITION_UNAVAILABLE);
+ err.insert("message", "unavailable");
+
+ this->cb(ecId, err);
+ return;
+ }
+
+ _id2sc[id] = scId;
+ _id2ec[id] = ecId;
+}
+
+void Geolocation::clearWatch(int scId, int ecId, const QString &id) {
+ _id2sc.remove(id);
+ _id2ec.remove(id);
+}
+
+void Geolocation::getLocation(int scId, int ecId, bool enableHighAccuracy, qint64 maximumAge) {
+ Q_UNUSED(maximumAge);
+ Q_UNUSED(enableHighAccuracy);
+
+ if (!_geoPositionInfoSource.data()) {
+ QVariantMap err;
+ err.insert("code", POSITION_UNAVAILABLE);
+ err.insert("message", "unavailable");
+
+ this->cb(ecId, err);
+ return;
+ }
+
+ _geoPositionInfoSource->requestUpdate();
+
+ QString id = QString("_INTERNAL_") + QUuid::createUuid().toString();
+
+ _id2sc[id] = scId;
+ _id2ec[id] = ecId;
+ _singleUpdate.insert(id);
+}
+
+void Geolocation::positionUpdated(const QGeoPositionInfo &update) {
+ QGeoCoordinate coordinate = update.coordinate();
+
+ QVariantMap p;
+
+ p.insert("latitude", coordinate.latitude());
+ p.insert("longitude", coordinate.longitude());
+ p.insert("altitude", coordinate.altitude());
+
+ if (update.hasAttribute(QGeoPositionInfo::VerticalAccuracy))
+ p.insert("accuracy", update.attribute(QGeoPositionInfo::VerticalAccuracy));
+ if (update.hasAttribute(QGeoPositionInfo::Direction))
+ p.insert("heading", update.attribute(QGeoPositionInfo::Direction));
+ if (update.hasAttribute(QGeoPositionInfo::GroundSpeed))
+ p.insert("velocity", update.attribute(QGeoPositionInfo::GroundSpeed));
+ if (update.hasAttribute(QGeoPositionInfo::HorizontalAccuracy))
+ p.insert("altitudeAccuracy", update.attribute(QGeoPositionInfo::HorizontalAccuracy));
+ p.insert("timestamp", update.timestamp().toMSecsSinceEpoch());
+
+ for (const QString &id: _id2sc.keys()) {
+ int scId = _id2sc[id];
+ this->cb(scId, p);
+ if (_singleUpdate.contains(id)) {
+ _singleUpdate.remove(id);
+ _id2sc.remove(id);
+ _id2ec.remove(id);
+ }
+ }
+}
+
+void Geolocation::updateTimeout() {
+ QVariantMap err;
+ err.insert("code", TIMEOUT);
+ err.insert("message", "timeout");
+
+ for (int ecId: _id2ec) {
+ this->cb(ecId, err);
+ }
+
+ _id2ec.clear();
+ _id2sc.clear();
+ _singleUpdate.clear();
+}
diff --git a/StoneIsland/plugins/cordova-plugin-geolocation/src/ubuntu/geolocation.h b/StoneIsland/plugins/cordova-plugin-geolocation/src/ubuntu/geolocation.h
new file mode 100644
index 00000000..7345bec9
--- /dev/null
+++ b/StoneIsland/plugins/cordova-plugin-geolocation/src/ubuntu/geolocation.h
@@ -0,0 +1,69 @@
+/*
+ *
+ * Copyright 2013 Canonical Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+
+#ifndef GEOLOCATION_H_SVO2013
+#define GEOLOCATION_H_SVO2013
+
+#include <QGeoPositionInfoSource>
+#include <QGeoPositionInfo>
+#include <QtCore>
+#include <cassert>
+
+#include <cplugin.h>
+
+class Geolocation: public CPlugin {
+ Q_OBJECT
+public:
+ explicit Geolocation(Cordova *cordova);
+
+ virtual const QString fullName() override {
+ return Geolocation::fullID();
+ }
+
+ virtual const QString shortName() override {
+ return "Geolocation";
+ }
+
+ static const QString fullID() {
+ return "Geolocation";
+ }
+
+public slots:
+ void getLocation(int scId, int ecId, bool enableHighAccuracy, qint64 maximumAge);
+ void addWatch(int scId, int ecId, const QString &id, bool enableHighAccuracy);
+ void clearWatch(int scId, int ecId, const QString &id);
+
+protected slots:
+ void positionUpdated(const QGeoPositionInfo &update);
+ void updateTimeout();
+
+private:
+ QMap<QString, int> _id2sc;
+ QMap<QString, int> _id2ec;
+ QSet<QString> _singleUpdate;
+ QSharedPointer<QGeoPositionInfoSource> _geoPositionInfoSource;
+
+ enum PositionError {
+ PERMISSION_DENIED = 1,
+ POSITION_UNAVAILABLE = 2,
+ TIMEOUT = 3
+ };
+};
+
+#endif
diff --git a/StoneIsland/plugins/cordova-plugin-geolocation/src/windows/GeolocationProxy.js b/StoneIsland/plugins/cordova-plugin-geolocation/src/windows/GeolocationProxy.js
new file mode 100644
index 00000000..9cab6a4d
--- /dev/null
+++ b/StoneIsland/plugins/cordova-plugin-geolocation/src/windows/GeolocationProxy.js
@@ -0,0 +1,174 @@
+/*
+ * Copyright 2013 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var PositionError = require('./PositionError'),
+ ids = {},
+ loc;
+
+function ensureLocator() {
+ if (loc == null)
+ loc = new Windows.Devices.Geolocation.Geolocator();
+
+ return loc;
+}
+
+function createErrorCode() {
+ switch (loc.locationStatus) {
+ case Windows.Devices.Geolocation.PositionStatus.initializing:
+ // This status indicates that a location device is still initializing
+ case Windows.Devices.Geolocation.PositionStatus.noData:
+ // No location data is currently available
+ case Windows.Devices.Geolocation.PositionStatus.notInitialized:
+ // This status indicates that the app has not yet requested
+ // location data by calling GetGeolocationAsync() or
+ // registering an event handler for the positionChanged event.
+ case Windows.Devices.Geolocation.PositionStatus.notAvailable:
+ // Location is not available on this version of Windows
+ return PositionError.POSITION_UNAVAILABLE;
+
+ case Windows.Devices.Geolocation.PositionStatus.disabled:
+ // The app doesn't have permission to access location,
+ // either because location has been turned off.
+ return PositionError.PERMISSION_DENIED;
+
+ default:
+ break;
+ }
+}
+function createResult(pos) {
+ var res = {
+ accuracy: pos.coordinate.accuracy,
+ heading: pos.coordinate.heading,
+ velocity: pos.coordinate.speed,
+ altitudeAccuracy: pos.coordinate.altitudeAccuracy,
+ timestamp: pos.coordinate.timestamp
+ }
+
+ if (pos.coordinate.point) {
+ res.latitude = pos.coordinate.point.position.latitude;
+ res.longitude = pos.coordinate.point.position.longitude;
+ res.altitude = pos.coordinate.point.position.altitude;
+ } else { // compatibility with old windows8.0 api
+ res.latitude = pos.coordinate.latitude;
+ res.longitude = pos.coordinate.longitude;
+ res.altitude = pos.coordinate.altitude;
+ }
+
+ return res;
+}
+
+module.exports = {
+ getLocation: function (success, fail, args, env) {
+ ensureLocator();
+ if (loc != null)
+ {
+ var highAccuracy = args[0],
+ maxAge = args[1];
+
+ loc.desiredAccuracy = highAccuracy ?
+ Windows.Devices.Geolocation.PositionAccuracy.high :
+ Windows.Devices.Geolocation.PositionAccuracy.default;
+
+ loc.reportInterval = maxAge ? maxAge : 0;
+
+ loc.getGeopositionAsync().then(
+ function (pos) {
+ success(createResult(pos));
+ },
+ function (err) {
+ fail({
+ code: createErrorCode(),
+ message: err.message
+ });
+ }
+ );
+ }
+ else
+ {
+ fail({
+ code: PositionError.POSITION_UNAVAILABLE,
+ message: "You do not have the required location services present on your system."
+ });
+ }
+ },
+
+ addWatch: function (success, fail, args, env) {
+ ensureLocator();
+ var clientId = args[0],
+ highAccuracy = args[1],
+
+ onPositionChanged = function (e) {
+ success(createResult(e.position), {keepCallback: true});
+ },
+
+ onStatusChanged = function (e) {
+ switch (e.status) {
+ case Windows.Devices.Geolocation.PositionStatus.noData:
+ case Windows.Devices.Geolocation.PositionStatus.notAvailable:
+ fail({
+ code: PositionError.POSITION_UNAVAILABLE,
+ message: "Data from location services is currently unavailable or you do not have the required location services present on your system."
+ });
+ break;
+
+ case Windows.Devices.Geolocation.PositionStatus.disabled:
+ fail({
+ code: PositionError.PERMISSION_DENIED,
+ message: "Your location is currently turned off."
+ });
+ break;
+
+ case Windows.Devices.Geolocation.PositionStatus.initializing:
+ case Windows.Devices.Geolocation.PositionStatus.ready:
+ default:
+ break;
+ }
+ };
+
+ loc.desiredAccuracy = highAccuracy ?
+ Windows.Devices.Geolocation.PositionAccuracy.high :
+ Windows.Devices.Geolocation.PositionAccuracy.default;
+
+ if (cordova.platformId == 'windows' && WinJS.Utilities.isPhone) {
+ // on Windows Phone 8.1 'positionchanged' event fails with error below if movementThreshold is not set
+ // JavaScript runtime error: Operation aborted
+ // You must set the MovementThreshold property or the ReportInterval property before adding event handlers.
+ // WinRT information: You must set the MovementThreshold property or the ReportInterval property before adding event handlers
+ loc.movementThreshold = loc.movementThreshold || 1; // 1 meter
+ }
+
+ loc.addEventListener("positionchanged", onPositionChanged);
+ loc.addEventListener("statuschanged", onStatusChanged);
+
+ ids[clientId] = { pos: onPositionChanged, status: onStatusChanged };
+ },
+
+ clearWatch: function (success, fail, args, env) {
+ var clientId = args[0],
+ callbacks = ids[clientId];
+
+ if (callbacks) {
+ loc.removeEventListener("positionchanged", callbacks.pos);
+ loc.removeEventListener("statuschanged", callbacks.status);
+
+ delete ids[clientId];
+ }
+
+ success && success();
+ }
+};
+
+require("cordova/exec/proxy").add("Geolocation", module.exports); \ No newline at end of file
diff --git a/StoneIsland/plugins/cordova-plugin-geolocation/src/wp/GeoLocation.cs b/StoneIsland/plugins/cordova-plugin-geolocation/src/wp/GeoLocation.cs
new file mode 100644
index 00000000..42af72de
--- /dev/null
+++ b/StoneIsland/plugins/cordova-plugin-geolocation/src/wp/GeoLocation.cs
@@ -0,0 +1,34 @@
+/*
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+using System.Threading;
+using System.Device.Location;
+
+namespace WPCordovaClassLib.Cordova.Commands
+{
+ /// <summary>
+ /// This is a command stub, the browser provides the correct implementation. We use this to trigger the static analyzer that we require this permission
+ /// </summary>
+ public class Geolocation
+ {
+ /* Unreachable code, by design -jm */
+ private void triggerGeoInclusion()
+ {
+ new GeoCoordinateWatcher();
+ }
+ }
+}