Skip to content

Commit

Permalink
darwin: add location
Browse files Browse the repository at this point in the history
  • Loading branch information
doronz88 committed Feb 17, 2022
1 parent 7ed1cac commit 1f7a66c
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/rpcclient/rpcclient/darwin/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from rpcclient.darwin.consts import kCFNumberSInt64Type, kCFNumberDoubleType
from rpcclient.darwin.fs import DarwinFs
from rpcclient.darwin.ioregistry import IORegistry
from rpcclient.darwin.location import Location
from rpcclient.darwin.media import DarwinMedia
from rpcclient.darwin.network import DarwinNetwork
from rpcclient.darwin.objective_c_symbol import ObjectiveCSymbol
Expand Down Expand Up @@ -58,6 +59,7 @@ def __init__(self, sock, sysname: str, hostname: str, port: int = None):
self.media = DarwinMedia(self)
self.network = DarwinNetwork(self)
self.ioregistry = IORegistry(self)
self.location = Location(self)

@property
def modules(self) -> typing.List[str]:
Expand Down
57 changes: 57 additions & 0 deletions src/rpcclient/rpcclient/darwin/location.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
from enum import Enum
from typing import Mapping

from rpcclient.exceptions import MissingLibraryError, PermissionDeniedError


class CLAuthorizationStatus(Enum):
kCLAuthorizationStatusNotDetermined = 0
kCLAuthorizationStatusRestricted = 1
kCLAuthorizationStatusDenied = 2
kCLAuthorizationStatusAuthorizedAlways = 3
kCLAuthorizationStatusAuthorizedWhenInUse = 4
kCLAuthorizationStatusAuthorized = kCLAuthorizationStatusAuthorizedAlways

@classmethod
def from_value(cls, value: int):
for i in cls:
if i.value == value:
return i


class Location:
"""
Wrapper to CLLocationManager
For details: https://developer.apple.com/documentation/corelocation/cllocationmanager?language=objc
"""

def __init__(self, client):
self._client = client

if not self._client.dlopen('/System/Library/Frameworks/CoreLocation.framework/Versions/A/CoreLocation', 2):
raise MissingLibraryError('failed to load CoreLocation')

self._location_manager = self._client.symbols.objc_getClass('CLLocationManager').objc_call('sharedManager')

@property
def authorization_status(self) -> CLAuthorizationStatus:
return CLAuthorizationStatus.from_value(self._location_manager.objc_call('authorizationStatus'))

@property
def last_sample(self) -> Mapping:
return self._location_manager.objc_call('location').objc_call('jsonObject').py

def start_updating_location(self):
if self.authorization_status.value < CLAuthorizationStatus.kCLAuthorizationStatusAuthorizedAlways.value:
raise PermissionDeniedError()
self._location_manager.objc_call('startUpdatingLocation')

def stop_updating_location(self):
self._location_manager.objc_call('stopUpdatingLocation')

def request_oneshot_location(self):
""" Requests the one-time delivery of the user’s current location. """
if self.authorization_status.value < CLAuthorizationStatus.kCLAuthorizationStatusAuthorizedAlways.value:
raise PermissionDeniedError()
self._location_manager.objc_call('requestLocation')
8 changes: 8 additions & 0 deletions src/rpcclient/rpcclient/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,11 @@ class UnrecognizedSelector(RpcClientException):

class GettingObjectiveCClassError(RpcClientException):
pass


class MissingLibraryError(RpcClientException):
pass


class PermissionDeniedError(RpcClientException):
pass

0 comments on commit 1f7a66c

Please sign in to comment.