151e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling/*
251e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling * Copyright (C) 2013 The Android Open Source Project
351e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling *
451e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling * Licensed under the Apache License, Version 2.0 (the "License");
551e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling * you may not use this file except in compliance with the License.
651e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling * You may obtain a copy of the License at
751e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling *
851e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling *      http://www.apache.org/licenses/LICENSE-2.0
951e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling *
1051e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling * Unless required by applicable law or agreed to in writing, software
1151e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling * distributed under the License is distributed on an "AS IS" BASIS,
1251e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1351e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling * See the License for the specific language governing permissions and
1451e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling * limitations under the License.
1551e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling */
1651e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling
1751e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling#define LOG_TAG "ConsumerIrService"
1851e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling
1951e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling#include "jni.h"
2051e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling#include "JNIHelp.h"
2151e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling#include "android_runtime/AndroidRuntime.h"
2251e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling
2351e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling#include <stdlib.h>
2451e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling#include <utils/misc.h>
2551e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling#include <utils/Log.h>
2651e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling#include <hardware/hardware.h>
2751e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling#include <hardware/consumerir.h>
2851e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling#include <ScopedPrimitiveArray.h>
2951e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling
3051e95df8f24e9ea30775686b9e324b9a671213dcErik Gillingnamespace android {
3151e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling
3226872f4b9e634d77ecd78e4eee9d5d070f8553f8Andreas Gampestatic jlong halOpen(JNIEnv* /* env */, jobject /* obj */) {
3351e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling    hw_module_t const* module;
3451e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling    consumerir_device_t *dev;
3551e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling    int err;
3651e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling
3751e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling    err = hw_get_module(CONSUMERIR_HARDWARE_MODULE_ID, &module);
3851e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling    if (err != 0) {
3951e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling        ALOGE("Can't open consumer IR HW Module, error: %d", err);
4051e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling        return 0;
4151e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling    }
4251e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling
4351e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling    err = module->methods->open(module, CONSUMERIR_TRANSMITTER,
4451e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling            (hw_device_t **) &dev);
4551e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling    if (err < 0) {
4651e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling        ALOGE("Can't open consumer IR transmitter, error: %d", err);
4751e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling        return 0;
4851e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling    }
4951e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling
500d552f7d8b793f44c9442c19683a5433004b023eAshok Bhat    return reinterpret_cast<jlong>(dev);
5151e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling}
5251e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling
5326872f4b9e634d77ecd78e4eee9d5d070f8553f8Andreas Gampestatic jint halTransmit(JNIEnv *env, jobject /* obj */, jlong halObject,
5451e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling   jint carrierFrequency, jintArray pattern) {
5551e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling    int ret;
5651e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling
5751e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling    consumerir_device_t *dev = reinterpret_cast<consumerir_device_t*>(halObject);
5851e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling    ScopedIntArrayRO cPattern(env, pattern);
5951e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling    if (cPattern.get() == NULL) {
6051e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling        return -EINVAL;
6151e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling    }
6251e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling    jsize patternLength = cPattern.size();
6351e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling
6451e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling    ret = dev->transmit(dev, carrierFrequency, cPattern.get(), patternLength);
6551e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling
6651e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling    return reinterpret_cast<jint>(ret);
6751e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling}
6851e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling
6926872f4b9e634d77ecd78e4eee9d5d070f8553f8Andreas Gampestatic jintArray halGetCarrierFrequencies(JNIEnv *env, jobject /* obj */,
700d552f7d8b793f44c9442c19683a5433004b023eAshok Bhat    jlong halObject) {
710d552f7d8b793f44c9442c19683a5433004b023eAshok Bhat    consumerir_device_t *dev = reinterpret_cast<consumerir_device_t*>(halObject);
7251e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling    consumerir_freq_range_t *ranges;
7351e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling    int len;
7451e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling
7551e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling    len = dev->get_num_carrier_freqs(dev);
7651e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling    if (len <= 0)
7751e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling        return NULL;
7851e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling
7951e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling    ranges = new consumerir_freq_range_t[len];
8051e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling
815022f275e31a1200c5e7e296642e513e52ed58d9Alex Ray    len = dev->get_carrier_freqs(dev, len, ranges);
8251e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling    if (len <= 0) {
8351e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling        delete[] ranges;
8451e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling        return NULL;
8551e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling    }
8651e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling
8751e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling    int i;
8851e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling    ScopedIntArrayRW freqsOut(env, env->NewIntArray(len*2));
8951e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling    jint *arr = freqsOut.get();
9051e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling    if (arr == NULL) {
9151e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling        delete[] ranges;
9251e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling        return NULL;
9351e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling    }
9451e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling    for (i = 0; i < len; i++) {
9551e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling        arr[i*2] = ranges[i].min;
9651e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling        arr[i*2+1] = ranges[i].max;
9751e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling    }
9851e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling
9951e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling    delete[] ranges;
10051e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling    return freqsOut.getJavaArray();
10151e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling}
10251e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling
10376f6a86de25e1bf74717e047e55fd44b089673f3Daniel Micaystatic const JNINativeMethod method_table[] = {
1040d552f7d8b793f44c9442c19683a5433004b023eAshok Bhat    { "halOpen", "()J", (void *)halOpen },
1050d552f7d8b793f44c9442c19683a5433004b023eAshok Bhat    { "halTransmit", "(JI[I)I", (void *)halTransmit },
1060d552f7d8b793f44c9442c19683a5433004b023eAshok Bhat    { "halGetCarrierFrequencies", "(J)[I", (void *)halGetCarrierFrequencies},
10751e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling};
10851e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling
10951e95df8f24e9ea30775686b9e324b9a671213dcErik Gillingint register_android_server_ConsumerIrService(JNIEnv *env) {
11051e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling    return jniRegisterNativeMethods(env, "com/android/server/ConsumerIrService",
11151e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling            method_table, NELEM(method_table));
11251e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling}
11351e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling
11451e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling};
115