131c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk/**
231c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk * Copyright (C) 2017 The Android Open Source Project
331c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk *
431c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk * Licensed under the Apache License, Version 2.0 (the "License");
531c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk * you may not use this file except in compliance with the License.
631c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk * You may obtain a copy of the License at
731c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk *
831c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk *      http://www.apache.org/licenses/LICENSE-2.0
931c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk *
1031c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk * Unless required by applicable law or agreed to in writing, software
1131c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk * distributed under the License is distributed on an "AS IS" BASIS,
1231c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1331c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk * See the License for the specific language governing permissions and
1431c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk * limitations under the License.
1531c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk */
1631c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk
176b4b646d9c0fa42973a429dbe78c8919a2772961Tomasz Wasilczyk#define LOG_TAG "BroadcastRadioService.convert.jni"
1831c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk#define LOG_NDEBUG 0
1931c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk
206b4b646d9c0fa42973a429dbe78c8919a2772961Tomasz Wasilczyk#include "convert.h"
2131c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk
22a6f1523532c08387e4ecd0282460321b50aecf0eTomasz Wasilczyk#include "regions.h"
23a6f1523532c08387e4ecd0282460321b50aecf0eTomasz Wasilczyk
248e67a33fec8741b8483a5a07f5f6a83cf5b5edfdTomasz Wasilczyk#include <broadcastradio-utils-1x/Utils.h>
2531c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk#include <core_jni_helpers.h>
26e3e8f90c74a4ed4a4463205d2f36ae5f9bc03ea4Tomasz Wasilczyk#include <nativehelper/JNIHelp.h>
2731c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk#include <utils/Log.h>
2831c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk
2931c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyknamespace android {
3031c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyknamespace server {
316b4b646d9c0fa42973a429dbe78c8919a2772961Tomasz Wasilczyknamespace BroadcastRadio {
3231c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyknamespace convert {
3331c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk
3420eef7d0e8ae6a22825d9760e7eb82b1386668ceTomasz Wasilczyknamespace utils = hardware::broadcastradio::utils;
35a6f1523532c08387e4ecd0282460321b50aecf0eTomasz Wasilczyk
368b6db4f2eb02f231dd8006debbc1e1be1181178aTomasz Wasilczykusing hardware::Return;
378e932c61db78e7a04f6a98e070089f10abdccf1aTomasz Wasilczykusing hardware::hidl_string;
3831c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczykusing hardware::hidl_vec;
39a6f1523532c08387e4ecd0282460321b50aecf0eTomasz Wasilczykusing regions::RegionalBandConfig;
4031c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk
4131c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczykusing V1_0::Band;
4231c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczykusing V1_0::Deemphasis;
432383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczykusing V1_0::Direction;
442383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczykusing V1_0::MetadataType;
458b6db4f2eb02f231dd8006debbc1e1be1181178aTomasz Wasilczykusing V1_0::Result;
4631c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczykusing V1_0::Rds;
478cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczykusing V1_1::ProgramIdentifier;
48d3d53f669268fe8dd15f16abbd0504f7b9e38405Tomasz Wasilczykusing V1_1::ProgramListResult;
498cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczykusing V1_1::ProgramSelector;
500f1776d08b43f5f71a9f89b6a4f1838df4d3d744Tomasz Wasilczykusing V1_1::VendorKeyValue;
5131c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk
52eab3e5509689cf4dd066f0de5e060967626b3a2aTomasz Wasilczyk// HAL 2.0 flags that have equivalent HAL 1.x fields
53eab3e5509689cf4dd066f0de5e060967626b3a2aTomasz Wasilczykenum class ProgramInfoFlagsExt {
54eab3e5509689cf4dd066f0de5e060967626b3a2aTomasz Wasilczyk    TUNED = 1 << 4,
55eab3e5509689cf4dd066f0de5e060967626b3a2aTomasz Wasilczyk    STEREO = 1 << 5,
56eab3e5509689cf4dd066f0de5e060967626b3a2aTomasz Wasilczyk};
57eab3e5509689cf4dd066f0de5e060967626b3a2aTomasz Wasilczyk
58a6f1523532c08387e4ecd0282460321b50aecf0eTomasz Wasilczykstatic JavaRef<jobject> BandDescriptorFromHal(JNIEnv *env, const RegionalBandConfig &config);
59d15c9dfd8b87ff54b2e5304b941c2e62f7e93dd6Tomasz Wasilczykstatic JavaRef<jobject> BandDescriptorFromHal(JNIEnv *env, const V1_0::BandConfig &config, Region region);
60d15c9dfd8b87ff54b2e5304b941c2e62f7e93dd6Tomasz Wasilczyk
6131c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczykstatic struct {
6231c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk    struct {
6331c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk        jfieldID descriptor;
6431c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk    } BandConfig;
6531c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk    struct {
6631c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk        jclass clazz;
6731c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk        jmethodID cstor;
6831c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk        jfieldID stereo;
6931c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk        jfieldID rds;
7031c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk        jfieldID ta;
7131c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk        jfieldID af;
7231c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk        jfieldID ea;
7331c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk    } FmBandConfig;
7431c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk    struct {
7531c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk        jclass clazz;
7631c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk        jmethodID cstor;
7731c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk        jfieldID stereo;
7831c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk    } AmBandConfig;
7931c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk
8031c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk    struct {
81d15c9dfd8b87ff54b2e5304b941c2e62f7e93dd6Tomasz Wasilczyk        jclass clazz;
8231c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk        jfieldID region;
8331c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk        jfieldID type;
8431c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk        jfieldID lowerLimit;
8531c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk        jfieldID upperLimit;
8631c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk        jfieldID spacing;
8731c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk    } BandDescriptor;
88d15c9dfd8b87ff54b2e5304b941c2e62f7e93dd6Tomasz Wasilczyk    struct {
89d15c9dfd8b87ff54b2e5304b941c2e62f7e93dd6Tomasz Wasilczyk        jclass clazz;
90d15c9dfd8b87ff54b2e5304b941c2e62f7e93dd6Tomasz Wasilczyk        jmethodID cstor;
91d15c9dfd8b87ff54b2e5304b941c2e62f7e93dd6Tomasz Wasilczyk    } FmBandDescriptor;
92d15c9dfd8b87ff54b2e5304b941c2e62f7e93dd6Tomasz Wasilczyk    struct {
93d15c9dfd8b87ff54b2e5304b941c2e62f7e93dd6Tomasz Wasilczyk        jclass clazz;
94d15c9dfd8b87ff54b2e5304b941c2e62f7e93dd6Tomasz Wasilczyk        jmethodID cstor;
95d15c9dfd8b87ff54b2e5304b941c2e62f7e93dd6Tomasz Wasilczyk    } AmBandDescriptor;
96d15c9dfd8b87ff54b2e5304b941c2e62f7e93dd6Tomasz Wasilczyk
97d15c9dfd8b87ff54b2e5304b941c2e62f7e93dd6Tomasz Wasilczyk    struct {
98d15c9dfd8b87ff54b2e5304b941c2e62f7e93dd6Tomasz Wasilczyk        jclass clazz;
990f1776d08b43f5f71a9f89b6a4f1838df4d3d744Tomasz Wasilczyk        jmethodID stringMapToNative;
1000f1776d08b43f5f71a9f89b6a4f1838df4d3d744Tomasz Wasilczyk    } Convert;
1010f1776d08b43f5f71a9f89b6a4f1838df4d3d744Tomasz Wasilczyk
1020f1776d08b43f5f71a9f89b6a4f1838df4d3d744Tomasz Wasilczyk    struct {
1030f1776d08b43f5f71a9f89b6a4f1838df4d3d744Tomasz Wasilczyk        jclass clazz;
1040f1776d08b43f5f71a9f89b6a4f1838df4d3d744Tomasz Wasilczyk        jmethodID cstor;
1050f1776d08b43f5f71a9f89b6a4f1838df4d3d744Tomasz Wasilczyk    } HashMap;
1060f1776d08b43f5f71a9f89b6a4f1838df4d3d744Tomasz Wasilczyk
1070f1776d08b43f5f71a9f89b6a4f1838df4d3d744Tomasz Wasilczyk    struct {
1088e932c61db78e7a04f6a98e070089f10abdccf1aTomasz Wasilczyk        jmethodID get;
1098e932c61db78e7a04f6a98e070089f10abdccf1aTomasz Wasilczyk        jmethodID size;
1108e932c61db78e7a04f6a98e070089f10abdccf1aTomasz Wasilczyk    } List;
1118e932c61db78e7a04f6a98e070089f10abdccf1aTomasz Wasilczyk
1128e932c61db78e7a04f6a98e070089f10abdccf1aTomasz Wasilczyk    struct {
1130f1776d08b43f5f71a9f89b6a4f1838df4d3d744Tomasz Wasilczyk        jmethodID put;
1140f1776d08b43f5f71a9f89b6a4f1838df4d3d744Tomasz Wasilczyk    } Map;
1150f1776d08b43f5f71a9f89b6a4f1838df4d3d744Tomasz Wasilczyk
1160f1776d08b43f5f71a9f89b6a4f1838df4d3d744Tomasz Wasilczyk    struct {
1170f1776d08b43f5f71a9f89b6a4f1838df4d3d744Tomasz Wasilczyk        jclass clazz;
118d15c9dfd8b87ff54b2e5304b941c2e62f7e93dd6Tomasz Wasilczyk        jmethodID cstor;
119d15c9dfd8b87ff54b2e5304b941c2e62f7e93dd6Tomasz Wasilczyk    } ModuleProperties;
1202383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk
1212383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk    struct {
1222383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk        jclass clazz;
1232383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk        jmethodID cstor;
1242383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk    } ProgramInfo;
1252383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk
1262383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk    struct {
1272383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk        jclass clazz;
1282383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk        jmethodID cstor;
1298cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk        jfieldID programType;
1308cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk        jfieldID primaryId;
1318cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk        jfieldID secondaryIds;
1328cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk        jfieldID vendorIds;
1338cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk
1348cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk        struct {
1358cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk            jclass clazz;
1368cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk            jmethodID cstor;
1378cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk            jfieldID type;
1388cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk            jfieldID value;
1398cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk        } Identifier;
1408cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk    } ProgramSelector;
1418cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk
1428cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk    struct {
1438cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk        jclass clazz;
1448cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk        jmethodID cstor;
1452383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk        jmethodID putIntFromNative;
1462383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk        jmethodID putStringFromNative;
1472383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk        jmethodID putBitmapFromNative;
1482383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk        jmethodID putClockFromNative;
1492383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk    } RadioMetadata;
150c62e38d573b647ff4d3293d07dbdce3440a6b739Tomasz Wasilczyk
151c62e38d573b647ff4d3293d07dbdce3440a6b739Tomasz Wasilczyk    struct {
152c62e38d573b647ff4d3293d07dbdce3440a6b739Tomasz Wasilczyk        jclass clazz;
153c62e38d573b647ff4d3293d07dbdce3440a6b739Tomasz Wasilczyk        jmethodID cstor;
154c62e38d573b647ff4d3293d07dbdce3440a6b739Tomasz Wasilczyk    } RuntimeException;
155c62e38d573b647ff4d3293d07dbdce3440a6b739Tomasz Wasilczyk
156c62e38d573b647ff4d3293d07dbdce3440a6b739Tomasz Wasilczyk    struct {
157c62e38d573b647ff4d3293d07dbdce3440a6b739Tomasz Wasilczyk        jclass clazz;
158c62e38d573b647ff4d3293d07dbdce3440a6b739Tomasz Wasilczyk        jmethodID cstor;
159c62e38d573b647ff4d3293d07dbdce3440a6b739Tomasz Wasilczyk    } ParcelableException;
1608e932c61db78e7a04f6a98e070089f10abdccf1aTomasz Wasilczyk
1618e932c61db78e7a04f6a98e070089f10abdccf1aTomasz Wasilczyk    struct {
1628e932c61db78e7a04f6a98e070089f10abdccf1aTomasz Wasilczyk        jclass clazz;
1638e932c61db78e7a04f6a98e070089f10abdccf1aTomasz Wasilczyk    } String;
16431c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk} gjni;
16531c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk
1668e932c61db78e7a04f6a98e070089f10abdccf1aTomasz Wasilczykstatic jstring CastToString(JNIEnv *env, jobject obj) {
1678e932c61db78e7a04f6a98e070089f10abdccf1aTomasz Wasilczyk    if (env->IsInstanceOf(obj, gjni.String.clazz)) {
1688e932c61db78e7a04f6a98e070089f10abdccf1aTomasz Wasilczyk        return static_cast<jstring>(obj);
1698e932c61db78e7a04f6a98e070089f10abdccf1aTomasz Wasilczyk    } else {
1708e932c61db78e7a04f6a98e070089f10abdccf1aTomasz Wasilczyk        ALOGE("Cast failed, object is not a string");
1718e932c61db78e7a04f6a98e070089f10abdccf1aTomasz Wasilczyk        return nullptr;
1728e932c61db78e7a04f6a98e070089f10abdccf1aTomasz Wasilczyk    }
1738e932c61db78e7a04f6a98e070089f10abdccf1aTomasz Wasilczyk}
1748e932c61db78e7a04f6a98e070089f10abdccf1aTomasz Wasilczyk
1754482b1413656b9c0c5937b4d7a73235f872a6678Tomasz Wasilczyktemplate <>
1764482b1413656b9c0c5937b4d7a73235f872a6678Tomasz Wasilczykbool ThrowIfFailed(JNIEnv *env, const hardware::Return<void> &hidlResult) {
1774482b1413656b9c0c5937b4d7a73235f872a6678Tomasz Wasilczyk    return __ThrowIfFailedHidl(env, hidlResult);
1784482b1413656b9c0c5937b4d7a73235f872a6678Tomasz Wasilczyk}
1794482b1413656b9c0c5937b4d7a73235f872a6678Tomasz Wasilczyk
180d3d53f669268fe8dd15f16abbd0504f7b9e38405Tomasz Wasilczykbool __ThrowIfFailedHidl(JNIEnv *env, const hardware::details::return_status &hidlResult) {
1818b6db4f2eb02f231dd8006debbc1e1be1181178aTomasz Wasilczyk    if (hidlResult.isOk()) return false;
1828b6db4f2eb02f231dd8006debbc1e1be1181178aTomasz Wasilczyk
183c62e38d573b647ff4d3293d07dbdce3440a6b739Tomasz Wasilczyk    ThrowParcelableRuntimeException(env, "HIDL call failed: " + hidlResult.description());
1848b6db4f2eb02f231dd8006debbc1e1be1181178aTomasz Wasilczyk    return true;
1858b6db4f2eb02f231dd8006debbc1e1be1181178aTomasz Wasilczyk}
1868b6db4f2eb02f231dd8006debbc1e1be1181178aTomasz Wasilczyk
187d3d53f669268fe8dd15f16abbd0504f7b9e38405Tomasz Wasilczykbool __ThrowIfFailed(JNIEnv *env, const Result halResult) {
18837d986d17d0210706be907ce9119b711eeaca235Tomasz Wasilczyk    switch (halResult) {
1898b6db4f2eb02f231dd8006debbc1e1be1181178aTomasz Wasilczyk        case Result::OK:
1908b6db4f2eb02f231dd8006debbc1e1be1181178aTomasz Wasilczyk            return false;
1918b6db4f2eb02f231dd8006debbc1e1be1181178aTomasz Wasilczyk        case Result::NOT_INITIALIZED:
192c62e38d573b647ff4d3293d07dbdce3440a6b739Tomasz Wasilczyk            ThrowParcelableRuntimeException(env, "Result::NOT_INITIALIZED");
1938b6db4f2eb02f231dd8006debbc1e1be1181178aTomasz Wasilczyk            return true;
1948b6db4f2eb02f231dd8006debbc1e1be1181178aTomasz Wasilczyk        case Result::INVALID_ARGUMENTS:
1958b6db4f2eb02f231dd8006debbc1e1be1181178aTomasz Wasilczyk            jniThrowException(env, "java/lang/IllegalArgumentException",
1968b6db4f2eb02f231dd8006debbc1e1be1181178aTomasz Wasilczyk                    "Result::INVALID_ARGUMENTS");
1978b6db4f2eb02f231dd8006debbc1e1be1181178aTomasz Wasilczyk            return true;
1988b6db4f2eb02f231dd8006debbc1e1be1181178aTomasz Wasilczyk        case Result::INVALID_STATE:
1998b6db4f2eb02f231dd8006debbc1e1be1181178aTomasz Wasilczyk            jniThrowException(env, "java/lang/IllegalStateException", "Result::INVALID_STATE");
2008b6db4f2eb02f231dd8006debbc1e1be1181178aTomasz Wasilczyk            return true;
2018b6db4f2eb02f231dd8006debbc1e1be1181178aTomasz Wasilczyk        case Result::TIMEOUT:
202c62e38d573b647ff4d3293d07dbdce3440a6b739Tomasz Wasilczyk            ThrowParcelableRuntimeException(env, "Result::TIMEOUT (unexpected here)");
2038b6db4f2eb02f231dd8006debbc1e1be1181178aTomasz Wasilczyk            return true;
2048b6db4f2eb02f231dd8006debbc1e1be1181178aTomasz Wasilczyk        default:
205c62e38d573b647ff4d3293d07dbdce3440a6b739Tomasz Wasilczyk            ThrowParcelableRuntimeException(env, "Unknown failure, result: "
206c62e38d573b647ff4d3293d07dbdce3440a6b739Tomasz Wasilczyk                    + std::to_string(static_cast<int32_t>(halResult)));
2078b6db4f2eb02f231dd8006debbc1e1be1181178aTomasz Wasilczyk            return true;
2088b6db4f2eb02f231dd8006debbc1e1be1181178aTomasz Wasilczyk    }
2098b6db4f2eb02f231dd8006debbc1e1be1181178aTomasz Wasilczyk}
2108b6db4f2eb02f231dd8006debbc1e1be1181178aTomasz Wasilczyk
211d3d53f669268fe8dd15f16abbd0504f7b9e38405Tomasz Wasilczykbool __ThrowIfFailed(JNIEnv *env, const ProgramListResult halResult) {
212d3d53f669268fe8dd15f16abbd0504f7b9e38405Tomasz Wasilczyk    switch (halResult) {
213d3d53f669268fe8dd15f16abbd0504f7b9e38405Tomasz Wasilczyk        case ProgramListResult::NOT_READY:
214d3d53f669268fe8dd15f16abbd0504f7b9e38405Tomasz Wasilczyk            jniThrowException(env, "java/lang/IllegalStateException", "Scan is in progress");
215d3d53f669268fe8dd15f16abbd0504f7b9e38405Tomasz Wasilczyk            return true;
216d3d53f669268fe8dd15f16abbd0504f7b9e38405Tomasz Wasilczyk        case ProgramListResult::NOT_STARTED:
217d3d53f669268fe8dd15f16abbd0504f7b9e38405Tomasz Wasilczyk            jniThrowException(env, "java/lang/IllegalStateException", "Scan has not been started");
218d3d53f669268fe8dd15f16abbd0504f7b9e38405Tomasz Wasilczyk            return true;
219d3d53f669268fe8dd15f16abbd0504f7b9e38405Tomasz Wasilczyk        case ProgramListResult::UNAVAILABLE:
220c62e38d573b647ff4d3293d07dbdce3440a6b739Tomasz Wasilczyk            ThrowParcelableRuntimeException(env,
221c62e38d573b647ff4d3293d07dbdce3440a6b739Tomasz Wasilczyk                    "ProgramListResult::UNAVAILABLE (unexpected here)");
222d3d53f669268fe8dd15f16abbd0504f7b9e38405Tomasz Wasilczyk            return true;
223d3d53f669268fe8dd15f16abbd0504f7b9e38405Tomasz Wasilczyk        default:
224d3d53f669268fe8dd15f16abbd0504f7b9e38405Tomasz Wasilczyk            return __ThrowIfFailed(env, static_cast<Result>(halResult));
225d3d53f669268fe8dd15f16abbd0504f7b9e38405Tomasz Wasilczyk    }
22637d986d17d0210706be907ce9119b711eeaca235Tomasz Wasilczyk}
22737d986d17d0210706be907ce9119b711eeaca235Tomasz Wasilczyk
228c62e38d573b647ff4d3293d07dbdce3440a6b739Tomasz Wasilczykvoid ThrowParcelableRuntimeException(JNIEnv *env, const std::string& msg) {
229cc0b479479d66f23ea791b55deacc453c0285322Tomasz Wasilczyk    auto jMsg = make_javastr(env, msg);
230cc0b479479d66f23ea791b55deacc453c0285322Tomasz Wasilczyk    auto runtimeExc = make_javaref(env, env->NewObject(gjni.RuntimeException.clazz,
231c62e38d573b647ff4d3293d07dbdce3440a6b739Tomasz Wasilczyk            gjni.RuntimeException.cstor, jMsg.get()));
232cc0b479479d66f23ea791b55deacc453c0285322Tomasz Wasilczyk    auto parcelableExc = make_javaref(env, env->NewObject(gjni.ParcelableException.clazz,
233c62e38d573b647ff4d3293d07dbdce3440a6b739Tomasz Wasilczyk            gjni.ParcelableException.cstor, runtimeExc.get()));
234c62e38d573b647ff4d3293d07dbdce3440a6b739Tomasz Wasilczyk
235c62e38d573b647ff4d3293d07dbdce3440a6b739Tomasz Wasilczyk    auto res = env->Throw(static_cast<jthrowable>(parcelableExc.get()));
236c62e38d573b647ff4d3293d07dbdce3440a6b739Tomasz Wasilczyk    ALOGE_IF(res != JNI_OK, "Couldn't throw parcelable runtime exception");
237c62e38d573b647ff4d3293d07dbdce3440a6b739Tomasz Wasilczyk}
238c62e38d573b647ff4d3293d07dbdce3440a6b739Tomasz Wasilczyk
23954587ced033aca263d05e784a038cc717a1d2f3cTomasz Wasilczykstatic JavaRef<jintArray> ArrayFromHal(JNIEnv *env, const hidl_vec<uint32_t>& vec) {
24054587ced033aca263d05e784a038cc717a1d2f3cTomasz Wasilczyk    auto jArr = make_javaref(env, env->NewIntArray(vec.size()));
24154587ced033aca263d05e784a038cc717a1d2f3cTomasz Wasilczyk    auto jArrElements = env->GetIntArrayElements(jArr.get(), nullptr);
24254587ced033aca263d05e784a038cc717a1d2f3cTomasz Wasilczyk    for (size_t i = 0; i < vec.size(); i++) {
24354587ced033aca263d05e784a038cc717a1d2f3cTomasz Wasilczyk        jArrElements[i] = vec[i];
24454587ced033aca263d05e784a038cc717a1d2f3cTomasz Wasilczyk    }
24554587ced033aca263d05e784a038cc717a1d2f3cTomasz Wasilczyk    env->ReleaseIntArrayElements(jArr.get(), jArrElements, 0);
24654587ced033aca263d05e784a038cc717a1d2f3cTomasz Wasilczyk    return jArr;
24754587ced033aca263d05e784a038cc717a1d2f3cTomasz Wasilczyk}
24854587ced033aca263d05e784a038cc717a1d2f3cTomasz Wasilczyk
24954587ced033aca263d05e784a038cc717a1d2f3cTomasz Wasilczykstatic JavaRef<jlongArray> ArrayFromHal(JNIEnv *env, const hidl_vec<uint64_t>& vec) {
25054587ced033aca263d05e784a038cc717a1d2f3cTomasz Wasilczyk    auto jArr = make_javaref(env, env->NewLongArray(vec.size()));
25154587ced033aca263d05e784a038cc717a1d2f3cTomasz Wasilczyk    auto jArrElements = env->GetLongArrayElements(jArr.get(), nullptr);
25254587ced033aca263d05e784a038cc717a1d2f3cTomasz Wasilczyk    for (size_t i = 0; i < vec.size(); i++) {
25354587ced033aca263d05e784a038cc717a1d2f3cTomasz Wasilczyk        jArrElements[i] = vec[i];
25454587ced033aca263d05e784a038cc717a1d2f3cTomasz Wasilczyk    }
25554587ced033aca263d05e784a038cc717a1d2f3cTomasz Wasilczyk    env->ReleaseLongArrayElements(jArr.get(), jArrElements, 0);
25654587ced033aca263d05e784a038cc717a1d2f3cTomasz Wasilczyk    return jArr;
25754587ced033aca263d05e784a038cc717a1d2f3cTomasz Wasilczyk}
25854587ced033aca263d05e784a038cc717a1d2f3cTomasz Wasilczyk
25954587ced033aca263d05e784a038cc717a1d2f3cTomasz Wasilczyktemplate <typename T>
26054587ced033aca263d05e784a038cc717a1d2f3cTomasz Wasilczykstatic JavaRef<jobjectArray> ArrayFromHal(JNIEnv *env, const hidl_vec<T>& vec,
26154587ced033aca263d05e784a038cc717a1d2f3cTomasz Wasilczyk        jclass jElementClass, std::function<JavaRef<jobject>(JNIEnv*, const T&)> converter) {
26254587ced033aca263d05e784a038cc717a1d2f3cTomasz Wasilczyk    auto jArr = make_javaref(env, env->NewObjectArray(vec.size(), jElementClass, nullptr));
26354587ced033aca263d05e784a038cc717a1d2f3cTomasz Wasilczyk    for (size_t i = 0; i < vec.size(); i++) {
26454587ced033aca263d05e784a038cc717a1d2f3cTomasz Wasilczyk        auto jElement = converter(env, vec[i]);
26554587ced033aca263d05e784a038cc717a1d2f3cTomasz Wasilczyk        env->SetObjectArrayElement(jArr.get(), i, jElement.get());
26654587ced033aca263d05e784a038cc717a1d2f3cTomasz Wasilczyk    }
26754587ced033aca263d05e784a038cc717a1d2f3cTomasz Wasilczyk    return jArr;
26854587ced033aca263d05e784a038cc717a1d2f3cTomasz Wasilczyk}
26954587ced033aca263d05e784a038cc717a1d2f3cTomasz Wasilczyk
27054587ced033aca263d05e784a038cc717a1d2f3cTomasz Wasilczyktemplate <typename T>
27154587ced033aca263d05e784a038cc717a1d2f3cTomasz Wasilczykstatic JavaRef<jobjectArray> ArrayFromHal(JNIEnv *env, const hidl_vec<T>& vec,
27254587ced033aca263d05e784a038cc717a1d2f3cTomasz Wasilczyk        jclass jElementClass, JavaRef<jobject>(*converter)(JNIEnv*, const T&)) {
27354587ced033aca263d05e784a038cc717a1d2f3cTomasz Wasilczyk    return ArrayFromHal(env, vec, jElementClass,
27454587ced033aca263d05e784a038cc717a1d2f3cTomasz Wasilczyk            std::function<JavaRef<jobject>(JNIEnv*, const T&)>(converter));
27554587ced033aca263d05e784a038cc717a1d2f3cTomasz Wasilczyk}
27654587ced033aca263d05e784a038cc717a1d2f3cTomasz Wasilczyk
2770f1776d08b43f5f71a9f89b6a4f1838df4d3d744Tomasz Wasilczykstatic std::string StringFromJava(JNIEnv *env, JavaRef<jstring> &jStr) {
2788e932c61db78e7a04f6a98e070089f10abdccf1aTomasz Wasilczyk    if (jStr == nullptr) return {};
2798e932c61db78e7a04f6a98e070089f10abdccf1aTomasz Wasilczyk    auto cstr = env->GetStringUTFChars(jStr.get(), nullptr);
2800f1776d08b43f5f71a9f89b6a4f1838df4d3d744Tomasz Wasilczyk    std::string str(cstr);
2810f1776d08b43f5f71a9f89b6a4f1838df4d3d744Tomasz Wasilczyk    env->ReleaseStringUTFChars(jStr.get(), cstr);
2820f1776d08b43f5f71a9f89b6a4f1838df4d3d744Tomasz Wasilczyk    return str;
2830f1776d08b43f5f71a9f89b6a4f1838df4d3d744Tomasz Wasilczyk}
2840f1776d08b43f5f71a9f89b6a4f1838df4d3d744Tomasz Wasilczyk
2858e932c61db78e7a04f6a98e070089f10abdccf1aTomasz Wasilczykhidl_vec<hidl_string> StringListToHal(JNIEnv *env, jobject jList) {
2868e932c61db78e7a04f6a98e070089f10abdccf1aTomasz Wasilczyk    auto len = (jList == nullptr) ? 0 : env->CallIntMethod(jList, gjni.List.size);
2878e932c61db78e7a04f6a98e070089f10abdccf1aTomasz Wasilczyk    hidl_vec<hidl_string> list(len);
2888e932c61db78e7a04f6a98e070089f10abdccf1aTomasz Wasilczyk
2898e932c61db78e7a04f6a98e070089f10abdccf1aTomasz Wasilczyk    for (decltype(len) i = 0; i < len; i++) {
2908e932c61db78e7a04f6a98e070089f10abdccf1aTomasz Wasilczyk        auto jString = make_javaref(env, CastToString(env, env->CallObjectMethod(
2918e932c61db78e7a04f6a98e070089f10abdccf1aTomasz Wasilczyk                jList, gjni.List.get, i)));
2928e932c61db78e7a04f6a98e070089f10abdccf1aTomasz Wasilczyk        list[i] = StringFromJava(env, jString);
2938e932c61db78e7a04f6a98e070089f10abdccf1aTomasz Wasilczyk    }
2948e932c61db78e7a04f6a98e070089f10abdccf1aTomasz Wasilczyk
2958e932c61db78e7a04f6a98e070089f10abdccf1aTomasz Wasilczyk    return list;
2968e932c61db78e7a04f6a98e070089f10abdccf1aTomasz Wasilczyk}
2978e932c61db78e7a04f6a98e070089f10abdccf1aTomasz Wasilczyk
2980f1776d08b43f5f71a9f89b6a4f1838df4d3d744Tomasz WasilczykJavaRef<jobject> VendorInfoFromHal(JNIEnv *env, const hidl_vec<VendorKeyValue> &info) {
2990f1776d08b43f5f71a9f89b6a4f1838df4d3d744Tomasz Wasilczyk    ALOGV("%s(%s)", __func__, toString(info).substr(0, 100).c_str());
3000f1776d08b43f5f71a9f89b6a4f1838df4d3d744Tomasz Wasilczyk
3010f1776d08b43f5f71a9f89b6a4f1838df4d3d744Tomasz Wasilczyk    auto jInfo = make_javaref(env, env->NewObject(gjni.HashMap.clazz, gjni.HashMap.cstor));
3020f1776d08b43f5f71a9f89b6a4f1838df4d3d744Tomasz Wasilczyk
3030f1776d08b43f5f71a9f89b6a4f1838df4d3d744Tomasz Wasilczyk    for (auto&& entry : info) {
3040f1776d08b43f5f71a9f89b6a4f1838df4d3d744Tomasz Wasilczyk        auto jKey = make_javastr(env, entry.key);
3050f1776d08b43f5f71a9f89b6a4f1838df4d3d744Tomasz Wasilczyk        auto jValue = make_javastr(env, entry.value);
3060f1776d08b43f5f71a9f89b6a4f1838df4d3d744Tomasz Wasilczyk        env->CallObjectMethod(jInfo.get(), gjni.Map.put, jKey.get(), jValue.get());
3070f1776d08b43f5f71a9f89b6a4f1838df4d3d744Tomasz Wasilczyk    }
3080f1776d08b43f5f71a9f89b6a4f1838df4d3d744Tomasz Wasilczyk
3090f1776d08b43f5f71a9f89b6a4f1838df4d3d744Tomasz Wasilczyk    return jInfo;
3100f1776d08b43f5f71a9f89b6a4f1838df4d3d744Tomasz Wasilczyk}
3110f1776d08b43f5f71a9f89b6a4f1838df4d3d744Tomasz Wasilczyk
3120f1776d08b43f5f71a9f89b6a4f1838df4d3d744Tomasz Wasilczykhidl_vec<VendorKeyValue> VendorInfoToHal(JNIEnv *env, jobject jInfo) {
3130f1776d08b43f5f71a9f89b6a4f1838df4d3d744Tomasz Wasilczyk    ALOGV("%s", __func__);
3140f1776d08b43f5f71a9f89b6a4f1838df4d3d744Tomasz Wasilczyk
3150f1776d08b43f5f71a9f89b6a4f1838df4d3d744Tomasz Wasilczyk    auto jInfoArr = make_javaref(env, static_cast<jobjectArray>(env->CallStaticObjectMethod(
3160f1776d08b43f5f71a9f89b6a4f1838df4d3d744Tomasz Wasilczyk            gjni.Convert.clazz, gjni.Convert.stringMapToNative, jInfo)));
3178e932c61db78e7a04f6a98e070089f10abdccf1aTomasz Wasilczyk    if (jInfoArr == nullptr) {
3188e932c61db78e7a04f6a98e070089f10abdccf1aTomasz Wasilczyk        ALOGE("Converted array is null");
3198e932c61db78e7a04f6a98e070089f10abdccf1aTomasz Wasilczyk        return {};
3208e932c61db78e7a04f6a98e070089f10abdccf1aTomasz Wasilczyk    }
3210f1776d08b43f5f71a9f89b6a4f1838df4d3d744Tomasz Wasilczyk
3220f1776d08b43f5f71a9f89b6a4f1838df4d3d744Tomasz Wasilczyk    auto len = env->GetArrayLength(jInfoArr.get());
3230f1776d08b43f5f71a9f89b6a4f1838df4d3d744Tomasz Wasilczyk    hidl_vec<VendorKeyValue> vec;
3240f1776d08b43f5f71a9f89b6a4f1838df4d3d744Tomasz Wasilczyk    vec.resize(len);
3250f1776d08b43f5f71a9f89b6a4f1838df4d3d744Tomasz Wasilczyk
3260f1776d08b43f5f71a9f89b6a4f1838df4d3d744Tomasz Wasilczyk    for (jsize i = 0; i < len; i++) {
3270f1776d08b43f5f71a9f89b6a4f1838df4d3d744Tomasz Wasilczyk        auto entry = make_javaref(env, static_cast<jobjectArray>(
3280f1776d08b43f5f71a9f89b6a4f1838df4d3d744Tomasz Wasilczyk                env->GetObjectArrayElement(jInfoArr.get(), i)));
3290f1776d08b43f5f71a9f89b6a4f1838df4d3d744Tomasz Wasilczyk        auto jKey = make_javaref(env, static_cast<jstring>(
3300f1776d08b43f5f71a9f89b6a4f1838df4d3d744Tomasz Wasilczyk                env->GetObjectArrayElement(entry.get(), 0)));
3310f1776d08b43f5f71a9f89b6a4f1838df4d3d744Tomasz Wasilczyk        auto jValue = make_javaref(env, static_cast<jstring>(
3320f1776d08b43f5f71a9f89b6a4f1838df4d3d744Tomasz Wasilczyk                env->GetObjectArrayElement(entry.get(), 1)));
3330f1776d08b43f5f71a9f89b6a4f1838df4d3d744Tomasz Wasilczyk        auto key = StringFromJava(env, jKey);
3340f1776d08b43f5f71a9f89b6a4f1838df4d3d744Tomasz Wasilczyk        auto value = StringFromJava(env, jValue);
3350f1776d08b43f5f71a9f89b6a4f1838df4d3d744Tomasz Wasilczyk        vec[i] = { key, value };
3360f1776d08b43f5f71a9f89b6a4f1838df4d3d744Tomasz Wasilczyk    }
3370f1776d08b43f5f71a9f89b6a4f1838df4d3d744Tomasz Wasilczyk
3380f1776d08b43f5f71a9f89b6a4f1838df4d3d744Tomasz Wasilczyk    return vec;
3390f1776d08b43f5f71a9f89b6a4f1838df4d3d744Tomasz Wasilczyk}
3400f1776d08b43f5f71a9f89b6a4f1838df4d3d744Tomasz Wasilczyk
34131c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczykstatic Rds RdsForRegion(bool rds, Region region) {
34231c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk    if (!rds) return Rds::NONE;
34331c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk
34431c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk    switch(region) {
34531c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk        case Region::ITU_1:
34631c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk        case Region::OIRT:
34731c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk        case Region::JAPAN:
34831c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk        case Region::KOREA:
34931c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk            return Rds::WORLD;
35031c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk        case Region::ITU_2:
35131c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk            return Rds::US;
35231c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk        default:
35331c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk            ALOGE("Unexpected region: %d", region);
35431c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk            return Rds::NONE;
35531c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk    }
35631c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk}
35731c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk
35831c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczykstatic Deemphasis DeemphasisForRegion(Region region) {
35931c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk    switch(region) {
36031c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk        case Region::KOREA:
36131c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk        case Region::ITU_2:
36231c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk            return Deemphasis::D75;
36331c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk        case Region::ITU_1:
36431c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk        case Region::OIRT:
36531c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk        case Region::JAPAN:
36631c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk            return Deemphasis::D50;
36731c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk        default:
36831c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk            ALOGE("Unexpected region: %d", region);
36931c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk            return Deemphasis::D50;
37031c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk    }
37131c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk}
37231c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk
373d15c9dfd8b87ff54b2e5304b941c2e62f7e93dd6Tomasz Wasilczykstatic JavaRef<jobject> ModulePropertiesFromHal(JNIEnv *env, const V1_0::Properties &prop10,
374d15c9dfd8b87ff54b2e5304b941c2e62f7e93dd6Tomasz Wasilczyk        const V1_1::Properties *prop11, jint moduleId, const std::string& serviceName) {
375e3e8f90c74a4ed4a4463205d2f36ae5f9bc03ea4Tomasz Wasilczyk    ALOGV("%s", __func__);
37654587ced033aca263d05e784a038cc717a1d2f3cTomasz Wasilczyk    using namespace std::placeholders;
377d15c9dfd8b87ff54b2e5304b941c2e62f7e93dd6Tomasz Wasilczyk
378d15c9dfd8b87ff54b2e5304b941c2e62f7e93dd6Tomasz Wasilczyk    auto jServiceName = make_javastr(env, serviceName);
379d15c9dfd8b87ff54b2e5304b941c2e62f7e93dd6Tomasz Wasilczyk    auto jImplementor = make_javastr(env, prop10.implementor);
380d15c9dfd8b87ff54b2e5304b941c2e62f7e93dd6Tomasz Wasilczyk    auto jProduct = make_javastr(env, prop10.product);
381d15c9dfd8b87ff54b2e5304b941c2e62f7e93dd6Tomasz Wasilczyk    auto jVersion = make_javastr(env, prop10.version);
382d15c9dfd8b87ff54b2e5304b941c2e62f7e93dd6Tomasz Wasilczyk    auto jSerial = make_javastr(env, prop10.serial);
38327926edc3b737823bd6bc3146b6e73a69f8dfe3aTomasz Wasilczyk    constexpr bool isInitializationRequired = true;
384d15c9dfd8b87ff54b2e5304b941c2e62f7e93dd6Tomasz Wasilczyk    bool isBgScanSupported = prop11 ? prop11->supportsBackgroundScanning : false;
3850f1776d08b43f5f71a9f89b6a4f1838df4d3d744Tomasz Wasilczyk    auto jVendorInfo = prop11 ? VendorInfoFromHal(env, prop11->vendorInfo) : nullptr;
386a6f1523532c08387e4ecd0282460321b50aecf0eTomasz Wasilczyk
387a6f1523532c08387e4ecd0282460321b50aecf0eTomasz Wasilczyk    auto regionalBands = regions::mapRegions(prop10.bands);
388a6f1523532c08387e4ecd0282460321b50aecf0eTomasz Wasilczyk    auto jBands = ArrayFromHal<RegionalBandConfig>(env, regionalBands,
389a6f1523532c08387e4ecd0282460321b50aecf0eTomasz Wasilczyk            gjni.BandDescriptor.clazz, BandDescriptorFromHal);
39054587ced033aca263d05e784a038cc717a1d2f3cTomasz Wasilczyk    auto jSupportedProgramTypes =
39154587ced033aca263d05e784a038cc717a1d2f3cTomasz Wasilczyk            prop11 ? ArrayFromHal(env, prop11->supportedProgramTypes) : nullptr;
39254587ced033aca263d05e784a038cc717a1d2f3cTomasz Wasilczyk    auto jSupportedIdentifierTypes =
39354587ced033aca263d05e784a038cc717a1d2f3cTomasz Wasilczyk            prop11 ? ArrayFromHal(env, prop11->supportedIdentifierTypes) : nullptr;
394d15c9dfd8b87ff54b2e5304b941c2e62f7e93dd6Tomasz Wasilczyk
395d15c9dfd8b87ff54b2e5304b941c2e62f7e93dd6Tomasz Wasilczyk    return make_javaref(env, env->NewObject(gjni.ModuleProperties.clazz,
396d15c9dfd8b87ff54b2e5304b941c2e62f7e93dd6Tomasz Wasilczyk            gjni.ModuleProperties.cstor, moduleId, jServiceName.get(), prop10.classId,
397d15c9dfd8b87ff54b2e5304b941c2e62f7e93dd6Tomasz Wasilczyk            jImplementor.get(), jProduct.get(), jVersion.get(), jSerial.get(), prop10.numTuners,
39827926edc3b737823bd6bc3146b6e73a69f8dfe3aTomasz Wasilczyk            prop10.numAudioSources, isInitializationRequired, prop10.supportsCapture, jBands.get(),
39927926edc3b737823bd6bc3146b6e73a69f8dfe3aTomasz Wasilczyk            isBgScanSupported, jSupportedProgramTypes.get(), jSupportedIdentifierTypes.get(),
40027926edc3b737823bd6bc3146b6e73a69f8dfe3aTomasz Wasilczyk            nullptr, jVendorInfo.get()));
401d15c9dfd8b87ff54b2e5304b941c2e62f7e93dd6Tomasz Wasilczyk}
402d15c9dfd8b87ff54b2e5304b941c2e62f7e93dd6Tomasz Wasilczyk
403d15c9dfd8b87ff54b2e5304b941c2e62f7e93dd6Tomasz WasilczykJavaRef<jobject> ModulePropertiesFromHal(JNIEnv *env, const V1_0::Properties &properties,
404d15c9dfd8b87ff54b2e5304b941c2e62f7e93dd6Tomasz Wasilczyk        jint moduleId, const std::string& serviceName) {
405d15c9dfd8b87ff54b2e5304b941c2e62f7e93dd6Tomasz Wasilczyk    return ModulePropertiesFromHal(env, properties, nullptr, moduleId, serviceName);
406d15c9dfd8b87ff54b2e5304b941c2e62f7e93dd6Tomasz Wasilczyk}
407d15c9dfd8b87ff54b2e5304b941c2e62f7e93dd6Tomasz Wasilczyk
408d15c9dfd8b87ff54b2e5304b941c2e62f7e93dd6Tomasz WasilczykJavaRef<jobject> ModulePropertiesFromHal(JNIEnv *env, const V1_1::Properties &properties,
409d15c9dfd8b87ff54b2e5304b941c2e62f7e93dd6Tomasz Wasilczyk        jint moduleId, const std::string& serviceName) {
410d15c9dfd8b87ff54b2e5304b941c2e62f7e93dd6Tomasz Wasilczyk    return ModulePropertiesFromHal(env, properties.base, &properties, moduleId, serviceName);
411d15c9dfd8b87ff54b2e5304b941c2e62f7e93dd6Tomasz Wasilczyk}
412d15c9dfd8b87ff54b2e5304b941c2e62f7e93dd6Tomasz Wasilczyk
413a6f1523532c08387e4ecd0282460321b50aecf0eTomasz Wasilczykstatic JavaRef<jobject> BandDescriptorFromHal(JNIEnv *env, const RegionalBandConfig &config) {
414a6f1523532c08387e4ecd0282460321b50aecf0eTomasz Wasilczyk    return BandDescriptorFromHal(env, config.bandConfig, config.region);
415a6f1523532c08387e4ecd0282460321b50aecf0eTomasz Wasilczyk}
416a6f1523532c08387e4ecd0282460321b50aecf0eTomasz Wasilczyk
417d15c9dfd8b87ff54b2e5304b941c2e62f7e93dd6Tomasz Wasilczykstatic JavaRef<jobject> BandDescriptorFromHal(JNIEnv *env, const V1_0::BandConfig &config, Region region) {
418e3e8f90c74a4ed4a4463205d2f36ae5f9bc03ea4Tomasz Wasilczyk    ALOGV("%s", __func__);
41931c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk
42031c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk    jint spacing = config.spacings.size() > 0 ? config.spacings[0] : 0;
421a6f1523532c08387e4ecd0282460321b50aecf0eTomasz Wasilczyk    ALOGW_IF(config.spacings.size() > 1, "Multiple spacings - not a regional config");
42231c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk    ALOGW_IF(config.spacings.size() == 0, "No channel spacing specified");
42331c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk
424a6f1523532c08387e4ecd0282460321b50aecf0eTomasz Wasilczyk    if (utils::isFm(config.type)) {
425a6f1523532c08387e4ecd0282460321b50aecf0eTomasz Wasilczyk        auto& fm = config.ext.fm;
426a6f1523532c08387e4ecd0282460321b50aecf0eTomasz Wasilczyk        return make_javaref(env, env->NewObject(
427a6f1523532c08387e4ecd0282460321b50aecf0eTomasz Wasilczyk                gjni.FmBandDescriptor.clazz, gjni.FmBandDescriptor.cstor,
428a6f1523532c08387e4ecd0282460321b50aecf0eTomasz Wasilczyk                region, config.type, config.lowerLimit, config.upperLimit, spacing,
429a6f1523532c08387e4ecd0282460321b50aecf0eTomasz Wasilczyk                fm.stereo, fm.rds != Rds::NONE, fm.ta, fm.af, fm.ea));
430a6f1523532c08387e4ecd0282460321b50aecf0eTomasz Wasilczyk    } else if (utils::isAm(config.type)) {
431a6f1523532c08387e4ecd0282460321b50aecf0eTomasz Wasilczyk        auto& am = config.ext.am;
432a6f1523532c08387e4ecd0282460321b50aecf0eTomasz Wasilczyk        return make_javaref(env, env->NewObject(
433a6f1523532c08387e4ecd0282460321b50aecf0eTomasz Wasilczyk                gjni.AmBandDescriptor.clazz, gjni.AmBandDescriptor.cstor,
434a6f1523532c08387e4ecd0282460321b50aecf0eTomasz Wasilczyk                region, config.type, config.lowerLimit, config.upperLimit, spacing, am.stereo));
435a6f1523532c08387e4ecd0282460321b50aecf0eTomasz Wasilczyk    } else {
436a6f1523532c08387e4ecd0282460321b50aecf0eTomasz Wasilczyk        ALOGE("Unsupported band type: %d", config.type);
437a6f1523532c08387e4ecd0282460321b50aecf0eTomasz Wasilczyk        return nullptr;
43831c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk    }
43931c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk}
44031c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk
441d15c9dfd8b87ff54b2e5304b941c2e62f7e93dd6Tomasz WasilczykJavaRef<jobject> BandConfigFromHal(JNIEnv *env, const V1_0::BandConfig &config, Region region) {
442e3e8f90c74a4ed4a4463205d2f36ae5f9bc03ea4Tomasz Wasilczyk    ALOGV("%s", __func__);
443d15c9dfd8b87ff54b2e5304b941c2e62f7e93dd6Tomasz Wasilczyk
444d15c9dfd8b87ff54b2e5304b941c2e62f7e93dd6Tomasz Wasilczyk    auto descriptor = BandDescriptorFromHal(env, config, region);
445d15c9dfd8b87ff54b2e5304b941c2e62f7e93dd6Tomasz Wasilczyk    if (descriptor == nullptr) return nullptr;
446d15c9dfd8b87ff54b2e5304b941c2e62f7e93dd6Tomasz Wasilczyk
447a6f1523532c08387e4ecd0282460321b50aecf0eTomasz Wasilczyk    if (utils::isFm(config.type)) {
448a6f1523532c08387e4ecd0282460321b50aecf0eTomasz Wasilczyk        return make_javaref(env, env->NewObject(
449a6f1523532c08387e4ecd0282460321b50aecf0eTomasz Wasilczyk                gjni.FmBandConfig.clazz, gjni.FmBandConfig.cstor, descriptor.get()));
450a6f1523532c08387e4ecd0282460321b50aecf0eTomasz Wasilczyk    } else if (utils::isAm(config.type)) {
451a6f1523532c08387e4ecd0282460321b50aecf0eTomasz Wasilczyk        return make_javaref(env, env->NewObject(
452a6f1523532c08387e4ecd0282460321b50aecf0eTomasz Wasilczyk                gjni.AmBandConfig.clazz, gjni.AmBandConfig.cstor, descriptor.get()));
453a6f1523532c08387e4ecd0282460321b50aecf0eTomasz Wasilczyk    } else {
454a6f1523532c08387e4ecd0282460321b50aecf0eTomasz Wasilczyk        ALOGE("Unsupported band type: %d", config.type);
455a6f1523532c08387e4ecd0282460321b50aecf0eTomasz Wasilczyk        return nullptr;
456d15c9dfd8b87ff54b2e5304b941c2e62f7e93dd6Tomasz Wasilczyk    }
457d15c9dfd8b87ff54b2e5304b941c2e62f7e93dd6Tomasz Wasilczyk}
458d15c9dfd8b87ff54b2e5304b941c2e62f7e93dd6Tomasz Wasilczyk
45931c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz WasilczykV1_0::BandConfig BandConfigToHal(JNIEnv *env, jobject jConfig, Region &region) {
460e3e8f90c74a4ed4a4463205d2f36ae5f9bc03ea4Tomasz Wasilczyk    ALOGV("%s", __func__);
46131c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk    auto jDescriptor = env->GetObjectField(jConfig, gjni.BandConfig.descriptor);
46231c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk    if (jDescriptor == nullptr) {
46331c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk        ALOGE("Descriptor is missing");
46431c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk        return {};
46531c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk    }
46631c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk
46731c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk    region = static_cast<Region>(env->GetIntField(jDescriptor, gjni.BandDescriptor.region));
46831c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk
46931c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk    V1_0::BandConfig config = {};
47031c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk    config.type = static_cast<Band>(env->GetIntField(jDescriptor, gjni.BandDescriptor.type));
47131c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk    config.antennaConnected = false;  // just don't set it
47231c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk    config.lowerLimit = env->GetIntField(jDescriptor, gjni.BandDescriptor.lowerLimit);
47331c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk    config.upperLimit = env->GetIntField(jDescriptor, gjni.BandDescriptor.upperLimit);
47431c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk    config.spacings = hidl_vec<uint32_t>({
47531c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk        static_cast<uint32_t>(env->GetIntField(jDescriptor, gjni.BandDescriptor.spacing))
47631c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk    });
47731c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk
47831c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk    if (env->IsInstanceOf(jConfig, gjni.FmBandConfig.clazz)) {
47931c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk        auto& fm = config.ext.fm;
48031c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk        fm.deemphasis = DeemphasisForRegion(region);
48131c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk        fm.stereo = env->GetBooleanField(jConfig, gjni.FmBandConfig.stereo);
48231c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk        fm.rds = RdsForRegion(env->GetBooleanField(jConfig, gjni.FmBandConfig.rds), region);
48331c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk        fm.ta = env->GetBooleanField(jConfig, gjni.FmBandConfig.ta);
48431c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk        fm.af = env->GetBooleanField(jConfig, gjni.FmBandConfig.af);
48531c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk        fm.ea = env->GetBooleanField(jConfig, gjni.FmBandConfig.ea);
48631c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk    } else if (env->IsInstanceOf(jConfig, gjni.AmBandConfig.clazz)) {
48731c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk        auto& am = config.ext.am;
48831c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk        am.stereo = env->GetBooleanField(jConfig, gjni.AmBandConfig.stereo);
48931c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk    } else {
49031c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk        ALOGE("Unexpected band config type");
49131c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk        return {};
49231c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk    }
49331c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk
49431c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk    return config;
49531c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk}
49631c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk
4972383793eaee223546985ee12c2f35a3445e34b1cTomasz WasilczykDirection DirectionToHal(bool directionDown) {
4982383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk    return directionDown ? Direction::DOWN : Direction::UP;
4992383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk}
5002383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk
501c9a1ac78192e773d32462a3de899c7522c55ededTomasz WasilczykJavaRef<jobject> MetadataFromHal(JNIEnv *env, const hidl_vec<V1_0::MetaData> &metadata) {
502e3e8f90c74a4ed4a4463205d2f36ae5f9bc03ea4Tomasz Wasilczyk    ALOGV("%s", __func__);
5032383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk    if (metadata.size() == 0) return nullptr;
5042383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk
505cc0b479479d66f23ea791b55deacc453c0285322Tomasz Wasilczyk    auto jMetadata = make_javaref(env, env->NewObject(
506cc0b479479d66f23ea791b55deacc453c0285322Tomasz Wasilczyk            gjni.RadioMetadata.clazz, gjni.RadioMetadata.cstor));
5072383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk
5082383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk    for (auto& item : metadata) {
5092383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk        jint key = static_cast<jint>(item.key);
5102383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk        jint status = 0;
5112383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk        switch (item.type) {
5122383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk            case MetadataType::INT:
5132383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk                status = env->CallIntMethod(jMetadata.get(), gjni.RadioMetadata.putIntFromNative,
5142383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk                        key, item.intValue);
5152383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk                break;
5162383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk            case MetadataType::TEXT: {
517cc0b479479d66f23ea791b55deacc453c0285322Tomasz Wasilczyk                auto value = make_javastr(env, item.stringValue);
5182383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk                status = env->CallIntMethod(jMetadata.get(), gjni.RadioMetadata.putStringFromNative,
5192383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk                        key, value.get());
5202383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk                break;
5212383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk            }
5222383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk            case MetadataType::RAW: {
5232383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk                auto len = item.rawValue.size();
5242383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk                if (len == 0) break;
525cc0b479479d66f23ea791b55deacc453c0285322Tomasz Wasilczyk                auto value = make_javaref(env, env->NewByteArray(len));
5262383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk                if (value == nullptr) {
5272383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk                    ALOGE("Failed to allocate byte array of len %zu", len);
5282383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk                    break;
5292383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk                }
5302383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk                env->SetByteArrayRegion(value.get(), 0, len,
5312383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk                        reinterpret_cast<const jbyte*>(item.rawValue.data()));
5322383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk                status = env->CallIntMethod(jMetadata.get(), gjni.RadioMetadata.putBitmapFromNative,
5332383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk                        key, value.get());
5342383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk                break;
5352383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk            }
5362383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk            case MetadataType::CLOCK:
5372383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk                status = env->CallIntMethod(jMetadata.get(), gjni.RadioMetadata.putClockFromNative,
5382383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk                        key, item.clockValue.utcSecondsSinceEpoch,
5392383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk                        item.clockValue.timezoneOffsetInMinutes);
5402383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk                break;
5412383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk            default:
5422383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk                ALOGW("invalid metadata type %d", item.type);
5432383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk        }
5442383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk        ALOGE_IF(status != 0, "Failed inserting metadata %d (of type %d)", key, item.type);
5452383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk    }
5462383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk
5472383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk    return jMetadata;
5482383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk}
5492383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk
5508cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczykstatic JavaRef<jobject> ProgramIdentifierFromHal(JNIEnv *env, const ProgramIdentifier &id) {
551e3e8f90c74a4ed4a4463205d2f36ae5f9bc03ea4Tomasz Wasilczyk    ALOGV("%s", __func__);
5528cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk    return make_javaref(env, env->NewObject(gjni.ProgramSelector.Identifier.clazz,
5538cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk            gjni.ProgramSelector.Identifier.cstor, id.type, id.value));
5548cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk}
5558cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk
5568cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczykstatic JavaRef<jobject> ProgramSelectorFromHal(JNIEnv *env, const ProgramSelector &selector) {
557e3e8f90c74a4ed4a4463205d2f36ae5f9bc03ea4Tomasz Wasilczyk    ALOGV("%s", __func__);
5588cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk    auto jPrimary = ProgramIdentifierFromHal(env, selector.primaryId);
55954587ced033aca263d05e784a038cc717a1d2f3cTomasz Wasilczyk    auto jSecondary = ArrayFromHal(env, selector.secondaryIds,
56054587ced033aca263d05e784a038cc717a1d2f3cTomasz Wasilczyk            gjni.ProgramSelector.Identifier.clazz, ProgramIdentifierFromHal);
56154587ced033aca263d05e784a038cc717a1d2f3cTomasz Wasilczyk    auto jVendor = ArrayFromHal(env, selector.vendorIds);
5628cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk
5638cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk    return make_javaref(env, env->NewObject(gjni.ProgramSelector.clazz, gjni.ProgramSelector.cstor,
5648cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk            selector.programType, jPrimary.get(), jSecondary.get(), jVendor.get()));
5658cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk}
5668cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk
5678cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczykstatic ProgramIdentifier ProgramIdentifierToHal(JNIEnv *env, jobject jId) {
568e3e8f90c74a4ed4a4463205d2f36ae5f9bc03ea4Tomasz Wasilczyk    ALOGV("%s", __func__);
5698cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk
5708cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk    ProgramIdentifier id = {};
5718cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk    id.type = env->GetIntField(jId, gjni.ProgramSelector.Identifier.type);
5728cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk    id.value = env->GetLongField(jId, gjni.ProgramSelector.Identifier.value);
5738cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk    return id;
5748cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk}
5758cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk
5768cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz WasilczykProgramSelector ProgramSelectorToHal(JNIEnv *env, jobject jSelector) {
577e3e8f90c74a4ed4a4463205d2f36ae5f9bc03ea4Tomasz Wasilczyk    ALOGV("%s", __func__);
5788cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk
5798cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk    ProgramSelector selector = {};
5808cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk
5818cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk    selector.programType = env->GetIntField(jSelector, gjni.ProgramSelector.programType);
5828cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk
5838cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk    auto jPrimary = env->GetObjectField(jSelector, gjni.ProgramSelector.primaryId);
5848cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk    auto jSecondary = reinterpret_cast<jobjectArray>(
5858cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk            env->GetObjectField(jSelector, gjni.ProgramSelector.secondaryIds));
5868cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk    auto jVendor = reinterpret_cast<jlongArray>(
5878cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk            env->GetObjectField(jSelector, gjni.ProgramSelector.vendorIds));
5888cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk
5898cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk    if (jPrimary == nullptr || jSecondary == nullptr || jVendor == nullptr) {
5908cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk        ALOGE("ProgramSelector object is incomplete");
5918cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk        return {};
5928cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk    }
5938cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk
5948cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk    selector.primaryId = ProgramIdentifierToHal(env, jPrimary);
5958cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk    auto count = env->GetArrayLength(jSecondary);
5968cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk    selector.secondaryIds.resize(count);
5978cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk    for (jsize i = 0; i < count; i++) {
5988cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk        auto jId = env->GetObjectArrayElement(jSecondary, i);
5998cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk        selector.secondaryIds[i] = ProgramIdentifierToHal(env, jId);
6008cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk    }
6018cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk
6028cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk    count = env->GetArrayLength(jVendor);
6038cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk    selector.vendorIds.resize(count);
6048cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk    auto jVendorElements = env->GetLongArrayElements(jVendor, nullptr);
6058cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk    for (jint i = 0; i < count; i++) {
6068cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk        selector.vendorIds[i] = jVendorElements[i];
6078cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk    }
6088cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk    env->ReleaseLongArrayElements(jVendor, jVendorElements, 0);
6098cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk
6108cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk    return selector;
6118cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk}
6128cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk
613bad4cd2b174ca979612ac63bb50836491b54b5fbTomasz Wasilczykstatic JavaRef<jobject> ProgramInfoFromHal(JNIEnv *env, const V1_0::ProgramInfo &info10,
6148cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk        const V1_1::ProgramInfo *info11, const ProgramSelector &selector) {
615e3e8f90c74a4ed4a4463205d2f36ae5f9bc03ea4Tomasz Wasilczyk    ALOGV("%s", __func__);
6162383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk
6172383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk    auto jMetadata = MetadataFromHal(env, info10.metadata);
6180f1776d08b43f5f71a9f89b6a4f1838df4d3d744Tomasz Wasilczyk    auto jVendorInfo = info11 ? VendorInfoFromHal(env, info11->vendorInfo) : nullptr;
6198cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk    auto jSelector = ProgramSelectorFromHal(env, selector);
6202383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk
621eab3e5509689cf4dd066f0de5e060967626b3a2aTomasz Wasilczyk    jint flags = info11 ? info11->flags : 0;
622eab3e5509689cf4dd066f0de5e060967626b3a2aTomasz Wasilczyk    if (info10.tuned) flags |= static_cast<jint>(ProgramInfoFlagsExt::TUNED);
623eab3e5509689cf4dd066f0de5e060967626b3a2aTomasz Wasilczyk    if (info10.stereo) flags |= static_cast<jint>(ProgramInfoFlagsExt::STEREO);
624eab3e5509689cf4dd066f0de5e060967626b3a2aTomasz Wasilczyk    // info10.digital is dropped, because it has no equivalent in the new APIs
625eab3e5509689cf4dd066f0de5e060967626b3a2aTomasz Wasilczyk
626cc0b479479d66f23ea791b55deacc453c0285322Tomasz Wasilczyk    return make_javaref(env, env->NewObject(gjni.ProgramInfo.clazz, gjni.ProgramInfo.cstor,
627eab3e5509689cf4dd066f0de5e060967626b3a2aTomasz Wasilczyk            jSelector.get(), nullptr, nullptr, nullptr, flags, info10.signalStrength,
628eab3e5509689cf4dd066f0de5e060967626b3a2aTomasz Wasilczyk            jMetadata.get(), jVendorInfo.get()));
6292383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk}
6302383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk
6318cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz WasilczykJavaRef<jobject> ProgramInfoFromHal(JNIEnv *env, const V1_0::ProgramInfo &info, V1_0::Band band) {
632a6f1523532c08387e4ecd0282460321b50aecf0eTomasz Wasilczyk    auto selector = utils::make_selector(band, info.channel, info.subChannel);
6338cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk    return ProgramInfoFromHal(env, info, nullptr, selector);
634bad4cd2b174ca979612ac63bb50836491b54b5fbTomasz Wasilczyk}
635bad4cd2b174ca979612ac63bb50836491b54b5fbTomasz Wasilczyk
636bad4cd2b174ca979612ac63bb50836491b54b5fbTomasz WasilczykJavaRef<jobject> ProgramInfoFromHal(JNIEnv *env, const V1_1::ProgramInfo &info) {
6378cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk    return ProgramInfoFromHal(env, info.base, &info, info.selector);
638bad4cd2b174ca979612ac63bb50836491b54b5fbTomasz Wasilczyk}
63931c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk
64031c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk} // namespace convert
6416b4b646d9c0fa42973a429dbe78c8919a2772961Tomasz Wasilczyk} // namespace BroadcastRadio
64231c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk} // namespace server
64331c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk
6446b4b646d9c0fa42973a429dbe78c8919a2772961Tomasz Wasilczykvoid register_android_server_broadcastradio_convert(JNIEnv *env) {
6456b4b646d9c0fa42973a429dbe78c8919a2772961Tomasz Wasilczyk    using namespace server::BroadcastRadio::convert;
64631c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk
64731c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk    auto bandConfigClass = FindClassOrDie(env, "android/hardware/radio/RadioManager$BandConfig");
64831c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk    gjni.BandConfig.descriptor = GetFieldIDOrDie(env, bandConfigClass,
64931c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk            "mDescriptor", "Landroid/hardware/radio/RadioManager$BandDescriptor;");
65031c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk
65131c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk    auto fmBandConfigClass = FindClassOrDie(env,
65231c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk            "android/hardware/radio/RadioManager$FmBandConfig");
65331c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk    gjni.FmBandConfig.clazz = MakeGlobalRefOrDie(env, fmBandConfigClass);
65431c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk    gjni.FmBandConfig.cstor = GetMethodIDOrDie(env, fmBandConfigClass,
655d15c9dfd8b87ff54b2e5304b941c2e62f7e93dd6Tomasz Wasilczyk            "<init>", "(Landroid/hardware/radio/RadioManager$FmBandDescriptor;)V");
65631c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk    gjni.FmBandConfig.stereo = GetFieldIDOrDie(env, fmBandConfigClass, "mStereo", "Z");
65731c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk    gjni.FmBandConfig.rds = GetFieldIDOrDie(env, fmBandConfigClass, "mRds", "Z");
65831c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk    gjni.FmBandConfig.ta = GetFieldIDOrDie(env, fmBandConfigClass, "mTa", "Z");
65931c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk    gjni.FmBandConfig.af = GetFieldIDOrDie(env, fmBandConfigClass, "mAf", "Z");
66031c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk    gjni.FmBandConfig.ea = GetFieldIDOrDie(env, fmBandConfigClass, "mEa", "Z");
66131c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk
66231c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk    auto amBandConfigClass = FindClassOrDie(env,
66331c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk            "android/hardware/radio/RadioManager$AmBandConfig");
66431c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk    gjni.AmBandConfig.clazz = MakeGlobalRefOrDie(env, amBandConfigClass);
665d15c9dfd8b87ff54b2e5304b941c2e62f7e93dd6Tomasz Wasilczyk    gjni.AmBandConfig.cstor = GetMethodIDOrDie(env, amBandConfigClass,
666d15c9dfd8b87ff54b2e5304b941c2e62f7e93dd6Tomasz Wasilczyk            "<init>", "(Landroid/hardware/radio/RadioManager$AmBandDescriptor;)V");
66731c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk    gjni.AmBandConfig.stereo = GetFieldIDOrDie(env, amBandConfigClass, "mStereo", "Z");
66831c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk
66931c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk    auto bandDescriptorClass = FindClassOrDie(env,
67031c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk            "android/hardware/radio/RadioManager$BandDescriptor");
671d15c9dfd8b87ff54b2e5304b941c2e62f7e93dd6Tomasz Wasilczyk    gjni.BandDescriptor.clazz = MakeGlobalRefOrDie(env, bandDescriptorClass);
67231c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk    gjni.BandDescriptor.region = GetFieldIDOrDie(env, bandDescriptorClass, "mRegion", "I");
67331c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk    gjni.BandDescriptor.type = GetFieldIDOrDie(env, bandDescriptorClass, "mType", "I");
67431c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk    gjni.BandDescriptor.lowerLimit = GetFieldIDOrDie(env, bandDescriptorClass, "mLowerLimit", "I");
67531c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk    gjni.BandDescriptor.upperLimit = GetFieldIDOrDie(env, bandDescriptorClass, "mUpperLimit", "I");
67631c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk    gjni.BandDescriptor.spacing = GetFieldIDOrDie(env, bandDescriptorClass, "mSpacing", "I");
6772383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk
678d15c9dfd8b87ff54b2e5304b941c2e62f7e93dd6Tomasz Wasilczyk    auto fmBandDescriptorClass = FindClassOrDie(env,
679d15c9dfd8b87ff54b2e5304b941c2e62f7e93dd6Tomasz Wasilczyk            "android/hardware/radio/RadioManager$FmBandDescriptor");
680d15c9dfd8b87ff54b2e5304b941c2e62f7e93dd6Tomasz Wasilczyk    gjni.FmBandDescriptor.clazz = MakeGlobalRefOrDie(env, fmBandDescriptorClass);
681d15c9dfd8b87ff54b2e5304b941c2e62f7e93dd6Tomasz Wasilczyk    gjni.FmBandDescriptor.cstor = GetMethodIDOrDie(env, fmBandDescriptorClass,
682d15c9dfd8b87ff54b2e5304b941c2e62f7e93dd6Tomasz Wasilczyk            "<init>", "(IIIIIZZZZZ)V");
683d15c9dfd8b87ff54b2e5304b941c2e62f7e93dd6Tomasz Wasilczyk
684d15c9dfd8b87ff54b2e5304b941c2e62f7e93dd6Tomasz Wasilczyk    auto amBandDescriptorClass = FindClassOrDie(env,
685d15c9dfd8b87ff54b2e5304b941c2e62f7e93dd6Tomasz Wasilczyk            "android/hardware/radio/RadioManager$AmBandDescriptor");
686d15c9dfd8b87ff54b2e5304b941c2e62f7e93dd6Tomasz Wasilczyk    gjni.AmBandDescriptor.clazz = MakeGlobalRefOrDie(env, amBandDescriptorClass);
687d15c9dfd8b87ff54b2e5304b941c2e62f7e93dd6Tomasz Wasilczyk    gjni.AmBandDescriptor.cstor = GetMethodIDOrDie(env, amBandDescriptorClass,
688d15c9dfd8b87ff54b2e5304b941c2e62f7e93dd6Tomasz Wasilczyk            "<init>", "(IIIIIZ)V");
689d15c9dfd8b87ff54b2e5304b941c2e62f7e93dd6Tomasz Wasilczyk
690df01326ba0dbc6bdb6dbc43c3b1ea7b1e4973e20Tomasz Wasilczyk    auto convertClass = FindClassOrDie(env, "com/android/server/broadcastradio/hal1/Convert");
6910f1776d08b43f5f71a9f89b6a4f1838df4d3d744Tomasz Wasilczyk    gjni.Convert.clazz = MakeGlobalRefOrDie(env, convertClass);
6920f1776d08b43f5f71a9f89b6a4f1838df4d3d744Tomasz Wasilczyk    gjni.Convert.stringMapToNative = GetStaticMethodIDOrDie(env, convertClass, "stringMapToNative",
6930f1776d08b43f5f71a9f89b6a4f1838df4d3d744Tomasz Wasilczyk            "(Ljava/util/Map;)[[Ljava/lang/String;");
6940f1776d08b43f5f71a9f89b6a4f1838df4d3d744Tomasz Wasilczyk
6950f1776d08b43f5f71a9f89b6a4f1838df4d3d744Tomasz Wasilczyk    auto hashMapClass = FindClassOrDie(env, "java/util/HashMap");
6960f1776d08b43f5f71a9f89b6a4f1838df4d3d744Tomasz Wasilczyk    gjni.HashMap.clazz = MakeGlobalRefOrDie(env, hashMapClass);
6970f1776d08b43f5f71a9f89b6a4f1838df4d3d744Tomasz Wasilczyk    gjni.HashMap.cstor = GetMethodIDOrDie(env, hashMapClass, "<init>", "()V");
6980f1776d08b43f5f71a9f89b6a4f1838df4d3d744Tomasz Wasilczyk
6998e932c61db78e7a04f6a98e070089f10abdccf1aTomasz Wasilczyk    auto listClass = FindClassOrDie(env, "java/util/List");
7008e932c61db78e7a04f6a98e070089f10abdccf1aTomasz Wasilczyk    gjni.List.get = GetMethodIDOrDie(env, listClass, "get", "(I)Ljava/lang/Object;");
7018e932c61db78e7a04f6a98e070089f10abdccf1aTomasz Wasilczyk    gjni.List.size = GetMethodIDOrDie(env, listClass, "size", "()I");
7028e932c61db78e7a04f6a98e070089f10abdccf1aTomasz Wasilczyk
7030f1776d08b43f5f71a9f89b6a4f1838df4d3d744Tomasz Wasilczyk    auto mapClass = FindClassOrDie(env, "java/util/Map");
7040f1776d08b43f5f71a9f89b6a4f1838df4d3d744Tomasz Wasilczyk    gjni.Map.put = GetMethodIDOrDie(env, mapClass, "put",
7050f1776d08b43f5f71a9f89b6a4f1838df4d3d744Tomasz Wasilczyk            "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
7060f1776d08b43f5f71a9f89b6a4f1838df4d3d744Tomasz Wasilczyk
707d15c9dfd8b87ff54b2e5304b941c2e62f7e93dd6Tomasz Wasilczyk    auto modulePropertiesClass = FindClassOrDie(env,
708d15c9dfd8b87ff54b2e5304b941c2e62f7e93dd6Tomasz Wasilczyk            "android/hardware/radio/RadioManager$ModuleProperties");
709d15c9dfd8b87ff54b2e5304b941c2e62f7e93dd6Tomasz Wasilczyk    gjni.ModuleProperties.clazz = MakeGlobalRefOrDie(env, modulePropertiesClass);
710d15c9dfd8b87ff54b2e5304b941c2e62f7e93dd6Tomasz Wasilczyk    gjni.ModuleProperties.cstor = GetMethodIDOrDie(env, modulePropertiesClass, "<init>",
711d15c9dfd8b87ff54b2e5304b941c2e62f7e93dd6Tomasz Wasilczyk            "(ILjava/lang/String;ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;"
71227926edc3b737823bd6bc3146b6e73a69f8dfe3aTomasz Wasilczyk            "Ljava/lang/String;IIZZ[Landroid/hardware/radio/RadioManager$BandDescriptor;Z"
71358f34065c53067a22bba6b8af7f9cb759701e79eTomasz Wasilczyk            "[I[ILjava/util/Map;Ljava/util/Map;)V");
714d15c9dfd8b87ff54b2e5304b941c2e62f7e93dd6Tomasz Wasilczyk
7152383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk    auto programInfoClass = FindClassOrDie(env, "android/hardware/radio/RadioManager$ProgramInfo");
7162383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk    gjni.ProgramInfo.clazz = MakeGlobalRefOrDie(env, programInfoClass);
717eab3e5509689cf4dd066f0de5e060967626b3a2aTomasz Wasilczyk    gjni.ProgramInfo.cstor = GetMethodIDOrDie(env, programInfoClass, "<init>", "("
718eab3e5509689cf4dd066f0de5e060967626b3a2aTomasz Wasilczyk            "Landroid/hardware/radio/ProgramSelector;"
719eab3e5509689cf4dd066f0de5e060967626b3a2aTomasz Wasilczyk            "Landroid/hardware/radio/ProgramSelector$Identifier;"
720eab3e5509689cf4dd066f0de5e060967626b3a2aTomasz Wasilczyk            "Landroid/hardware/radio/ProgramSelector$Identifier;"
721eab3e5509689cf4dd066f0de5e060967626b3a2aTomasz Wasilczyk            "Ljava/util/Collection;"  // relatedContent
722eab3e5509689cf4dd066f0de5e060967626b3a2aTomasz Wasilczyk            "II"  // flags, signalQuality
723eab3e5509689cf4dd066f0de5e060967626b3a2aTomasz Wasilczyk            "Landroid/hardware/radio/RadioMetadata;"
724eab3e5509689cf4dd066f0de5e060967626b3a2aTomasz Wasilczyk            "Ljava/util/Map;"  // vendorInfo
725eab3e5509689cf4dd066f0de5e060967626b3a2aTomasz Wasilczyk            ")V");
7268cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk
7278cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk    auto programSelectorClass = FindClassOrDie(env, "android/hardware/radio/ProgramSelector");
7288cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk    gjni.ProgramSelector.clazz = MakeGlobalRefOrDie(env, programSelectorClass);
7298cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk    gjni.ProgramSelector.cstor = GetMethodIDOrDie(env, programSelectorClass, "<init>",
7308cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk            "(ILandroid/hardware/radio/ProgramSelector$Identifier;"
7318cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk            "[Landroid/hardware/radio/ProgramSelector$Identifier;[J)V");
7328cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk    gjni.ProgramSelector.programType = GetFieldIDOrDie(env, programSelectorClass,
7338cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk            "mProgramType", "I");
7348cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk    gjni.ProgramSelector.primaryId = GetFieldIDOrDie(env, programSelectorClass,
7358cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk            "mPrimaryId", "Landroid/hardware/radio/ProgramSelector$Identifier;");
7368cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk    gjni.ProgramSelector.secondaryIds = GetFieldIDOrDie(env, programSelectorClass,
7378cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk            "mSecondaryIds", "[Landroid/hardware/radio/ProgramSelector$Identifier;");
7388cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk    gjni.ProgramSelector.vendorIds = GetFieldIDOrDie(env, programSelectorClass,
7398cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk            "mVendorIds", "[J");
7408cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk
7418cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk    auto progSelIdClass = FindClassOrDie(env, "android/hardware/radio/ProgramSelector$Identifier");
7428cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk    gjni.ProgramSelector.Identifier.clazz = MakeGlobalRefOrDie(env, progSelIdClass);
7438cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk    gjni.ProgramSelector.Identifier.cstor = GetMethodIDOrDie(env, progSelIdClass,
7448cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk            "<init>", "(IJ)V");
7458cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk    gjni.ProgramSelector.Identifier.type = GetFieldIDOrDie(env, progSelIdClass,
7468cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk            "mType", "I");
7478cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk    gjni.ProgramSelector.Identifier.value = GetFieldIDOrDie(env, progSelIdClass,
7488cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk            "mValue", "J");
7492383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk
7502383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk    auto radioMetadataClass = FindClassOrDie(env, "android/hardware/radio/RadioMetadata");
7512383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk    gjni.RadioMetadata.clazz = MakeGlobalRefOrDie(env, radioMetadataClass);
7522383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk    gjni.RadioMetadata.cstor = GetMethodIDOrDie(env, radioMetadataClass, "<init>", "()V");
7532383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk    gjni.RadioMetadata.putIntFromNative = GetMethodIDOrDie(env, radioMetadataClass,
7542383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk            "putIntFromNative", "(II)I");
7552383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk    gjni.RadioMetadata.putStringFromNative = GetMethodIDOrDie(env, radioMetadataClass,
7562383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk            "putStringFromNative", "(ILjava/lang/String;)I");
7572383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk    gjni.RadioMetadata.putBitmapFromNative = GetMethodIDOrDie(env, radioMetadataClass,
7582383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk            "putBitmapFromNative", "(I[B)I");
7592383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk    gjni.RadioMetadata.putClockFromNative = GetMethodIDOrDie(env, radioMetadataClass,
7602383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk            "putClockFromNative", "(IJI)I");
761c62e38d573b647ff4d3293d07dbdce3440a6b739Tomasz Wasilczyk
762c62e38d573b647ff4d3293d07dbdce3440a6b739Tomasz Wasilczyk    auto runtimeExcClass = FindClassOrDie(env, "java/lang/RuntimeException");
763c62e38d573b647ff4d3293d07dbdce3440a6b739Tomasz Wasilczyk    gjni.RuntimeException.clazz = MakeGlobalRefOrDie(env, runtimeExcClass);
764c62e38d573b647ff4d3293d07dbdce3440a6b739Tomasz Wasilczyk    gjni.RuntimeException.cstor = GetMethodIDOrDie(env, runtimeExcClass, "<init>",
765c62e38d573b647ff4d3293d07dbdce3440a6b739Tomasz Wasilczyk            "(Ljava/lang/String;)V");
766c62e38d573b647ff4d3293d07dbdce3440a6b739Tomasz Wasilczyk
767c62e38d573b647ff4d3293d07dbdce3440a6b739Tomasz Wasilczyk    auto parcelableExcClass = FindClassOrDie(env, "android/os/ParcelableException");
768c62e38d573b647ff4d3293d07dbdce3440a6b739Tomasz Wasilczyk    gjni.ParcelableException.clazz = MakeGlobalRefOrDie(env, parcelableExcClass);
769c62e38d573b647ff4d3293d07dbdce3440a6b739Tomasz Wasilczyk    gjni.ParcelableException.cstor = GetMethodIDOrDie(env, parcelableExcClass, "<init>",
770c62e38d573b647ff4d3293d07dbdce3440a6b739Tomasz Wasilczyk            "(Ljava/lang/Throwable;)V");
7718e932c61db78e7a04f6a98e070089f10abdccf1aTomasz Wasilczyk
7728e932c61db78e7a04f6a98e070089f10abdccf1aTomasz Wasilczyk    auto stringClass = FindClassOrDie(env, "java/lang/String");
7738e932c61db78e7a04f6a98e070089f10abdccf1aTomasz Wasilczyk    gjni.String.clazz = MakeGlobalRefOrDie(env, stringClass);
77431c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk}
77531c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk
77631c8df0abdf08b8c66b246445b6a4ab596a6cb44Tomasz Wasilczyk} // namespace android
777