Merge "Implement front-end APIs for generic vendor-specific parameters."
This commit is contained in:
committed by
Android (Google) Code Review
commit
c99d6c1908
@@ -94,5 +94,17 @@ interface ITuner {
|
||||
*/
|
||||
void setAnalogForced(boolean isForced);
|
||||
|
||||
/**
|
||||
* @param parameters Vendor-specific key-value pairs, must be Map<String, String>
|
||||
* @return Vendor-specific key-value pairs, must be Map<String, String>
|
||||
*/
|
||||
Map setParameters(in Map parameters);
|
||||
|
||||
/**
|
||||
* @param keys Parameter keys to fetch
|
||||
* @return Vendor-specific key-value pairs, must be Map<String, String>
|
||||
*/
|
||||
Map getParameters(in List<String> keys);
|
||||
|
||||
boolean isAntennaConnected();
|
||||
}
|
||||
|
||||
@@ -30,4 +30,9 @@ oneway interface ITunerCallback {
|
||||
void onBackgroundScanAvailabilityChange(boolean isAvailable);
|
||||
void onBackgroundScanComplete();
|
||||
void onProgramListChanged();
|
||||
|
||||
/**
|
||||
* @param parameters Vendor-specific key-value pairs, must be Map<String, String>
|
||||
*/
|
||||
void onParametersUpdated(in Map parameters);
|
||||
}
|
||||
|
||||
@@ -308,6 +308,58 @@ public abstract class RadioTuner {
|
||||
*/
|
||||
public abstract void setAnalogForced(boolean isForced);
|
||||
|
||||
/**
|
||||
* Generic method for setting vendor-specific parameter values.
|
||||
* The framework does not interpret the parameters, they are passed
|
||||
* in an opaque manner between a vendor application and HAL.
|
||||
*
|
||||
* Framework does not make any assumptions on the keys or values, other than
|
||||
* ones stated in VendorKeyValue documentation (a requirement of key
|
||||
* prefixes).
|
||||
*
|
||||
* For each pair in the result map, the key will be one of the keys
|
||||
* contained in the input (possibly with wildcards expanded), and the value
|
||||
* will be a vendor-specific result status (such as "OK" or an error code).
|
||||
* The implementation may choose to return an empty map, or only return
|
||||
* a status for a subset of the provided inputs, at its discretion.
|
||||
*
|
||||
* Application and HAL must not use keys with unknown prefix. In particular,
|
||||
* it must not place a key-value pair in results vector for unknown key from
|
||||
* parameters vector - instead, an unknown key should simply be ignored.
|
||||
* In other words, results vector may contain a subset of parameter keys
|
||||
* (however, the framework doesn't enforce a strict subset - the only
|
||||
* formal requirement is vendor domain prefix for keys).
|
||||
*
|
||||
* @param parameters Vendor-specific key-value pairs.
|
||||
* @return Operation completion status for parameters being set.
|
||||
* @hide FutureFeature
|
||||
*/
|
||||
public abstract @NonNull Map<String, String>
|
||||
setParameters(@NonNull Map<String, String> parameters);
|
||||
|
||||
/**
|
||||
* Generic method for retrieving vendor-specific parameter values.
|
||||
* The framework does not interpret the parameters, they are passed
|
||||
* in an opaque manner between a vendor application and HAL.
|
||||
*
|
||||
* Framework does not cache set/get requests, so it's possible for
|
||||
* getParameter to return a different value than previous setParameter call.
|
||||
*
|
||||
* The syntax and semantics of keys are up to the vendor (as long as prefix
|
||||
* rules are obeyed). For instance, vendors may include some form of
|
||||
* wildcard support. In such case, result vector may be of different size
|
||||
* than requested keys vector. However, wildcards are not recognized by
|
||||
* framework and they are passed as-is to the HAL implementation.
|
||||
*
|
||||
* Unknown keys must be ignored and not placed into results vector.
|
||||
*
|
||||
* @param keys Parameter keys to fetch.
|
||||
* @return Vendor-specific key-value pairs.
|
||||
* @hide FutureFeature
|
||||
*/
|
||||
public abstract @NonNull Map<String, String>
|
||||
getParameters(@NonNull List<String> keys);
|
||||
|
||||
/**
|
||||
* Get current antenna connection state for current configuration.
|
||||
* Only valid if a configuration has been applied.
|
||||
@@ -429,6 +481,22 @@ public abstract class RadioTuner {
|
||||
* Use {@link RadioTuner#getProgramList(String)} to get an actual list.
|
||||
*/
|
||||
public void onProgramListChanged() {}
|
||||
|
||||
/**
|
||||
* Generic callback for passing updates to vendor-specific parameter values.
|
||||
* The framework does not interpret the parameters, they are passed
|
||||
* in an opaque manner between a vendor application and HAL.
|
||||
*
|
||||
* It's up to the HAL implementation if and how to implement this callback,
|
||||
* as long as it obeys the prefix rule. In particular, only selected keys
|
||||
* may be notified this way. However, setParameters must not trigger
|
||||
* this callback, while an internal event can change parameters
|
||||
* asynchronously.
|
||||
*
|
||||
* @param parameters Vendor-specific key-value pairs.
|
||||
* @hide FutureFeature
|
||||
*/
|
||||
public void onParametersUpdated(@NonNull Map<String, String> parameters) {}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import android.util.Log;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Implements the RadioTuner interface by forwarding calls to radio service.
|
||||
@@ -250,6 +251,24 @@ class TunerAdapter extends RadioTuner {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull Map<String, String> setParameters(@NonNull Map<String, String> parameters) {
|
||||
try {
|
||||
return mTuner.setParameters(Objects.requireNonNull(parameters));
|
||||
} catch (RemoteException e) {
|
||||
throw new RuntimeException("service died", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull Map<String, String> getParameters(@NonNull List<String> keys) {
|
||||
try {
|
||||
return mTuner.getParameters(Objects.requireNonNull(keys));
|
||||
} catch (RemoteException e) {
|
||||
throw new RuntimeException("service died", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAntennaConnected() {
|
||||
try {
|
||||
|
||||
@@ -22,6 +22,8 @@ import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Implements the ITunerCallback interface by forwarding calls to RadioTuner.Callback.
|
||||
*/
|
||||
@@ -94,4 +96,9 @@ class TunerCallbackAdapter extends ITunerCallback.Stub {
|
||||
public void onProgramListChanged() {
|
||||
mHandler.post(() -> mCallback.onProgramListChanged());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onParametersUpdated(Map parameters) {
|
||||
mHandler.post(() -> mCallback.onParametersUpdated(parameters));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,8 +27,10 @@ import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Slog;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
class Tuner extends ITuner.Stub {
|
||||
private static final String TAG = "BroadcastRadioService.Tuner";
|
||||
@@ -96,6 +98,10 @@ class Tuner extends ITuner.Stub {
|
||||
private native boolean nativeIsAnalogForced(long nativeContext);
|
||||
private native void nativeSetAnalogForced(long nativeContext, boolean isForced);
|
||||
|
||||
private native Map<String, String> nativeSetParameters(long nativeContext,
|
||||
Map<String, String> parameters);
|
||||
private native Map<String, String> nativeGetParameters(long nativeContext, List<String> keys);
|
||||
|
||||
private native boolean nativeIsAntennaConnected(long nativeContext);
|
||||
|
||||
@Override
|
||||
@@ -272,6 +278,31 @@ class Tuner extends ITuner.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map setParameters(Map parameters) {
|
||||
Map<String, String> results;
|
||||
synchronized (mLock) {
|
||||
checkNotClosedLocked();
|
||||
results = nativeSetParameters(mNativeContext, Objects.requireNonNull(parameters));
|
||||
}
|
||||
if (results == null) return Collections.emptyMap();
|
||||
return results;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map getParameters(List<String> keys) {
|
||||
if (keys == null) {
|
||||
throw new IllegalArgumentException("The argument must not be a null pointer");
|
||||
}
|
||||
Map<String, String> results;
|
||||
synchronized (mLock) {
|
||||
checkNotClosedLocked();
|
||||
results = nativeGetParameters(mNativeContext, keys);
|
||||
}
|
||||
if (results == null) return Collections.emptyMap();
|
||||
return results;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAntennaConnected() {
|
||||
synchronized (mLock) {
|
||||
|
||||
@@ -26,6 +26,9 @@ import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Slog;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
class TunerCallback implements ITunerCallback {
|
||||
private static final String TAG = "BroadcastRadioService.TunerCallback";
|
||||
|
||||
@@ -120,6 +123,11 @@ class TunerCallback implements ITunerCallback {
|
||||
dispatch(() -> mClientCallback.onProgramListChanged());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onParametersUpdated(Map parameters) {
|
||||
dispatch(() -> mClientCallback.onParametersUpdated(parameters));
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBinder asBinder() {
|
||||
throw new RuntimeException("Not a binder");
|
||||
|
||||
@@ -51,8 +51,9 @@ using V1_0::Band;
|
||||
using V1_0::BandConfig;
|
||||
using V1_0::MetaData;
|
||||
using V1_0::Result;
|
||||
using V1_2::ITunerCallback;
|
||||
using V1_1::ProgramListResult;
|
||||
using V1_1::VendorKeyValue;
|
||||
using V1_2::ITunerCallback;
|
||||
using utils::HalRevision;
|
||||
|
||||
static mutex gContextMutex;
|
||||
@@ -93,6 +94,7 @@ struct TunerContext {
|
||||
wp<V1_1::IBroadcastRadio> mHalModule11;
|
||||
sp<V1_0::ITuner> mHalTuner;
|
||||
sp<V1_1::ITuner> mHalTuner11;
|
||||
sp<V1_2::ITuner> mHalTuner12;
|
||||
sp<HalDeathRecipient> mHalDeathRecipient;
|
||||
|
||||
private:
|
||||
@@ -179,8 +181,11 @@ void assignHalInterfaces(JNIEnv *env, JavaRef<jobject> const &jTuner,
|
||||
|
||||
ctx.mHalTuner = halTuner;
|
||||
ctx.mHalTuner11 = V1_1::ITuner::castFrom(halTuner).withDefault(nullptr);
|
||||
ctx.mHalTuner12 = V1_2::ITuner::castFrom(halTuner).withDefault(nullptr);
|
||||
ALOGW_IF(ctx.mHalRev >= HalRevision::V1_1 && ctx.mHalTuner11 == nullptr,
|
||||
"Provided tuner does not implement 1.1 HAL");
|
||||
ALOGW_IF(ctx.mHalRev >= HalRevision::V1_2 && ctx.mHalTuner12 == nullptr,
|
||||
"Provided tuner does not implement 1.2 HAL");
|
||||
|
||||
ctx.mHalDeathRecipient = new HalDeathRecipient(getNativeCallback(env, jTuner));
|
||||
halTuner->linkToDeath(ctx.mHalDeathRecipient, 0);
|
||||
@@ -194,16 +199,21 @@ static sp<V1_0::ITuner> getHalTuner(const TunerContext& ctx) {
|
||||
return tuner;
|
||||
}
|
||||
|
||||
sp<V1_0::ITuner> getHalTuner(jlong nativeContext) {
|
||||
static sp<V1_0::ITuner> getHalTuner(jlong nativeContext) {
|
||||
lock_guard<mutex> lk(gContextMutex);
|
||||
return getHalTuner(getNativeContext(nativeContext));
|
||||
}
|
||||
|
||||
sp<V1_1::ITuner> getHalTuner11(jlong nativeContext) {
|
||||
static sp<V1_1::ITuner> getHalTuner11(jlong nativeContext) {
|
||||
lock_guard<mutex> lk(gContextMutex);
|
||||
return getNativeContext(nativeContext).mHalTuner11;
|
||||
}
|
||||
|
||||
static sp<V1_2::ITuner> getHalTuner12(jlong nativeContext) {
|
||||
lock_guard<mutex> lk(gContextMutex);
|
||||
return getNativeContext(nativeContext).mHalTuner12;
|
||||
}
|
||||
|
||||
sp<ITunerCallback> getNativeCallback(JNIEnv *env, JavaRef<jobject> const &tuner) {
|
||||
return TunerCallback::getNativeCallback(env,
|
||||
env->GetObjectField(tuner.get(), gjni.Tuner.tunerCallback));
|
||||
@@ -233,6 +243,7 @@ static void nativeClose(JNIEnv *env, jobject obj, jlong nativeContext) {
|
||||
ctx.mHalDeathRecipient = nullptr;
|
||||
|
||||
ctx.mHalTuner11 = nullptr;
|
||||
ctx.mHalTuner12 = nullptr;
|
||||
ctx.mHalTuner = nullptr;
|
||||
}
|
||||
|
||||
@@ -488,6 +499,48 @@ static void nativeSetAnalogForced(JNIEnv *env, jobject obj, jlong nativeContext,
|
||||
convert::ThrowIfFailed(env, halResult);
|
||||
}
|
||||
|
||||
static jobject nativeSetParameters(JNIEnv *env, jobject obj, jlong nativeContext, jobject jParameters) {
|
||||
ALOGV("%s", __func__);
|
||||
|
||||
auto halTuner = getHalTuner12(nativeContext);
|
||||
if (halTuner == nullptr) {
|
||||
ALOGI("Parameters are not supported with HAL < 1.2");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
JavaRef<jobject> jResults = nullptr;
|
||||
auto parameters = convert::VendorInfoToHal(env, jParameters);
|
||||
auto hidlResult = halTuner->setParameters(parameters,
|
||||
[&](const hidl_vec<VendorKeyValue> results) {
|
||||
jResults = convert::VendorInfoFromHal(env, results);
|
||||
});
|
||||
|
||||
if (convert::ThrowIfFailed(env, hidlResult)) return nullptr;
|
||||
|
||||
return jResults.release();
|
||||
}
|
||||
|
||||
static jobject nativeGetParameters(JNIEnv *env, jobject obj, jlong nativeContext, jobject jKeys) {
|
||||
ALOGV("%s", __func__);
|
||||
|
||||
auto halTuner = getHalTuner12(nativeContext);
|
||||
if (halTuner == nullptr) {
|
||||
ALOGI("Parameters are not supported with HAL < 1.2");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
JavaRef<jobject> jResults = nullptr;
|
||||
auto keys = convert::StringListToHal(env, jKeys);
|
||||
auto hidlResult = halTuner->getParameters(keys,
|
||||
[&](const hidl_vec<VendorKeyValue> parameters) {
|
||||
jResults = convert::VendorInfoFromHal(env, parameters);
|
||||
});
|
||||
|
||||
if (convert::ThrowIfFailed(env, hidlResult)) return nullptr;
|
||||
|
||||
return jResults.release();
|
||||
}
|
||||
|
||||
static bool nativeIsAntennaConnected(JNIEnv *env, jobject obj, jlong nativeContext) {
|
||||
ALOGV("%s", __func__);
|
||||
auto halTuner = getHalTuner(nativeContext);
|
||||
@@ -525,6 +578,8 @@ static const JNINativeMethod gTunerMethods[] = {
|
||||
{ "nativeGetImage", "(JI)[B", (void*)nativeGetImage},
|
||||
{ "nativeIsAnalogForced", "(J)Z", (void*)nativeIsAnalogForced },
|
||||
{ "nativeSetAnalogForced", "(JZ)V", (void*)nativeSetAnalogForced },
|
||||
{ "nativeSetParameters", "(JLjava/util/Map;)Ljava/util/Map;", (void*)nativeSetParameters },
|
||||
{ "nativeGetParameters", "(JLjava/util/List;)Ljava/util/Map;", (void*)nativeGetParameters },
|
||||
{ "nativeIsAntennaConnected", "(J)Z", (void*)nativeIsAntennaConnected },
|
||||
};
|
||||
|
||||
|
||||
@@ -70,6 +70,7 @@ static struct {
|
||||
jmethodID onBackgroundScanAvailabilityChange;
|
||||
jmethodID onBackgroundScanComplete;
|
||||
jmethodID onProgramListChanged;
|
||||
jmethodID onParametersUpdated;
|
||||
} TunerCallback;
|
||||
} gjni;
|
||||
|
||||
@@ -346,7 +347,10 @@ Return<void> NativeCallback::currentProgramInfoChanged(const ProgramInfo& info)
|
||||
Return<void> NativeCallback::parametersUpdated(const hidl_vec<VendorKeyValue>& parameters) {
|
||||
ALOGV("%s", __func__);
|
||||
|
||||
// TODO(b/65862441): pass this callback to the front-end
|
||||
mCallbackThread.enqueue([this, parameters](JNIEnv *env) {
|
||||
auto jParameters = convert::VendorInfoFromHal(env, parameters);
|
||||
env->CallVoidMethod(mJCallback, gjni.TunerCallback.onParametersUpdated, jParameters.get());
|
||||
});
|
||||
|
||||
return {};
|
||||
}
|
||||
@@ -437,6 +441,8 @@ void register_android_server_broadcastradio_TunerCallback(JavaVM *vm, JNIEnv *en
|
||||
"onBackgroundScanComplete", "()V");
|
||||
gjni.TunerCallback.onProgramListChanged = GetMethodIDOrDie(env, tunerCbClass,
|
||||
"onProgramListChanged", "()V");
|
||||
gjni.TunerCallback.onParametersUpdated = GetMethodIDOrDie(env, tunerCbClass,
|
||||
"onParametersUpdated", "(Ljava/util/Map;)V");
|
||||
|
||||
auto res = jniRegisterNativeMethods(env, "com/android/server/broadcastradio/TunerCallback",
|
||||
gTunerCallbackMethods, NELEM(gTunerCallbackMethods));
|
||||
|
||||
@@ -34,6 +34,7 @@ namespace convert {
|
||||
namespace utils = hardware::broadcastradio::utils;
|
||||
|
||||
using hardware::Return;
|
||||
using hardware::hidl_string;
|
||||
using hardware::hidl_vec;
|
||||
using regions::RegionalBandConfig;
|
||||
|
||||
@@ -97,6 +98,11 @@ static struct {
|
||||
jmethodID cstor;
|
||||
} HashMap;
|
||||
|
||||
struct {
|
||||
jmethodID get;
|
||||
jmethodID size;
|
||||
} List;
|
||||
|
||||
struct {
|
||||
jmethodID put;
|
||||
} Map;
|
||||
@@ -145,8 +151,21 @@ static struct {
|
||||
jclass clazz;
|
||||
jmethodID cstor;
|
||||
} ParcelableException;
|
||||
|
||||
struct {
|
||||
jclass clazz;
|
||||
} String;
|
||||
} gjni;
|
||||
|
||||
static jstring CastToString(JNIEnv *env, jobject obj) {
|
||||
if (env->IsInstanceOf(obj, gjni.String.clazz)) {
|
||||
return static_cast<jstring>(obj);
|
||||
} else {
|
||||
ALOGE("Cast failed, object is not a string");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
bool ThrowIfFailed(JNIEnv *env, const hardware::Return<void> &hidlResult) {
|
||||
return __ThrowIfFailedHidl(env, hidlResult);
|
||||
@@ -250,12 +269,26 @@ static JavaRef<jobjectArray> ArrayFromHal(JNIEnv *env, const hidl_vec<T>& vec,
|
||||
}
|
||||
|
||||
static std::string StringFromJava(JNIEnv *env, JavaRef<jstring> &jStr) {
|
||||
auto cstr = (jStr == nullptr) ? nullptr : env->GetStringUTFChars(jStr.get(), nullptr);
|
||||
if (jStr == nullptr) return {};
|
||||
auto cstr = env->GetStringUTFChars(jStr.get(), nullptr);
|
||||
std::string str(cstr);
|
||||
env->ReleaseStringUTFChars(jStr.get(), cstr);
|
||||
return str;
|
||||
}
|
||||
|
||||
hidl_vec<hidl_string> StringListToHal(JNIEnv *env, jobject jList) {
|
||||
auto len = (jList == nullptr) ? 0 : env->CallIntMethod(jList, gjni.List.size);
|
||||
hidl_vec<hidl_string> list(len);
|
||||
|
||||
for (decltype(len) i = 0; i < len; i++) {
|
||||
auto jString = make_javaref(env, CastToString(env, env->CallObjectMethod(
|
||||
jList, gjni.List.get, i)));
|
||||
list[i] = StringFromJava(env, jString);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
JavaRef<jobject> VendorInfoFromHal(JNIEnv *env, const hidl_vec<VendorKeyValue> &info) {
|
||||
ALOGV("%s(%s)", __func__, toString(info).substr(0, 100).c_str());
|
||||
|
||||
@@ -275,7 +308,10 @@ hidl_vec<VendorKeyValue> VendorInfoToHal(JNIEnv *env, jobject jInfo) {
|
||||
|
||||
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");
|
||||
if (jInfoArr == nullptr) {
|
||||
ALOGE("Converted array is null");
|
||||
return {};
|
||||
}
|
||||
|
||||
auto len = env->GetArrayLength(jInfoArr.get());
|
||||
hidl_vec<VendorKeyValue> vec;
|
||||
@@ -651,6 +687,10 @@ void register_android_server_broadcastradio_convert(JNIEnv *env) {
|
||||
gjni.HashMap.clazz = MakeGlobalRefOrDie(env, hashMapClass);
|
||||
gjni.HashMap.cstor = GetMethodIDOrDie(env, hashMapClass, "<init>", "()V");
|
||||
|
||||
auto listClass = FindClassOrDie(env, "java/util/List");
|
||||
gjni.List.get = GetMethodIDOrDie(env, listClass, "get", "(I)Ljava/lang/Object;");
|
||||
gjni.List.size = GetMethodIDOrDie(env, listClass, "size", "()I");
|
||||
|
||||
auto mapClass = FindClassOrDie(env, "java/util/Map");
|
||||
gjni.Map.put = GetMethodIDOrDie(env, mapClass, "put",
|
||||
"(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
|
||||
@@ -713,6 +753,9 @@ void register_android_server_broadcastradio_convert(JNIEnv *env) {
|
||||
gjni.ParcelableException.clazz = MakeGlobalRefOrDie(env, parcelableExcClass);
|
||||
gjni.ParcelableException.cstor = GetMethodIDOrDie(env, parcelableExcClass, "<init>",
|
||||
"(Ljava/lang/Throwable;)V");
|
||||
|
||||
auto stringClass = FindClassOrDie(env, "java/lang/String");
|
||||
gjni.String.clazz = MakeGlobalRefOrDie(env, stringClass);
|
||||
}
|
||||
|
||||
} // namespace android
|
||||
|
||||
@@ -35,6 +35,8 @@ namespace convert {
|
||||
namespace V1_0 = hardware::broadcastradio::V1_0;
|
||||
namespace V1_1 = hardware::broadcastradio::V1_1;
|
||||
|
||||
hardware::hidl_vec<hardware::hidl_string> StringListToHal(JNIEnv *env, jobject jList);
|
||||
|
||||
JavaRef<jobject> VendorInfoFromHal(JNIEnv *env, const hardware::hidl_vec<V1_1::VendorKeyValue> &info);
|
||||
hardware::hidl_vec<V1_1::VendorKeyValue> VendorInfoToHal(JNIEnv *env, jobject jInfo);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user