diff options
author | Mike Lockwood <lockwood@android.com> | 2009-05-23 10:36:58 -0700 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-05-23 10:36:58 -0700 |
commit | b57d6c9939190f440d3e13adb5fafba6a0cf653d (patch) | |
tree | 83d8e33dfb2a54d19078115e7d76491b09516837 | |
parent | a742dc421bd17117ec802b944190a1c731e05a91 (diff) | |
parent | 270e87f71abc2edf446dbec20c725c823e8c7f37 (diff) | |
download | frameworks_base-b57d6c9939190f440d3e13adb5fafba6a0cf653d.zip frameworks_base-b57d6c9939190f440d3e13adb5fafba6a0cf653d.tar.gz frameworks_base-b57d6c9939190f440d3e13adb5fafba6a0cf653d.tar.bz2 |
am 270e87f7: Sensors: Use a native_handle for the data channel instead of a single file descriptor.
Merge commit '270e87f71abc2edf446dbec20c725c823e8c7f37'
* commit '270e87f71abc2edf446dbec20c725c823e8c7f37':
Sensors: Use a native_handle for the data channel instead of a single file descriptor.
-rw-r--r-- | core/java/android/hardware/ISensorService.aidl | 4 | ||||
-rw-r--r-- | core/java/android/hardware/SensorManager.java | 72 | ||||
-rw-r--r-- | core/jni/android_hardware_SensorManager.cpp | 37 | ||||
-rw-r--r-- | services/java/com/android/server/SensorService.java | 6 | ||||
-rw-r--r-- | services/jni/com_android_server_SensorService.cpp | 77 |
5 files changed, 147 insertions, 49 deletions
diff --git a/core/java/android/hardware/ISensorService.aidl b/core/java/android/hardware/ISensorService.aidl index 04af2ae..67180bd 100644 --- a/core/java/android/hardware/ISensorService.aidl +++ b/core/java/android/hardware/ISensorService.aidl @@ -17,13 +17,13 @@ package android.hardware; -import android.os.ParcelFileDescriptor; +import android.os.Bundle; /** * {@hide} */ interface ISensorService { - ParcelFileDescriptor getDataChanel(); + Bundle getDataChannel(); boolean enableSensor(IBinder listener, String name, int sensor, int enable); } diff --git a/core/java/android/hardware/SensorManager.java b/core/java/android/hardware/SensorManager.java index 67df23b..bf945ec 100644 --- a/core/java/android/hardware/SensorManager.java +++ b/core/java/android/hardware/SensorManager.java @@ -18,7 +18,9 @@ package android.hardware; import android.content.Context; import android.os.Binder; +import android.os.Bundle; import android.os.Looper; +import android.os.Parcelable; import android.os.ParcelFileDescriptor; import android.os.Process; import android.os.RemoteException; @@ -280,8 +282,8 @@ public class SensorManager void startLocked(ISensorService service) { try { if (mThread == null) { - ParcelFileDescriptor fd = service.getDataChanel(); - mThread = new Thread(new SensorThreadRunnable(fd), + Bundle dataChannel = service.getDataChannel(); + mThread = new Thread(new SensorThreadRunnable(dataChannel), SensorThread.class.getName()); mThread.start(); } @@ -291,10 +293,52 @@ public class SensorManager } private class SensorThreadRunnable implements Runnable { - private ParcelFileDescriptor mSensorDataFd; - SensorThreadRunnable(ParcelFileDescriptor fd) { - mSensorDataFd = fd; + private Bundle mDataChannel; + SensorThreadRunnable(Bundle dataChannel) { + mDataChannel = dataChannel; } + + private boolean open() { + if (mDataChannel == null) { + Log.e(TAG, "mDataChannel == NULL, exiting"); + synchronized (sListeners) { + mThread = null; + } + return false; + } + + // this thread is guaranteed to be unique + Parcelable[] pfds = mDataChannel.getParcelableArray("fds"); + FileDescriptor[] fds; + if (pfds != null) { + int length = pfds.length; + fds = new FileDescriptor[length]; + for (int i = 0; i < length; i++) { + ParcelFileDescriptor pfd = (ParcelFileDescriptor)pfds[i]; + fds[i] = pfd.getFileDescriptor(); + } + } else { + fds = null; + } + int[] ints = mDataChannel.getIntArray("ints"); + sensors_data_open(fds, ints); + if (pfds != null) { + try { + // close our copies of the file descriptors, + // since we are just passing these to the JNI code and not using them here. + for (int i = pfds.length - 1; i >= 0; i--) { + ParcelFileDescriptor pfd = (ParcelFileDescriptor)pfds[i]; + pfd.close(); + } + } catch (IOException e) { + // *shrug* + Log.e(TAG, "IOException: ", e); + } + } + mDataChannel = null; + return true; + } + public void run() { //Log.d(TAG, "entering main sensor thread"); final float[] values = new float[3]; @@ -302,23 +346,9 @@ public class SensorManager final long timestamp[] = new long[1]; Process.setThreadPriority(Process.THREAD_PRIORITY_DISPLAY); - if (mSensorDataFd == null) { - Log.e(TAG, "mSensorDataFd == NULL, exiting"); - synchronized (sListeners) { - mThread = null; - } + if (!open()) { return; } - // this thread is guaranteed to be unique - sensors_data_open(mSensorDataFd.getFileDescriptor()); - try { - mSensorDataFd.close(); - } catch (IOException e) { - // *shrug* - Log.e(TAG, "IOException: ", e); - } - mSensorDataFd = null; - while (true) { // wait for an event @@ -1469,7 +1499,7 @@ public class SensorManager // Used within this module from outside SensorManager, don't make private static native int sensors_data_init(); static native int sensors_data_uninit(); - static native int sensors_data_open(FileDescriptor fd); + static native int sensors_data_open(FileDescriptor[] fds, int[] ints); static native int sensors_data_close(); static native int sensors_data_poll(float[] values, int[] status, long[] timestamp); } diff --git a/core/jni/android_hardware_SensorManager.cpp b/core/jni/android_hardware_SensorManager.cpp index 75aa458..3e27978 100644 --- a/core/jni/android_hardware_SensorManager.cpp +++ b/core/jni/android_hardware_SensorManager.cpp @@ -14,9 +14,13 @@ * limitations under the License. */ -#define LOG_TAG "Sensors" +#define LOG_TAG "SensorManager" + +#define LOG_NDEBUG 0 +#include "utils/Log.h" #include <hardware/sensors.h> +#include <cutils/native_handle.h> #include "jni.h" #include "JNIHelp.h" @@ -106,12 +110,33 @@ sensors_data_uninit(JNIEnv *env, jclass clazz) } static jint -sensors_data_open(JNIEnv *env, jclass clazz, jobject fdo) +sensors_data_open(JNIEnv *env, jclass clazz, jobjectArray fdArray, jintArray intArray) { jclass FileDescriptor = env->FindClass("java/io/FileDescriptor"); - jfieldID offset = env->GetFieldID(FileDescriptor, "descriptor", "I"); - int fd = env->GetIntField(fdo, offset); - return sSensorDevice->data_open(sSensorDevice, fd); // doesn't take ownership of fd + jfieldID fieldOffset = env->GetFieldID(FileDescriptor, "descriptor", "I"); + int numFds = (fdArray ? env->GetArrayLength(fdArray) : 0); + int numInts = (intArray ? env->GetArrayLength(intArray) : 0); + native_handle_t* handle = native_handle_create(numFds, numInts); + int offset = 0; + + for (int i = 0; i < numFds; i++) { + jobject fdo = env->GetObjectArrayElement(fdArray, i); + if (fdo) { + handle->data[offset++] = env->GetIntField(fdo, fieldOffset); + } else { + handle->data[offset++] = -1; + } + } + if (numInts > 0) { + jint* ints = env->GetIntArrayElements(intArray, 0); + for (int i = 0; i < numInts; i++) { + handle->data[offset++] = ints[i]; + } + env->ReleaseIntArrayElements(intArray, ints, 0); + } + + // doesn't take ownership of the native handle + return sSensorDevice->data_open(sSensorDevice, handle); } static jint @@ -157,7 +182,7 @@ static JNINativeMethod gMethods[] = { (void*)sensors_module_get_next_sensor }, {"sensors_data_init", "()I", (void*)sensors_data_init }, {"sensors_data_uninit", "()I", (void*)sensors_data_uninit }, - {"sensors_data_open", "(Ljava/io/FileDescriptor;)I", (void*)sensors_data_open }, + {"sensors_data_open", "([Ljava/io/FileDescriptor;[I)I", (void*)sensors_data_open }, {"sensors_data_close", "()I", (void*)sensors_data_close }, {"sensors_data_poll", "([F[I[J)I", (void*)sensors_data_poll }, }; diff --git a/services/java/com/android/server/SensorService.java b/services/java/com/android/server/SensorService.java index b253038..ceef39f 100644 --- a/services/java/com/android/server/SensorService.java +++ b/services/java/com/android/server/SensorService.java @@ -19,7 +19,7 @@ package com.android.server; import android.content.Context; import android.hardware.ISensorService; import android.os.Binder; -import android.os.ParcelFileDescriptor; +import android.os.Bundle; import android.os.RemoteException; import android.os.IBinder; import android.util.Config; @@ -101,7 +101,7 @@ class SensorService extends ISensorService.Stub { _sensors_control_init(); } - public ParcelFileDescriptor getDataChanel() throws RemoteException { + public Bundle getDataChannel() throws RemoteException { return _sensors_control_open(); } @@ -190,7 +190,7 @@ class SensorService extends ISensorService.Stub { ArrayList<Listener> mListeners = new ArrayList<Listener>(); private static native int _sensors_control_init(); - private static native ParcelFileDescriptor _sensors_control_open(); + private static native Bundle _sensors_control_open(); private static native boolean _sensors_control_activate(int sensor, boolean activate); private static native int _sensors_control_set_delay(int ms); private static native int _sensors_control_wake(); diff --git a/services/jni/com_android_server_SensorService.cpp b/services/jni/com_android_server_SensorService.cpp index 695a8a3..7390786 100644 --- a/services/jni/com_android_server_SensorService.cpp +++ b/services/jni/com_android_server_SensorService.cpp @@ -14,7 +14,10 @@ * limitations under the License. */ -#define LOG_TAG "Sensors" +#define LOG_TAG "SensorService" + +#define LOG_NDEBUG 0 +#include "utils/Log.h" #include <hardware/sensors.h> @@ -36,6 +39,14 @@ static struct parcel_file_descriptor_offsets_t jmethodID mConstructor; } gParcelFileDescriptorOffsets; +static struct bundle_descriptor_offsets_t +{ + jclass mClass; + jmethodID mConstructor; + jmethodID mPutIntArray; + jmethodID mPutParcelableArray; +} gBundleOffsets; + /* * The method below are not thread-safe and not intended to be */ @@ -59,21 +70,45 @@ android_init(JNIEnv *env, jclass clazz) static jobject android_open(JNIEnv *env, jclass clazz) { - int fd = sSensorDevice->open_data_source(sSensorDevice); - // new FileDescriptor() - jobject filedescriptor = env->NewObject( - gFileDescriptorOffsets.mClass, - gFileDescriptorOffsets.mConstructor); - - if (filedescriptor != NULL) { - env->SetIntField(filedescriptor, gFileDescriptorOffsets.mDescriptor, fd); - // new ParcelFileDescriptor() - return env->NewObject(gParcelFileDescriptorOffsets.mClass, - gParcelFileDescriptorOffsets.mConstructor, - filedescriptor); + native_handle_t* handle = sSensorDevice->open_data_source(sSensorDevice); + if (!handle) { + return NULL; } - close(fd); - return NULL; + + // new Bundle() + jobject bundle = env->NewObject( + gBundleOffsets.mClass, + gBundleOffsets.mConstructor); + + if (handle->numFds > 0) { + jobjectArray fdArray = env->NewObjectArray(handle->numFds, + gParcelFileDescriptorOffsets.mClass, NULL); + for (int i = 0; i < handle->numFds; i++) { + // new FileDescriptor() + jobject fd = env->NewObject(gFileDescriptorOffsets.mClass, + gFileDescriptorOffsets.mConstructor); + env->SetIntField(fd, gFileDescriptorOffsets.mDescriptor, handle->data[i]); + // new ParcelFileDescriptor() + jobject pfd = env->NewObject(gParcelFileDescriptorOffsets.mClass, + gParcelFileDescriptorOffsets.mConstructor, fd); + env->SetObjectArrayElement(fdArray, i, pfd); + } + // bundle.putParcelableArray("fds", fdArray); + env->CallVoidMethod(bundle, gBundleOffsets.mPutParcelableArray, + env->NewStringUTF("fds"), fdArray); + } + + if (handle->numInts > 0) { + jintArray intArray = env->NewIntArray(handle->numInts); + env->SetIntArrayRegion(intArray, 0, handle->numInts, &handle->data[handle->numInts]); + // bundle.putIntArray("ints", intArray); + env->CallVoidMethod(bundle, gBundleOffsets.mPutIntArray, + env->NewStringUTF("ints"), intArray); + } + + // delete the file handle, but don't close any file descriptors + native_handle_delete(handle); + return bundle; } static jboolean @@ -99,7 +134,7 @@ android_data_wake(JNIEnv *env, jclass clazz) static JNINativeMethod gMethods[] = { {"_sensors_control_init", "()I", (void*) android_init }, - {"_sensors_control_open", "()Landroid/os/ParcelFileDescriptor;", (void*) android_open }, + {"_sensors_control_open", "()Landroid/os/Bundle;", (void*) android_open }, {"_sensors_control_activate", "(IZ)Z", (void*) android_activate }, {"_sensors_control_wake", "()I", (void*) android_data_wake }, {"_sensors_control_set_delay","(I)I", (void*) android_set_delay }, @@ -116,7 +151,15 @@ int register_android_server_SensorService(JNIEnv *env) clazz = env->FindClass("android/os/ParcelFileDescriptor"); gParcelFileDescriptorOffsets.mClass = (jclass) env->NewGlobalRef(clazz); - gParcelFileDescriptorOffsets.mConstructor = env->GetMethodID(clazz, "<init>", "(Ljava/io/FileDescriptor;)V"); + gParcelFileDescriptorOffsets.mConstructor = env->GetMethodID(clazz, "<init>", + "(Ljava/io/FileDescriptor;)V"); + + clazz = env->FindClass("android/os/Bundle"); + gBundleOffsets.mClass = (jclass) env->NewGlobalRef(clazz); + gBundleOffsets.mConstructor = env->GetMethodID(clazz, "<init>", "()V"); + gBundleOffsets.mPutIntArray = env->GetMethodID(clazz, "putIntArray", "(Ljava/lang/String;[I)V"); + gBundleOffsets.mPutParcelableArray = env->GetMethodID(clazz, "putParcelableArray", + "(Ljava/lang/String;[Landroid/os/Parcelable;)V"); return jniRegisterNativeMethods(env, "com/android/server/SensorService", gMethods, NELEM(gMethods)); |