Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 66f53ca9 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Sensor direct report HardwareBuffer implementation"

parents a6a31fd3 7d96fa0b
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -135,8 +135,8 @@ public final class SensorDirectChannel implements AutoCloseable {
    }

    /**
     * This function encode handle information in {@link android.os.Memory} into a long array to be
     * passed down to native methods.
     * This function encode handle information in {@link android.os.MemoryFile} into a long array to
     * be passed down to native methods.
     *
     * @hide */
    static long[] encodeData(MemoryFile ashmem) {
+4 −4
Original line number Diff line number Diff line
@@ -895,7 +895,7 @@ public abstract class SensorManager {
     * @see #configureDirectChannel(SensorDirectChannel, Sensor, int)
     */
    public SensorDirectChannel createDirectChannel(MemoryFile mem) {
        return createDirectChannelImpl(mem.length(), mem, null);
        return createDirectChannelImpl(mem, null);
    }

    /**
@@ -913,12 +913,12 @@ public abstract class SensorManager {
     * @see #configureDirectChannel(SensorDirectChannel, Sensor, int)
     */
    public SensorDirectChannel createDirectChannel(HardwareBuffer mem) {
        return null;
        return createDirectChannelImpl(null, mem);
    }

    /** @hide */
    protected abstract SensorDirectChannel createDirectChannelImpl(long size,
            MemoryFile ashmemFile, HardwareBuffer hardwareBuffer);
    protected abstract SensorDirectChannel createDirectChannelImpl(
            MemoryFile memoryFile, HardwareBuffer hardwareBuffer);

    /** @hide */
    void destroyDirectChannel(SensorDirectChannel channel) {
+44 −12
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@ import dalvik.system.CloseGuard;

import com.android.internal.annotations.GuardedBy;

import java.io.IOException;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.HashMap;
@@ -50,6 +51,7 @@ import java.util.Map;
public class SystemSensorManager extends SensorManager {
    //TODO: disable extra logging before release
    private static boolean DEBUG_DYNAMIC_SENSOR = true;
    private static int MIN_DIRECT_CHANNEL_BUFFER_SIZE = 104;

    private static native void nativeClassInit();
    private static native long nativeCreate(String opPackageName);
@@ -59,7 +61,7 @@ public class SystemSensorManager extends SensorManager {
    private static native boolean nativeIsDataInjectionEnabled(long nativeInstance);

    private static native int nativeCreateDirectChannel(
            long nativeInstance, long size, int channelType, long [] channelData);
            long nativeInstance, long size, int channelType, int fd, HardwareBuffer buffer);
    private static native void nativeDestroyDirectChannel(
            long nativeInstance, int channelHandle);
    private static native int nativeConfigDirectChannel(
@@ -525,24 +527,54 @@ public class SystemSensorManager extends SensorManager {
    }

    /** @hide */
    protected SensorDirectChannel createDirectChannelImpl(long size,
            MemoryFile ashmemFile, HardwareBuffer grallocMemObject) {
    protected SensorDirectChannel createDirectChannelImpl(
            MemoryFile memoryFile, HardwareBuffer hardwareBuffer) {
        SensorDirectChannel ch = null;
        long size;
        if (memoryFile != null) {
            int fd;
            try {
                fd = memoryFile.getFileDescriptor().getInt$();
            } catch (IOException e) {
                throw new IllegalArgumentException("MemoryFile object is not valid");
            }

        if (size <= 0) throw new IllegalArgumentException("size has to be greater than 0");

        if (ashmemFile != null) {
            if (size != ashmemFile.length()) {
                throw new IllegalArgumentException("size has to match MemoryFile.length()");
            if (memoryFile.length() < MIN_DIRECT_CHANNEL_BUFFER_SIZE) {
                throw new IllegalArgumentException(
                        "Size of MemoryFile has to be greater than "
                        + MIN_DIRECT_CHANNEL_BUFFER_SIZE);
            }

            size = memoryFile.length();
            int id = nativeCreateDirectChannel(
                    mNativeInstance, size, SensorDirectChannel.TYPE_ASHMEM,
                    SensorDirectChannel.encodeData(ashmemFile));
                    mNativeInstance, size, SensorDirectChannel.TYPE_ASHMEM, fd, null);
            if (id > 0) {
                ch = new SensorDirectChannel(this, id, SensorDirectChannel.TYPE_ASHMEM, size);
            }
        } else if (grallocMemObject != null) {
            Log.wtf(TAG, "Implement GRALLOC or remove GRALLOC support entirely");
        } else if (hardwareBuffer != null) {
            if (hardwareBuffer.getFormat() != HardwareBuffer.BLOB) {
                throw new IllegalArgumentException("Format of HardwareBuffer must be BLOB");
            }
            if (hardwareBuffer.getHeight() != 1) {
                throw new IllegalArgumentException("Height of HardwareBuffer must be 1");
            }
            if (hardwareBuffer.getWidth() < MIN_DIRECT_CHANNEL_BUFFER_SIZE) {
                throw new IllegalArgumentException(
                        "Width if HaradwareBuffer must be greater than "
                        + MIN_DIRECT_CHANNEL_BUFFER_SIZE);
            }
            if ((hardwareBuffer.getUsage() & HardwareBuffer.USAGE0_SENSOR_DIRECT_DATA) == 0) {
                throw new IllegalArgumentException(
                        "HardwareBuffer must set usage flag USAGE0_SENSOR_DIRECT_DATA");
            }
            size = hardwareBuffer.getWidth();
            int id = nativeCreateDirectChannel(
                    mNativeInstance, size, SensorDirectChannel.TYPE_HARDWARE_BUFFER,
                    -1, hardwareBuffer);
            if (id > 0) {
                ch = new SensorDirectChannel(
                        this, id, SensorDirectChannel.TYPE_HARDWARE_BUFFER, size);
            }
        } else {
            throw new IllegalArgumentException("Invalid parameter");
        }
+22 −32
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@
#include <ScopedUtfChars.h>
#include <ScopedLocalRef.h>
#include <android_runtime/AndroidRuntime.h>
#include <android_runtime/android_hardware_HardwareBuffer.h>
#include <sensor/Sensor.h>
#include <sensor/SensorEventQueue.h>
#include <sensor/SensorManager.h>
@@ -245,39 +246,28 @@ static jboolean nativeIsDataInjectionEnabled(JNIEnv *_env, jclass _this, jlong s
}

static jint nativeCreateDirectChannel(JNIEnv *_env, jclass _this, jlong sensorManager,
        jlong size, jint channelType, jlongArray channelData) {
    jint ret = -1;
    jsize len = _env->GetArrayLength(channelData);
    if (len > 2) {
        jlong *data = _env->GetLongArrayElements(channelData, NULL);
        if (data != nullptr) {
            // construct native handle from jlong*
            jlong numFd = data[0];
            jlong numInt = data[1];
            if ((numFd + numInt + 2) == len) {
                native_handle_t *nativeHandle = native_handle_create(numFd, numInt);
                if (nativeHandle != nullptr) {
                    const jlong *readPointer = data + 2;
                    int *writePointer = nativeHandle->data;
                    size_t n = static_cast<size_t>(numFd + numInt);
                    while (n--) {
                        // native type of data is int, jlong is just to ensure Java does not
                        // truncate data on 64-bit system. The cast here is safe.
                        *writePointer++ = static_cast<int>(*readPointer++);
                    }

                    SensorManager* mgr = reinterpret_cast<SensorManager*>(sensorManager);
                    ret = mgr->createDirectChannel(size, channelType, nativeHandle);
        jlong size, jint channelType, jint fd, jobject hardwareBufferObj) {
    const native_handle_t *nativeHandle = nullptr;
    NATIVE_HANDLE_DECLARE_STORAGE(ashmemHandle, 1, 0);

                    // do not native_handle_close() here as handle is owned by java
                    native_handle_delete(nativeHandle);
                }
    if (channelType == SENSOR_DIRECT_MEM_TYPE_ASHMEM) {
        native_handle_t *handle = native_handle_init(ashmemHandle, 1, 0);
        handle->data[0] = fd;
        nativeHandle = handle;
    } else if (channelType == SENSOR_DIRECT_MEM_TYPE_GRALLOC) {
        AHardwareBuffer *hardwareBuffer =
                android_hardware_HardwareBuffer_getNativeHardwareBuffer(_env, hardwareBufferObj);
        if (hardwareBuffer != nullptr) {
            nativeHandle = AHardwareBuffer_getNativeHandle(hardwareBuffer);
        }
            // unidirectional parameter passing, thus JNI_ABORT
            _env->ReleaseLongArrayElements(channelData, data, JNI_ABORT);
    }

    if (nativeHandle == nullptr) {
        return BAD_VALUE;
    }
    return ret;

    SensorManager* mgr = reinterpret_cast<SensorManager*>(sensorManager);
    return mgr->createDirectChannel(size, channelType, nativeHandle);
}

static void nativeDestroyDirectChannel(JNIEnv *_env, jclass _this, jlong sensorManager,
@@ -499,7 +489,7 @@ static const JNINativeMethod gSystemSensorManagerMethods[] = {
            (void*)nativeIsDataInjectionEnabled },

    {"nativeCreateDirectChannel",
            "(JJI[J)I",
            "(JJIILandroid/hardware/HardwareBuffer;)I",
            (void*)nativeCreateDirectChannel },

    {"nativeDestroyDirectChannel",