Merge "Move ConsumerIrService to HIDL HAL"

This commit is contained in:
Connor O'Brien
2016-12-16 19:03:23 +00:00
committed by Android (Google) Code Review
3 changed files with 43 additions and 59 deletions

View File

@@ -29,13 +29,13 @@ public class ConsumerIrService extends IConsumerIrService.Stub {
private static final int MAX_XMIT_TIME = 2000000; /* in microseconds */
private static native long halOpen();
private static native int halTransmit(long halObject, int carrierFrequency, int[] pattern);
private static native int[] halGetCarrierFrequencies(long halObject);
private static native boolean halOpen();
private static native int halTransmit(int carrierFrequency, int[] pattern);
private static native int[] halGetCarrierFrequencies();
private final Context mContext;
private final PowerManager.WakeLock mWakeLock;
private final long mNativeHal;
private final boolean mHasNativeHal;
private final Object mHalLock = new Object();
ConsumerIrService(Context context) {
@@ -45,23 +45,23 @@ public class ConsumerIrService extends IConsumerIrService.Stub {
mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
mWakeLock.setReferenceCounted(true);
mNativeHal = halOpen();
mHasNativeHal = halOpen();
if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CONSUMER_IR)) {
if (mNativeHal == 0) {
if (!mHasNativeHal) {
throw new RuntimeException("FEATURE_CONSUMER_IR present, but no IR HAL loaded!");
}
} else if (mNativeHal != 0) {
} else if (mHasNativeHal) {
throw new RuntimeException("IR HAL present, but FEATURE_CONSUMER_IR is not set!");
}
}
@Override
public boolean hasIrEmitter() {
return mNativeHal != 0;
return mHasNativeHal;
}
private void throwIfNoIrEmitter() {
if (mNativeHal == 0) {
if (!mHasNativeHal) {
throw new UnsupportedOperationException("IR emitter not available");
}
}
@@ -91,7 +91,7 @@ public class ConsumerIrService extends IConsumerIrService.Stub {
// Right now there is no mechanism to ensure fair queing of IR requests
synchronized (mHalLock) {
int err = halTransmit(mNativeHal, carrierFrequency, pattern);
int err = halTransmit(carrierFrequency, pattern);
if (err < 0) {
Slog.e(TAG, "Error transmitting: " + err);
@@ -109,7 +109,7 @@ public class ConsumerIrService extends IConsumerIrService.Stub {
throwIfNoIrEmitter();
synchronized(mHalLock) {
return halGetCarrierFrequencies(mNativeHal);
return halGetCarrierFrequencies();
}
}
}

View File

@@ -74,6 +74,7 @@ LOCAL_SHARED_LIBRARIES += \
libutils \
android.hardware.audio.common@2.0 \
android.hardware.gnss@1.0 \
android.hardware.ir@1.0 \
android.hardware.light@2.0 \
android.hardware.power@1.0 \
android.hardware.thermal@1.0 \

View File

@@ -23,87 +23,70 @@
#include <stdlib.h>
#include <utils/misc.h>
#include <utils/Log.h>
#include <hardware/hardware.h>
#include <hardware/consumerir.h>
#include <android/hardware/ir/1.0/IConsumerIr.h>
#include <ScopedPrimitiveArray.h>
using ::android::hardware::ir::V1_0::IConsumerIr;
using ::android::hardware::ir::V1_0::ConsumerIrFreqRange;
using ::android::hardware::hidl_vec;
namespace android {
static jlong halOpen(JNIEnv* /* env */, jobject /* obj */) {
hw_module_t const* module;
consumerir_device_t *dev;
int err;
static sp<IConsumerIr> mHal;
err = hw_get_module(CONSUMERIR_HARDWARE_MODULE_ID, &module);
if (err != 0) {
ALOGE("Can't open consumer IR HW Module, error: %d", err);
return 0;
}
err = module->methods->open(module, CONSUMERIR_TRANSMITTER,
(hw_device_t **) &dev);
if (err < 0) {
ALOGE("Can't open consumer IR transmitter, error: %d", err);
return 0;
}
return reinterpret_cast<jlong>(dev);
static jboolean halOpen(JNIEnv* /* env */, jobject /* obj */) {
// TODO(b/31632518)
mHal = IConsumerIr::getService("consumerir");
return mHal != nullptr;
}
static jint halTransmit(JNIEnv *env, jobject /* obj */, jlong halObject,
jint carrierFrequency, jintArray pattern) {
int ret;
consumerir_device_t *dev = reinterpret_cast<consumerir_device_t*>(halObject);
static jint halTransmit(JNIEnv *env, jobject /* obj */, jint carrierFrequency,
jintArray pattern) {
ScopedIntArrayRO cPattern(env, pattern);
if (cPattern.get() == NULL) {
return -EINVAL;
}
jsize patternLength = cPattern.size();
hidl_vec<int32_t> patternVec;
patternVec.setToExternal(const_cast<int32_t*>(cPattern.get()), cPattern.size());
ret = dev->transmit(dev, carrierFrequency, cPattern.get(), patternLength);
return reinterpret_cast<jint>(ret);
bool success = mHal->transmit(carrierFrequency, patternVec, cPattern.size());
return success ? 0 : -1;
}
static jintArray halGetCarrierFrequencies(JNIEnv *env, jobject /* obj */,
jlong halObject) {
consumerir_device_t *dev = reinterpret_cast<consumerir_device_t*>(halObject);
consumerir_freq_range_t *ranges;
static jintArray halGetCarrierFrequencies(JNIEnv *env, jobject /* obj */) {
int len;
hidl_vec<ConsumerIrFreqRange> ranges;
bool success;
len = dev->get_num_carrier_freqs(dev);
if (len <= 0)
return NULL;
auto cb = [&](bool s, hidl_vec<ConsumerIrFreqRange> vec) {
ranges = vec;
success = s;
};
mHal->getCarrierFreqs(cb);
ranges = new consumerir_freq_range_t[len];
len = dev->get_carrier_freqs(dev, len, ranges);
if (len <= 0) {
delete[] ranges;
if (!success) {
return NULL;
}
len = ranges.size();
int i;
ScopedIntArrayRW freqsOut(env, env->NewIntArray(len*2));
jint *arr = freqsOut.get();
if (arr == NULL) {
delete[] ranges;
return NULL;
}
for (i = 0; i < len; i++) {
arr[i*2] = ranges[i].min;
arr[i*2+1] = ranges[i].max;
arr[i*2] = static_cast<jint>(ranges[i].min);
arr[i*2+1] = static_cast<jint>(ranges[i].max);
}
delete[] ranges;
return freqsOut.getJavaArray();
}
static const JNINativeMethod method_table[] = {
{ "halOpen", "()J", (void *)halOpen },
{ "halTransmit", "(JI[I)I", (void *)halTransmit },
{ "halGetCarrierFrequencies", "(J)[I", (void *)halGetCarrierFrequencies},
{ "halOpen", "()Z", (void *)halOpen },
{ "halTransmit", "(I[I)I", (void *)halTransmit },
{ "halGetCarrierFrequencies", "()[I", (void *)halGetCarrierFrequencies},
};
int register_android_server_ConsumerIrService(JNIEnv *env) {