Skip to content

Commit

Permalink
Add possibility to control Android sensor states from native code.
Browse files Browse the repository at this point in the history
  • Loading branch information
ndob committed May 1, 2016
1 parent 67fe635 commit 0f5fcc8
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 15 deletions.
59 changes: 48 additions & 11 deletions platform/android/yarrar/src/main/java/com/ndob/yarrar/Sensors.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,41 +7,78 @@
import android.hardware.SensorManager;
import android.util.Log;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class Sensors implements SensorEventListener
{
private YarrarActivity mParent;
private SensorManager mSensorManager;
private int mAccuracy;
private boolean mUpdating;
private Set<Integer> mActiveSensors;

public Sensors(YarrarActivity parent) {
mParent = parent;
mSensorManager = (SensorManager) parent.getSystemService(Context.SENSOR_SERVICE);
mAccuracy = Integer.MAX_VALUE;
mUpdating = false;
mActiveSensors = new HashSet<Integer>();
}

public boolean setSensorState(int sensorType, boolean active) {
List<Sensor> available = mSensorManager.getSensorList(Sensor.TYPE_ALL);

boolean found = false;
for(Sensor s : available) {
if(s.getType() == sensorType) {
found = true;
break;
}
}

if(!found) {
return false;
}

if(active) {
mActiveSensors.add(sensorType);
}
else {
mActiveSensors.remove(sensorType);
}

refreshListeners();

return true;
}

public void setUpdating(boolean shouldUpdate) {
if (!mUpdating && shouldUpdate) {
mUpdating = true;
// TYPE_ROTATION_VECTOR is a virtual fused sensor.
// It uses acc-, gyro- and mag-sensors, if available.
mSensorManager.registerListener(
this,
mSensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR),
SensorManager.SENSOR_DELAY_UI);

mSensorManager.registerListener(
this,
mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE),
SensorManager.SENSOR_DELAY_UI);
refreshListeners();
}
else if(mUpdating && !shouldUpdate) {
mUpdating = false;
mSensorManager.unregisterListener(this);
}
}

private void refreshListeners() {
if(mActiveSensors.isEmpty()) {
mSensorManager.unregisterListener(this);
}
else {
for(int sensorType : mActiveSensors) {
mSensorManager.registerListener(
this,
mSensorManager.getDefaultSensor(sensorType),
SensorManager.SENSOR_DELAY_UI);
}
}
}

@Override
public void onSensorChanged(SensorEvent event) {
if(event.sensor.getType() == Sensor.TYPE_ROTATION_VECTOR) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,12 @@ public void onOpenGLSurfaceCreated() {
Log.i(TAG, "Yarrar successfully loaded.");
}

public boolean native_setSensorState(int sensorType, boolean active) {
boolean result = mSensors.setSensorState(sensorType, active);
Log.i(TAG, "Set sensor state: " + sensorType + ":" + result);
return result;
}

public void onOpenGLDrawFrame() {
run();
}
Expand Down
18 changes: 17 additions & 1 deletion src/android/AndroidServices.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ namespace
{

JNIEnv* s_env = nullptr;
jobject s_yarrarActivity = nullptr;
AAssetManager* s_assetManager = nullptr;
}

Expand All @@ -14,9 +15,10 @@ namespace yarrar
namespace android
{

bool initialize(JNIEnv* env, jobject assetManager)
bool initialize(JNIEnv* env, jobject yarrarActivity, jobject assetManager)
{
s_env = env;
s_yarrarActivity = yarrarActivity;
s_assetManager = AAssetManager_fromJava(env, assetManager);
return s_env != nullptr && s_assetManager != nullptr;
}
Expand All @@ -26,6 +28,20 @@ AAssetManager* getAssetManager()
return s_assetManager;
}

bool setSensorState(SensorType type, bool active)
{
jclass clazz = s_env->GetObjectClass(s_yarrarActivity);
jmethodID methodId = s_env->GetMethodID(clazz, "native_setSensorState", "(IZ)Z");
if(methodId == 0)
{
log("Could not find activateSensor-method through JNI.");
return false;
}

jboolean ret = s_env->CallBooleanMethod(s_yarrarActivity, methodId, static_cast<int>(type), active);
return static_cast<bool>(ret);
}

void log(const std::string& message)
{
__android_log_print(ANDROID_LOG_VERBOSE, "YARRAR", message.c_str());
Expand Down
12 changes: 11 additions & 1 deletion src/android/AndroidServices.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,18 @@ namespace yarrar
namespace android
{

bool initialize(JNIEnv* env, jobject assetManager);
// Android sensor constants
// See: http://developer.android.com/reference/android/hardware/Sensor.html
enum SensorType
{
TYPE_ROTATION_VECTOR = 0x0000000b,
TYPE_GYROSCOPE = 0x00000004
};


bool initialize(JNIEnv* env, jobject yarrarActivity, jobject assetManager);
AAssetManager* getAssetManager();
bool setSensorState(SensorType type, bool active);
void log(const std::string& message);
}
}
4 changes: 2 additions & 2 deletions src/android/YarrarGlue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ yarrar::Pipeline* s_pipe;

extern "C" {

void Java_com_ndob_yarrar_YarrarActivity_initYarrar(JNIEnv* env, jobject, jint width, jint height, jobject assetManager)
void Java_com_ndob_yarrar_YarrarActivity_initYarrar(JNIEnv* env, jobject yarrarActivity, jint width, jint height, jobject assetManager)
{
try
{
yarrar::android::initialize(env, assetManager);
yarrar::android::initialize(env, yarrarActivity, assetManager);
yarrar::AndroidCameraProvider::injectCameraSize(static_cast<int>(width), static_cast<int>(height));
s_pipe = new yarrar::Pipeline("pipeline.json");
}
Expand Down

0 comments on commit 0f5fcc8

Please sign in to comment.