The Locations sub-tab is found under the Peripherals tab for supported devices. This tab will allow you to set the Latitude, Longitude, Altitude and Time Offset using the provided entry boxes. You can also navigate to a latitude/longitude of your choice by moving the map to the location of interest.

On iOS

Note that location data is provided only to UI applications as a user-mode implementation of CLLocationManager. Only raw location events are supported. Activity filtering, region monitoring, beacons, and visit events are not currently supported.

Location Services on newly created iOS devices are disabled by default. You may need to go into the Settings application and enable Location Services if your application does not request them to be enabled.

On Android

Note that these values are provided to the Android system as a GPS hardware change. This means you can read them utilizing the direct permissions android.permission.ACCESS_FINE_LOCATION and android.permission.ACCESS_COARSE_LOCATION.

Directly using location data

Ensure that the application your are trying to test has direct access to the GPS by requesting the correct permissions you would like, either android.permission.ACCESS_FINE_LOCATION or android.permission.ACCESS_COARSE_LOCATION.

A good Android application to test the changes for this is SatSat, which is open sourced and can be found on F-droid or the github page for the source code. You can also reference a JavaScript example for requesting and accepting the GPS data inside a WebKit component can be tested here and find source on the github page.

Using a FusedLocationProvider

The Google FusedLocationProvider API enables functionality such as "Current Location." Without the FusedLocationProvider enabled, features such as centering on your current location in maps apps will not behave as expected.

In order to use the FusedLocationProvider, you will first need to install OpenGapps, which will install Google Play Services. Once that's installed, you will also need to install Google Maps, either via the Google Play Store or by side-loading. Next, you will need to run Google Maps at least once to activate the feature.

Google Services handles the FusedLocationProvider API interaction. When an application is subscribed to get location updates, Google Services relies on its own services to continually receive periodic locations to update the FusedLocation. This is why you must install and run Google Maps at least once to activate this feature.

Setting Sensors

When a VM supporting GPS, battery, or other sensor input is started, the boot response will contain a env: element. This element is a nshostport (i.e. a TCP port with optional namespace/ and host: specification). When connected to the TCP port, an application can send a sensor update consisting of following lineio elements:





integer, default 0

select container ID (1..16) to update


float, in seconds

GPS time offset from system time


scalar, in degrees north

geographic latitude


scalar, in degrees east

geographic longitude


scalar, in meters above MSL



integer, 0 or 1

AC adapter connected


integer, 0 or 1

battery inserted


charging, discharging, not-charging

battery charger status


good, overheat, dead, overvolt, failure

battery health


scalar, in percent

current battery state of charge


vector, in m/s^2

accelerometer data


vector, in rad/s

gyroscope data


vector, in uT

magnetometer data


vector, in degrees

orientation (azimuth, pitch, roll)


scalar, in degrees Celsius

temperature sensor data


scalar, in cm

face proximity sensor data


scalar, in lux

ambient light sensor data


scalar, in hPa

barometer data


scalar, in percent

hygrometer data

All elements are optional. If no default is specified, the element will retain previous value if not supplied.

Elements described as scalar can be supplied in one of three forms:


constant value as supplied


value will change by delta every second


value will change by delta every second, until the total delta is exhausted

Similarly, elements described as vector can be supplied in those three forms, but each of the value, delta and totaldelta parts must be a vector of 3 numbers x,y,z.

The “boot result” is found in the c3po logs and will appear with the env variable like the following:

Sep 09 13:18:29 vtest1-2 c3po[4193]: 768f03c4-8dcd-4db9-9565-33edc06f9f64: boot result: { Sep 09 13:18:29 vtest1-2 c3po[4193]: vmid: '0', Sep 09 13:18:29 vtest1-2 c3po[4193]: cons: [ '', '' ], Sep 09 13:18:29 vtest1-2 c3po[4193]: adb: '', Sep 09 13:18:29 vtest1-2 c3po[4193]: vstrm: '', Sep 09 13:18:29 vtest1-2 c3po[4193]: 'vstrm-metrics': '720,1280,2,368,640', Sep 09 13:18:29 vtest1-2 c3po[4193]: env: '45247', Sep 09 13:18:29 vtest1-2 c3po[4193]: strace: '5300', Sep 09 13:18:29 vtest1-2 c3po[4193]: gdb: '', Sep 09 13:18:29 vtest1-2 c3po[4193]: xalloc: '44513' Sep 09 13:18:29 vtest1-2 c3po[4193]: }

Alternative path to env

It is also possible to send environmental sensor commands directly as charmd commands. This is done by using the env command (which requires either vmid: or name: to target the VM). The sensor values should be passed on the same line.

The charmd path also permits retrieving sensor values. Use env vmid: get: to retrieve instantaneous values for all sensors (this also acts as a directory of sensors).

Did this answer your question?