diff options
11 files changed, 221 insertions, 50 deletions
diff --git a/api/system-current.txt b/api/system-current.txt index 1b292ccb5302..7b416db2831f 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -17392,7 +17392,7 @@ package android.hardware.radio { method public java.lang.String getProduct(); method public java.lang.String getSerial(); method public java.lang.String getServiceName(); - method public java.lang.String getVendorInfo(); + method public java.util.Map<java.lang.String, java.lang.String> getVendorInfo(); method public java.lang.String getVersion(); method public boolean isBackgroundScanningSupported(); method public boolean isCaptureSupported(); @@ -17409,7 +17409,7 @@ package android.hardware.radio { method public android.hardware.radio.ProgramSelector getSelector(); method public int getSignalStrength(); method public deprecated int getSubChannel(); - method public java.lang.String getVendorInfo(); + method public java.util.Map<java.lang.String, java.lang.String> getVendorInfo(); method public boolean isDigital(); method public boolean isLive(); method public boolean isMuted(); @@ -17473,7 +17473,7 @@ package android.hardware.radio { method public abstract int getConfiguration(android.hardware.radio.RadioManager.BandConfig[]); method public abstract boolean getMute(); method public abstract int getProgramInformation(android.hardware.radio.RadioManager.ProgramInfo[]); - method public abstract java.util.List<android.hardware.radio.RadioManager.ProgramInfo> getProgramList(java.lang.String); + method public abstract java.util.List<android.hardware.radio.RadioManager.ProgramInfo> getProgramList(java.util.Map<java.lang.String, java.lang.String>); method public abstract boolean hasControl(); method public abstract boolean isAnalogForced(); method public abstract boolean isAntennaConnected(); diff --git a/core/java/android/hardware/radio/ITuner.aidl b/core/java/android/hardware/radio/ITuner.aidl index 7f470ef15b96..ef8f80ce70dd 100644 --- a/core/java/android/hardware/radio/ITuner.aidl +++ b/core/java/android/hardware/radio/ITuner.aidl @@ -74,12 +74,13 @@ interface ITuner { boolean startBackgroundScan(); /** + * @param vendorFilter Vendor-specific filter, must be Map<String, String> * @returns the list, or null if scan is in progress * @throws IllegalArgumentException if invalid arguments are passed * @throws IllegalStateException if the scan has not been started, client may * call startBackgroundScan to fix this. */ - List<RadioManager.ProgramInfo> getProgramList(String filter); + List<RadioManager.ProgramInfo> getProgramList(in Map vendorFilter); /** * @throws IllegalStateException if the switch is not supported at current diff --git a/core/java/android/hardware/radio/RadioManager.java b/core/java/android/hardware/radio/RadioManager.java index fcb3d8641717..50a4da2ed656 100644 --- a/core/java/android/hardware/radio/RadioManager.java +++ b/core/java/android/hardware/radio/RadioManager.java @@ -35,7 +35,9 @@ import android.util.Log; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.Arrays; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Set; import java.util.stream.Collectors; @@ -117,6 +119,25 @@ public class RadioManager { * @see BandDescriptor */ public static final int REGION_KOREA = 4; + private static void writeStringMap(@NonNull Parcel dest, @NonNull Map<String, String> map) { + dest.writeInt(map.size()); + for (Map.Entry<String, String> entry : map.entrySet()) { + dest.writeString(entry.getKey()); + dest.writeString(entry.getValue()); + } + } + + private static @NonNull Map<String, String> readStringMap(@NonNull Parcel in) { + int size = in.readInt(); + Map<String, String> map = new HashMap<>(); + while (size-- > 0) { + String key = in.readString(); + String value = in.readString(); + map.put(key, value); + } + return map; + } + /***************************************************************************** * Lists properties, options and radio bands supported by a given broadcast radio module. * Each module has a unique ID used to address it when calling RadioManager APIs. @@ -138,14 +159,14 @@ public class RadioManager { private final boolean mIsBgScanSupported; private final Set<Integer> mSupportedProgramTypes; private final Set<Integer> mSupportedIdentifierTypes; - private final String mVendorInfo; + @NonNull private final Map<String, String> mVendorInfo; ModuleProperties(int id, String serviceName, int classId, String implementor, String product, String version, String serial, int numTuners, int numAudioSources, boolean isCaptureSupported, BandDescriptor[] bands, boolean isBgScanSupported, @ProgramSelector.ProgramType int[] supportedProgramTypes, @ProgramSelector.IdentifierType int[] supportedIdentifierTypes, - String vendorInfo) { + Map<String, String> vendorInfo) { mId = id; mServiceName = TextUtils.isEmpty(serviceName) ? "default" : serviceName; mClassId = classId; @@ -160,7 +181,7 @@ public class RadioManager { mIsBgScanSupported = isBgScanSupported; mSupportedProgramTypes = arrayToSet(supportedProgramTypes); mSupportedIdentifierTypes = arrayToSet(supportedIdentifierTypes); - mVendorInfo = vendorInfo; + mVendorInfo = (vendorInfo == null) ? new HashMap<>() : vendorInfo; } private static Set<Integer> arrayToSet(int[] arr) { @@ -287,17 +308,17 @@ public class RadioManager { } /** - * Opaque vendor-specific string, passed from HAL without changes. - * Format of this string can vary across vendors. + * A map of vendor-specific opaque strings, passed from HAL without changes. + * Format of these strings can vary across vendors. * * It may be used for extra features, that's not supported by a platform, - * for example: "preset-slots=6;ultra-hd-capable=false". + * for example: preset-slots=6; ultra-hd-capable=false. * - * Client application MUST verify vendor/product name from the - * ModuleProperties class before doing any interpretation of this value. + * Keys must be prefixed with unique vendor Java-style namespace, + * eg. 'com.somecompany.parameter1'. */ - public @NonNull String getVendorInfo() { - return mVendorInfo == null ? "" : mVendorInfo; + public @NonNull Map<String, String> getVendorInfo() { + return mVendorInfo; } /** List of descriptors for all bands supported by this module. @@ -327,7 +348,7 @@ public class RadioManager { mIsBgScanSupported = in.readInt() == 1; mSupportedProgramTypes = arrayToSet(in.createIntArray()); mSupportedIdentifierTypes = arrayToSet(in.createIntArray()); - mVendorInfo = in.readString(); + mVendorInfo = readStringMap(in); } public static final Parcelable.Creator<ModuleProperties> CREATOR @@ -357,7 +378,7 @@ public class RadioManager { dest.writeInt(mIsBgScanSupported ? 1 : 0); dest.writeIntArray(setToArray(mSupportedProgramTypes)); dest.writeIntArray(setToArray(mSupportedIdentifierTypes)); - dest.writeString(mVendorInfo); + writeStringMap(dest, mVendorInfo); } @Override @@ -394,7 +415,7 @@ public class RadioManager { result = prime * result + (mIsCaptureSupported ? 1 : 0); result = prime * result + Arrays.hashCode(mBands); result = prime * result + (mIsBgScanSupported ? 1 : 0); - result = prime * result + ((mVendorInfo == null) ? 0 : mVendorInfo.hashCode()); + result = prime * result + mVendorInfo.hashCode(); return result; } @@ -440,7 +461,7 @@ public class RadioManager { return false; if (mIsBgScanSupported != other.isBackgroundScanningSupported()) return false; - if (!TextUtils.equals(mVendorInfo, other.mVendorInfo)) return false; + if (!mVendorInfo.equals(other.mVendorInfo)) return false; return true; } } @@ -1324,11 +1345,11 @@ public class RadioManager { private final int mFlags; private final int mSignalStrength; private final RadioMetadata mMetadata; - private final String mVendorInfo; + @NonNull private final Map<String, String> mVendorInfo; ProgramInfo(@NonNull ProgramSelector selector, boolean tuned, boolean stereo, boolean digital, int signalStrength, RadioMetadata metadata, int flags, - String vendorInfo) { + Map<String, String> vendorInfo) { mSelector = selector; mTuned = tuned; mStereo = stereo; @@ -1336,7 +1357,7 @@ public class RadioManager { mFlags = flags; mSignalStrength = signalStrength; mMetadata = metadata; - mVendorInfo = vendorInfo; + mVendorInfo = (vendorInfo == null) ? new HashMap<>() : vendorInfo; } /** @@ -1447,17 +1468,17 @@ public class RadioManager { } /** - * Opaque vendor-specific string, passed from HAL without changes. - * Format of this string can vary across vendors. + * A map of vendor-specific opaque strings, passed from HAL without changes. + * Format of these strings can vary across vendors. * * It may be used for extra features, that's not supported by a platform, - * for example: "paid-service=true;bitrate=320kbps". + * for example: paid-service=true; bitrate=320kbps. * - * Client application MUST verify vendor/product name from the - * ModuleProperties class before doing any interpretation of this value. + * Keys must be prefixed with unique vendor Java-style namespace, + * eg. 'com.somecompany.parameter1'. */ - public @NonNull String getVendorInfo() { - return mVendorInfo == null ? "" : mVendorInfo; + public @NonNull Map<String, String> getVendorInfo() { + return mVendorInfo; } private ProgramInfo(Parcel in) { @@ -1472,7 +1493,7 @@ public class RadioManager { mMetadata = null; } mFlags = in.readInt(); - mVendorInfo = in.readString(); + mVendorInfo = readStringMap(in); } public static final Parcelable.Creator<ProgramInfo> CREATOR @@ -1500,7 +1521,7 @@ public class RadioManager { mMetadata.writeToParcel(dest, flags); } dest.writeInt(mFlags); - dest.writeString(mVendorInfo); + writeStringMap(dest, mVendorInfo); } @Override @@ -1528,7 +1549,7 @@ public class RadioManager { result = prime * result + mFlags; result = prime * result + mSignalStrength; result = prime * result + ((mMetadata == null) ? 0 : mMetadata.hashCode()); - result = prime * result + ((mVendorInfo == null) ? 0 : mVendorInfo.hashCode()); + result = prime * result + mVendorInfo.hashCode(); return result; } @@ -1555,7 +1576,7 @@ public class RadioManager { return false; } else if (!mMetadata.equals(other.getMetadata())) return false; - if (!TextUtils.equals(mVendorInfo, other.mVendorInfo)) return false; + if (!mVendorInfo.equals(other.mVendorInfo)) return false; return true; } } diff --git a/core/java/android/hardware/radio/RadioTuner.java b/core/java/android/hardware/radio/RadioTuner.java index be37cd0e342b..4b4fb1c8ce3c 100644 --- a/core/java/android/hardware/radio/RadioTuner.java +++ b/core/java/android/hardware/radio/RadioTuner.java @@ -23,6 +23,7 @@ import android.graphics.Bitmap; import android.os.Handler; import java.util.List; +import java.util.Map; /** * RadioTuner interface provides methods to control a radio tuner on the device: selecting and @@ -270,16 +271,18 @@ public abstract class RadioTuner { /** * Get the list of discovered radio stations. * - * To get the full list, set filter to null or empty string. Otherwise, client application - * must verify vendor product/name before setting this parameter to anything else. + * To get the full list, set filter to null or empty map. + * Keys must be prefixed with unique vendor Java-style namespace, + * eg. 'com.somecompany.parameter1'. * - * @param filter vendor-specific selector for radio stations. + * @param vendorFilter vendor-specific selector for radio stations. * @return a list of radio stations. * @throws IllegalStateException if the scan is in progress or has not been started, * startBackgroundScan() call may fix it. - * @throws IllegalArgumentException if the filter argument is not valid. + * @throws IllegalArgumentException if the vendorFilter argument is not valid. */ - public abstract @NonNull List<RadioManager.ProgramInfo> getProgramList(@Nullable String filter); + public abstract @NonNull List<RadioManager.ProgramInfo> + getProgramList(@Nullable Map<String, String> vendorFilter); /** * Checks, if the analog playback is forced, see setAnalogForced. diff --git a/core/java/android/hardware/radio/TunerAdapter.java b/core/java/android/hardware/radio/TunerAdapter.java index c68753788a4d..b62196902570 100644 --- a/core/java/android/hardware/radio/TunerAdapter.java +++ b/core/java/android/hardware/radio/TunerAdapter.java @@ -23,6 +23,7 @@ import android.os.RemoteException; import android.util.Log; import java.util.List; +import java.util.Map; /** * Implements the RadioTuner interface by forwarding calls to radio service. @@ -222,9 +223,10 @@ class TunerAdapter extends RadioTuner { } @Override - public @NonNull List<RadioManager.ProgramInfo> getProgramList(@Nullable String filter) { + public @NonNull List<RadioManager.ProgramInfo> + getProgramList(@Nullable Map<String, String> vendorFilter) { try { - return mTuner.getProgramList(filter); + return mTuner.getProgramList(vendorFilter); } catch (RemoteException e) { throw new RuntimeException("service died", e); } diff --git a/core/tests/BroadcastRadioTests/src/android/hardware/radio/tests/functional/RadioTunerTest.java b/core/tests/BroadcastRadioTests/src/android/hardware/radio/tests/functional/RadioTunerTest.java index ee40c48dcb58..29b6fd0e0c2c 100644 --- a/core/tests/BroadcastRadioTests/src/android/hardware/radio/tests/functional/RadioTunerTest.java +++ b/core/tests/BroadcastRadioTests/src/android/hardware/radio/tests/functional/RadioTunerTest.java @@ -28,7 +28,9 @@ import android.util.Log; import java.lang.reflect.Constructor; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import org.junit.After; import org.junit.Before; @@ -291,6 +293,7 @@ public class RadioTunerTest { assertEquals(RadioManager.STATUS_OK, ret); assertNotNull(info[0]); assertEquals(channel, info[0].getChannel()); + Log.d(TAG, "PI: " + info[0].toString()); } @Test @@ -344,7 +347,9 @@ public class RadioTunerTest { openTuner(); try { - List<RadioManager.ProgramInfo> list = mRadioTuner.getProgramList(null); + Map<String, String> filter = new HashMap<>(); + filter.put("com.google.dummy", "dummy"); + List<RadioManager.ProgramInfo> list = mRadioTuner.getProgramList(filter); assertNotNull(list); } catch (IllegalStateException e) { // the list may or may not be ready at this point diff --git a/services/core/java/com/android/server/broadcastradio/Convert.java b/services/core/java/com/android/server/broadcastradio/Convert.java new file mode 100644 index 000000000000..125554fc3025 --- /dev/null +++ b/services/core/java/com/android/server/broadcastradio/Convert.java @@ -0,0 +1,59 @@ +/** + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.broadcastradio; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.util.Slog; + +import java.util.Map; +import java.util.Set; + +class Convert { + private static final String TAG = "BroadcastRadioService.Convert"; + + /** + * Converts string map to an array that's easily accessible by native code. + * + * Calling this java method once is more efficient than converting map object on the native + * side, which requires several separate java calls for each element. + * + * @param map map to convert. + * @returns array (sized the same as map) of two-element string arrays + * (first element is the key, second is value). + */ + static @NonNull String[][] stringMapToNative(@Nullable Map<String, String> map) { + if (map == null) { + Slog.v(TAG, "map is null, returning zero-elements array"); + return new String[0][0]; + } + + Set<Map.Entry<String, String>> entries = map.entrySet(); + int len = entries.size(); + String[][] arr = new String[len][2]; + + int i = 0; + for (Map.Entry<String, String> entry : entries) { + arr[i][0] = entry.getKey(); + arr[i][1] = entry.getValue(); + i++; + } + + Slog.v(TAG, "converted " + i + " element(s)"); + return arr; + } +} diff --git a/services/core/java/com/android/server/broadcastradio/Tuner.java b/services/core/java/com/android/server/broadcastradio/Tuner.java index b9a1e8167ff2..06a5af5f482e 100644 --- a/services/core/java/com/android/server/broadcastradio/Tuner.java +++ b/services/core/java/com/android/server/broadcastradio/Tuner.java @@ -28,6 +28,7 @@ import android.os.RemoteException; import android.util.Slog; import java.util.List; +import java.util.Map; class Tuner extends ITuner.Stub { private static final String TAG = "BroadcastRadioService.Tuner"; @@ -86,7 +87,7 @@ class Tuner extends ITuner.Stub { private native RadioManager.ProgramInfo nativeGetProgramInformation(long nativeContext); private native boolean nativeStartBackgroundScan(long nativeContext); private native List<RadioManager.ProgramInfo> nativeGetProgramList(long nativeContext, - String filter); + Map<String, String> vendorFilter); private native byte[] nativeGetImage(long nativeContext, int id); @@ -242,10 +243,11 @@ class Tuner extends ITuner.Stub { } @Override - public List<RadioManager.ProgramInfo> getProgramList(String filter) { + public List<RadioManager.ProgramInfo> getProgramList(Map vendorFilter) { + Map<String, String> sFilter = vendorFilter; synchronized (mLock) { checkNotClosedLocked(); - List<RadioManager.ProgramInfo> list = nativeGetProgramList(mNativeContext, filter); + List<RadioManager.ProgramInfo> list = nativeGetProgramList(mNativeContext, sFilter); if (list == null) { throw new IllegalStateException("Program list is not ready"); } diff --git a/services/core/jni/BroadcastRadio/Tuner.cpp b/services/core/jni/BroadcastRadio/Tuner.cpp index aa1925ad365a..85603d5e3608 100644 --- a/services/core/jni/BroadcastRadio/Tuner.cpp +++ b/services/core/jni/BroadcastRadio/Tuner.cpp @@ -374,7 +374,7 @@ static bool nativeStartBackgroundScan(JNIEnv *env, jobject obj, jlong nativeCont return !convert::ThrowIfFailed(env, halResult); } -static jobject nativeGetProgramList(JNIEnv *env, jobject obj, jlong nativeContext, jstring jFilter) { +static jobject nativeGetProgramList(JNIEnv *env, jobject obj, jlong nativeContext, jobject jVendorFilter) { ALOGV("%s", __func__); auto halTuner = getHalTuner11(nativeContext); if (halTuner == nullptr) { @@ -384,7 +384,7 @@ static jobject nativeGetProgramList(JNIEnv *env, jobject obj, jlong nativeContex JavaRef<jobject> jList; ProgramListResult halResult = ProgramListResult::NOT_INITIALIZED; - auto filter = env->GetStringUTFChars(jFilter, nullptr); + auto filter = convert::VendorInfoToHal(env, jVendorFilter); auto hidlResult = halTuner->getProgramList(filter, [&](ProgramListResult result, const hidl_vec<V1_1::ProgramInfo>& programList) { halResult = result; @@ -505,7 +505,7 @@ static const JNINativeMethod gTunerMethods[] = { { "nativeGetProgramInformation", "(J)Landroid/hardware/radio/RadioManager$ProgramInfo;", (void*)nativeGetProgramInformation }, { "nativeStartBackgroundScan", "(J)Z", (void*)nativeStartBackgroundScan }, - { "nativeGetProgramList", "(JLjava/lang/String;)Ljava/util/List;", + { "nativeGetProgramList", "(JLjava/util/Map;)Ljava/util/List;", (void*)nativeGetProgramList }, { "nativeGetImage", "(JI)[B", (void*)nativeGetImage}, { "nativeIsAnalogForced", "(J)Z", (void*)nativeIsAnalogForced }, diff --git a/services/core/jni/BroadcastRadio/convert.cpp b/services/core/jni/BroadcastRadio/convert.cpp index ba1395f73045..3e0bc63c279f 100644 --- a/services/core/jni/BroadcastRadio/convert.cpp +++ b/services/core/jni/BroadcastRadio/convert.cpp @@ -41,6 +41,7 @@ using V1_0::Rds; using V1_1::ProgramIdentifier; using V1_1::ProgramListResult; using V1_1::ProgramSelector; +using V1_1::VendorKeyValue; static JavaRef<jobject> BandDescriptorFromHal(JNIEnv *env, const V1_0::BandConfig &config, Region region); @@ -82,6 +83,20 @@ static struct { struct { jclass clazz; + jmethodID stringMapToNative; + } Convert; + + struct { + jclass clazz; + jmethodID cstor; + } HashMap; + + struct { + jmethodID put; + } Map; + + struct { + jclass clazz; jmethodID cstor; } ModuleProperties; @@ -228,6 +243,53 @@ static JavaRef<jobjectArray> ArrayFromHal(JNIEnv *env, const hidl_vec<T>& vec, std::function<JavaRef<jobject>(JNIEnv*, const T&)>(converter)); } +static std::string StringFromJava(JNIEnv *env, JavaRef<jstring> &jStr) { + auto cstr = (jStr == nullptr) ? nullptr : env->GetStringUTFChars(jStr.get(), nullptr); + std::string str(cstr); + env->ReleaseStringUTFChars(jStr.get(), cstr); + return str; +} + +JavaRef<jobject> VendorInfoFromHal(JNIEnv *env, const hidl_vec<VendorKeyValue> &info) { + ALOGV("%s(%s)", __func__, toString(info).substr(0, 100).c_str()); + + auto jInfo = make_javaref(env, env->NewObject(gjni.HashMap.clazz, gjni.HashMap.cstor)); + + for (auto&& entry : info) { + auto jKey = make_javastr(env, entry.key); + auto jValue = make_javastr(env, entry.value); + env->CallObjectMethod(jInfo.get(), gjni.Map.put, jKey.get(), jValue.get()); + } + + return jInfo; +} + +hidl_vec<VendorKeyValue> VendorInfoToHal(JNIEnv *env, jobject jInfo) { + ALOGV("%s", __func__); + + auto jInfoArr = make_javaref(env, static_cast<jobjectArray>(env->CallStaticObjectMethod( + gjni.Convert.clazz, gjni.Convert.stringMapToNative, jInfo))); + LOG_FATAL_IF(jInfoArr == nullptr, "Converted array is null"); + + auto len = env->GetArrayLength(jInfoArr.get()); + hidl_vec<VendorKeyValue> vec; + vec.resize(len); + + for (jsize i = 0; i < len; i++) { + auto entry = make_javaref(env, static_cast<jobjectArray>( + env->GetObjectArrayElement(jInfoArr.get(), i))); + auto jKey = make_javaref(env, static_cast<jstring>( + env->GetObjectArrayElement(entry.get(), 0))); + auto jValue = make_javaref(env, static_cast<jstring>( + env->GetObjectArrayElement(entry.get(), 1))); + auto key = StringFromJava(env, jKey); + auto value = StringFromJava(env, jValue); + vec[i] = { key, value }; + } + + return vec; +} + static Rds RdsForRegion(bool rds, Region region) { if (!rds) return Rds::NONE; @@ -271,7 +333,7 @@ static JavaRef<jobject> ModulePropertiesFromHal(JNIEnv *env, const V1_0::Propert auto jVersion = make_javastr(env, prop10.version); auto jSerial = make_javastr(env, prop10.serial); bool isBgScanSupported = prop11 ? prop11->supportsBackgroundScanning : false; - auto jVendorInfo = prop11 ? make_javastr(env, prop11->vendorInfo) : nullptr; + auto jVendorInfo = prop11 ? VendorInfoFromHal(env, prop11->vendorInfo) : nullptr; // ITU_1 is the default region just because its index is 0. auto jBands = ArrayFromHal<V1_0::BandConfig>(env, prop10.bands, gjni.BandDescriptor.clazz, std::bind(BandDescriptorFromHal, _1, _2, Region::ITU_1)); @@ -512,7 +574,7 @@ static JavaRef<jobject> ProgramInfoFromHal(JNIEnv *env, const V1_0::ProgramInfo ALOGV("%s", __func__); auto jMetadata = MetadataFromHal(env, info10.metadata); - auto jVendorInfo = info11 ? make_javastr(env, info11->vendorInfo) : nullptr; + auto jVendorInfo = info11 ? VendorInfoFromHal(env, info11->vendorInfo) : nullptr; auto jSelector = ProgramSelectorFromHal(env, selector); return make_javaref(env, env->NewObject(gjni.ProgramInfo.clazz, gjni.ProgramInfo.cstor, @@ -579,19 +641,32 @@ void register_android_server_broadcastradio_convert(JNIEnv *env) { gjni.AmBandDescriptor.cstor = GetMethodIDOrDie(env, amBandDescriptorClass, "<init>", "(IIIIIZ)V"); + auto convertClass = FindClassOrDie(env, "com/android/server/broadcastradio/Convert"); + gjni.Convert.clazz = MakeGlobalRefOrDie(env, convertClass); + gjni.Convert.stringMapToNative = GetStaticMethodIDOrDie(env, convertClass, "stringMapToNative", + "(Ljava/util/Map;)[[Ljava/lang/String;"); + + auto hashMapClass = FindClassOrDie(env, "java/util/HashMap"); + gjni.HashMap.clazz = MakeGlobalRefOrDie(env, hashMapClass); + gjni.HashMap.cstor = GetMethodIDOrDie(env, hashMapClass, "<init>", "()V"); + + auto mapClass = FindClassOrDie(env, "java/util/Map"); + gjni.Map.put = GetMethodIDOrDie(env, mapClass, "put", + "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); + auto modulePropertiesClass = FindClassOrDie(env, "android/hardware/radio/RadioManager$ModuleProperties"); gjni.ModuleProperties.clazz = MakeGlobalRefOrDie(env, modulePropertiesClass); gjni.ModuleProperties.cstor = GetMethodIDOrDie(env, modulePropertiesClass, "<init>", "(ILjava/lang/String;ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;" "Ljava/lang/String;IIZ[Landroid/hardware/radio/RadioManager$BandDescriptor;Z" - "[I[ILjava/lang/String;)V"); + "[I[ILjava/util/Map;)V"); auto programInfoClass = FindClassOrDie(env, "android/hardware/radio/RadioManager$ProgramInfo"); gjni.ProgramInfo.clazz = MakeGlobalRefOrDie(env, programInfoClass); gjni.ProgramInfo.cstor = GetMethodIDOrDie(env, programInfoClass, "<init>", "(Landroid/hardware/radio/ProgramSelector;ZZZILandroid/hardware/radio/RadioMetadata;I" - "Ljava/lang/String;)V"); + "Ljava/util/Map;)V"); auto programSelectorClass = FindClassOrDie(env, "android/hardware/radio/ProgramSelector"); gjni.ProgramSelector.clazz = MakeGlobalRefOrDie(env, programSelectorClass); diff --git a/services/core/jni/BroadcastRadio/convert.h b/services/core/jni/BroadcastRadio/convert.h index 198e594553a3..1fc75f06f38d 100644 --- a/services/core/jni/BroadcastRadio/convert.h +++ b/services/core/jni/BroadcastRadio/convert.h @@ -35,6 +35,9 @@ namespace convert { namespace V1_0 = hardware::broadcastradio::V1_0; namespace V1_1 = hardware::broadcastradio::V1_1; +JavaRef<jobject> VendorInfoFromHal(JNIEnv *env, const hardware::hidl_vec<V1_1::VendorKeyValue> &info); +hardware::hidl_vec<V1_1::VendorKeyValue> VendorInfoToHal(JNIEnv *env, jobject jInfo); + JavaRef<jobject> ModulePropertiesFromHal(JNIEnv *env, const V1_0::Properties &properties, jint moduleId, const std::string& serviceName); JavaRef<jobject> ModulePropertiesFromHal(JNIEnv *env, const V1_1::Properties &properties, |