implement LocationManager and orientation sensor using libportal

This commit is contained in:
Julian Winkler
2023-07-14 20:02:34 +02:00
parent c72f3ba7d2
commit 696e0ce714
13 changed files with 167 additions and 3 deletions

View File

@@ -82,11 +82,12 @@ libtranslationlayer_so = shared_library('translation_layer_main', [
'src/api-impl-jni/android_graphics_Bitmap.c',
'src/api-impl-jni/android_app_NativeActivity.c',
'src/api-impl-jni/android_opengl_GLES20.c',
'src/api-impl-jni/location/android_location_LocationManager.c',
] + marshal_files,
install: true,
install_dir : get_option('libdir') / 'java/dex/android_translation_layer/natives',
dependencies: [
dependency('gtk4'), dependency('gl'), dependency('egl'), dependency('wayland-client'), dependency('jni')
dependency('gtk4'), dependency('gl'), dependency('egl'), dependency('wayland-client'), dependency('jni'), dependency('libportal')
],
link_with: [ libandroid_so ],
link_args: [

View File

@@ -0,0 +1,21 @@
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class android_location_LocationManager */
#ifndef _Included_android_location_LocationManager
#define _Included_android_location_LocationManager
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: android_location_LocationManager
* Method: nativeGetLocation
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_android_location_LocationManager_nativeGetLocation
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,35 @@
#include <libportal/portal.h>
#include "../defines.h"
#include "../generated_headers/android_location_LocationManager.h"
static void location_updated (
XdpPortal* self,
gdouble latitude,
gdouble longitude,
gdouble altitude,
gdouble accuracy,
gdouble speed,
gdouble heading,
gchar* description,
gint64 timestamp_s,
gint64 timestamp_ms,
JavaVM *jvm
) {
JNIEnv *env;
(*jvm)->GetEnv(jvm, (void**)&env, JNI_VERSION_1_6);
jclass class = (*env)->FindClass(env, "android/location/LocationManager");
(*env)->CallStaticVoidMethod(env, class, _STATIC_METHOD(class, "locationUpdated", "(DDD)V"), latitude, longitude, heading);
}
static XdpPortal *portal = NULL;
JNIEXPORT void JNICALL Java_android_location_LocationManager_nativeGetLocation(JNIEnv *env, jobject) {
if (!portal) {
portal = xdp_portal_new();
JavaVM *jvm;
(*env)->GetJavaVM(env, &jvm);
g_signal_connect(portal, "location-updated", G_CALLBACK(location_updated), jvm);
}
xdp_portal_location_monitor_start (portal, NULL, 0, 0, XDP_LOCATION_ACCURACY_EXACT, XDP_LOCATION_MONITOR_FLAG_NONE, NULL, NULL, NULL);
}

View File

@@ -20,6 +20,7 @@ import android.hardware.input.InputManager;
import android.hardware.SensorManager;
import android.hardware.display.DisplayManager;
import android.hardware.usb.UsbManager;
import android.location.LocationManager;
import android.media.AudioManager;
import android.media.MediaRouter;
import android.net.ConnectivityManager;
@@ -131,6 +132,8 @@ public class Context extends Object {
return new AlarmManager();
case "input":
return new InputManager();
case "location":
return new LocationManager();
default:
System.out.println("!!!!!!! getSystemService: case >" + name + "< is not implemented yet");
return null;

View File

@@ -327,7 +327,8 @@ public final class Sensor {
private int mFifoReservedEventCount;
private int mFifoMaxEventCount;
Sensor() {
Sensor(int type) {
mType = type;
}
/**

View File

@@ -0,0 +1,11 @@
package android.hardware;
public class SensorEvent {
public final float[] values;
public SensorEvent(float[] values) {
this.values = values;
}
}

View File

@@ -1,4 +1,6 @@
package android.hardware;
public interface SensorEventListener {
public void onSensorChanged(SensorEvent event);
}

View File

@@ -1,13 +1,31 @@
package android.hardware;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Handler;
public class SensorManager {
public Sensor getDefaultSensor(int type) {
return null;
return new Sensor(type);
}
public boolean registerListener(SensorEventListener listener, Sensor sensor, int samplingPeriodUs, Handler handler) {
return true; // we could try saying that the sensor doesn't exist and hope the app just doesn't use it then, but as long as we never call the handler the app should leave this alone
}
public boolean registerListener(final SensorEventListener listener, Sensor sensor, int samplingPeriodUs) {
switch(sensor.getType()) {
case Sensor.TYPE_ORIENTATION:
new LocationManager().requestLocationUpdates(null, 0, 0, new LocationListener() {
@Override
public void onLocationChanged(Location location) {
listener.onSensorChanged(new SensorEvent(new float[]{(float)location.getBearing()}));
}
});
return true;
default:
return false;
}
}
}

View File

@@ -12,4 +12,12 @@ public class Criteria {
public static final int ACCURACY_HIGH = 3;
public void setAccuracy(int accuracy) {}
public void setAltitudeRequired(boolean required) {}
public void setBearingRequired(boolean required) {}
public void setCostAllowed(boolean allowed) {}
public void setPowerRequirement(int powerRequirement) {}
}

View File

@@ -0,0 +1,27 @@
package android.location;
public class Location {
private double latitude;
private double longitude;
private double bearing;
public Location (double latitude, double longitude, double bearing) {
this.latitude = latitude;
this.longitude = longitude;
this.bearing = bearing;
}
public double getLatitude() {
return latitude;
}
public double getLongitude() {
return longitude;
}
public double getBearing() {
return bearing;
}
}

View File

@@ -1,4 +1,7 @@
package android.location;
public interface LocationListener {
public void onLocationChanged(Location location);
}

View File

@@ -0,0 +1,31 @@
package android.location;
import java.util.HashSet;
import java.util.Set;
public class LocationManager {
static Set<LocationListener> listeners = new HashSet<>();
public String getBestProvider(Criteria criteria, boolean enabledOnly) {
return "xdgportal";
}
public Location getLastKnownLocation(String provider) {
return null;
}
public void requestLocationUpdates (String provider, long minTimeMs, float minDistanceM, LocationListener listener) {
listeners.add(listener);
nativeGetLocation();
}
private native void nativeGetLocation();
private static void locationUpdated(double latitude, double longitude, double heading) {
for (LocationListener locationListener : listeners) {
locationListener.onLocationChanged(new Location(latitude, longitude, heading));
}
}
}

View File

@@ -98,12 +98,15 @@ hax_jar = jar('hax', [
'android/graphics/drawable/Drawable.java',
'android/hardware/display/DisplayManager.java',
'android/hardware/input/InputManager.java',
'android/hardware/SensorEvent.java',
'android/hardware/SensorEventListener.java',
'android/hardware/Sensor.java',
'android/hardware/SensorManager.java',
'android/hardware/usb/UsbManager.java',
'android/location/Criteria.java',
'android/location/Location.java',
'android/location/LocationListener.java',
'android/location/LocationManager.java',
'android/Manifest.java',
'android/media/AudioManager.java',
'android/media/AudioTrack.java',