summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/hardware/radio/ITunerCallback.aidl2
-rw-r--r--core/java/android/hardware/radio/RadioManager.java1
-rw-r--r--core/java/android/hardware/radio/TunerCallbackAdapter.java29
-rw-r--r--services/core/java/com/android/server/broadcastradio/TunerCallback.java4
-rw-r--r--services/core/jni/BroadcastRadio/TunerCallback.cpp81
5 files changed, 62 insertions, 55 deletions
diff --git a/core/java/android/hardware/radio/ITunerCallback.aidl b/core/java/android/hardware/radio/ITunerCallback.aidl
index a09a6864ac6e..6ed171bbb8a9 100644
--- a/core/java/android/hardware/radio/ITunerCallback.aidl
+++ b/core/java/android/hardware/radio/ITunerCallback.aidl
@@ -23,7 +23,7 @@ import android.hardware.radio.RadioMetadata;
oneway interface ITunerCallback {
void onError(int status);
void onConfigurationChanged(in RadioManager.BandConfig config);
- void onCurrentProgramInfoChanged();
+ void onCurrentProgramInfoChanged(in RadioManager.ProgramInfo info);
void onTrafficAnnouncement(boolean active);
void onEmergencyAnnouncement(boolean active);
void onAntennaState(boolean connected);
diff --git a/core/java/android/hardware/radio/RadioManager.java b/core/java/android/hardware/radio/RadioManager.java
index 50a4da2ed656..4f4361f6f1eb 100644
--- a/core/java/android/hardware/radio/RadioManager.java
+++ b/core/java/android/hardware/radio/RadioManager.java
@@ -1656,7 +1656,6 @@ public class RadioManager {
Log.e(TAG, "Failed to open tuner");
return null;
}
- halCallback.attachTuner(tuner);
return new TunerAdapter(tuner, config != null ? config.getType() : BAND_INVALID);
}
diff --git a/core/java/android/hardware/radio/TunerCallbackAdapter.java b/core/java/android/hardware/radio/TunerCallbackAdapter.java
index 02ca52ed84fc..ffd5b30fa15c 100644
--- a/core/java/android/hardware/radio/TunerCallbackAdapter.java
+++ b/core/java/android/hardware/radio/TunerCallbackAdapter.java
@@ -20,7 +20,6 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.Handler;
import android.os.Looper;
-import android.os.RemoteException;
import android.util.Log;
/**
@@ -31,10 +30,6 @@ class TunerCallbackAdapter extends ITunerCallback.Stub {
@NonNull private final RadioTuner.Callback mCallback;
@NonNull private final Handler mHandler;
- private final Object mLock = new Object();
-
- @Nullable private ITuner mTuner;
- boolean mPendingProgramInfoChanged = false;
TunerCallbackAdapter(@NonNull RadioTuner.Callback callback, @Nullable Handler handler) {
mCallback = callback;
@@ -45,14 +40,6 @@ class TunerCallbackAdapter extends ITunerCallback.Stub {
}
}
- public void attachTuner(@NonNull ITuner tuner) {
- synchronized (mLock) {
- if (mTuner != null) throw new IllegalStateException();
- mTuner = tuner;
- if (mPendingProgramInfoChanged) onCurrentProgramInfoChanged();
- }
- }
-
@Override
public void onError(int status) {
mHandler.post(() -> mCallback.onError(status));
@@ -64,19 +51,9 @@ class TunerCallbackAdapter extends ITunerCallback.Stub {
}
@Override
- public void onCurrentProgramInfoChanged() {
- synchronized (mLock) {
- if (mTuner == null) {
- mPendingProgramInfoChanged = true;
- return;
- }
- }
-
- RadioManager.ProgramInfo info;
- try {
- info = mTuner.getProgramInformation();
- } catch (RemoteException e) {
- Log.e(TAG, "service died", e);
+ public void onCurrentProgramInfoChanged(RadioManager.ProgramInfo info) {
+ if (info == null) {
+ Log.e(TAG, "ProgramInfo must not be null");
return;
}
diff --git a/services/core/java/com/android/server/broadcastradio/TunerCallback.java b/services/core/java/com/android/server/broadcastradio/TunerCallback.java
index 331b6574ee92..a87ae8d65bf8 100644
--- a/services/core/java/com/android/server/broadcastradio/TunerCallback.java
+++ b/services/core/java/com/android/server/broadcastradio/TunerCallback.java
@@ -86,8 +86,8 @@ class TunerCallback implements ITunerCallback {
}
@Override
- public void onCurrentProgramInfoChanged() {
- dispatch(() -> mClientCallback.onCurrentProgramInfoChanged());
+ public void onCurrentProgramInfoChanged(RadioManager.ProgramInfo info) {
+ dispatch(() -> mClientCallback.onCurrentProgramInfoChanged(info));
}
@Override
diff --git a/services/core/jni/BroadcastRadio/TunerCallback.cpp b/services/core/jni/BroadcastRadio/TunerCallback.cpp
index e01d8fa0b152..d53721fbd082 100644
--- a/services/core/jni/BroadcastRadio/TunerCallback.cpp
+++ b/services/core/jni/BroadcastRadio/TunerCallback.cpp
@@ -46,6 +46,7 @@ using V1_0::BandConfig;
using V1_0::MetaData;
using V1_0::Result;
using V1_1::ITunerCallback;
+using V1_1::ProgramInfo;
using V1_1::ProgramListResult;
using V1_1::ProgramSelector;
@@ -82,6 +83,8 @@ enum class TunerError : jint {
static mutex gContextMutex;
class NativeCallback : public ITunerCallback {
+ mutex mMut;
+
jobject mJTuner;
jobject mJCallback;
NativeCallbackThread mCallbackThread;
@@ -89,6 +92,9 @@ class NativeCallback : public ITunerCallback {
Band mBand;
+ // Carries current program info data for 1.0 newMetadata callback.
+ V1_0::ProgramInfo mCurrentProgramInfo;
+
DISALLOW_COPY_AND_ASSIGN(NativeCallback);
public:
@@ -107,11 +113,10 @@ public:
virtual Return<void> newMetadata(uint32_t channel, uint32_t subChannel,
const hidl_vec<MetaData>& metadata);
virtual Return<void> tuneComplete_1_1(Result result, const ProgramSelector& selector);
- virtual Return<void> afSwitch_1_1(const ProgramSelector& selector);
virtual Return<void> backgroundScanAvailable(bool isAvailable);
virtual Return<void> backgroundScanComplete(ProgramListResult result);
virtual Return<void> programListChanged();
- virtual Return<void> currentProgramInfoChanged();
+ virtual Return<void> currentProgramInfoChanged(const ProgramInfo& info);
};
struct TunerCallbackContext {
@@ -180,7 +185,22 @@ Return<void> NativeCallback::tuneComplete(Result result, const V1_0::ProgramInfo
if (mHalRev > HalRevision::V1_0) {
ALOGW("1.0 callback was ignored");
- return Return<void>();
+ return {};
+ }
+
+ if (result == Result::OK) {
+ {
+ lock_guard<mutex> lk(mMut);
+ mCurrentProgramInfo = info;
+ }
+
+ // tuneComplete_1_1 implementation does not handle success case, see the implementation
+ mCallbackThread.enqueue([this, info](JNIEnv *env) {
+ auto jInfo = convert::ProgramInfoFromHal(env, info, mBand);
+ env->CallVoidMethod(mJCallback, gjni.TunerCallback.onCurrentProgramInfoChanged,
+ jInfo.get());
+ });
+ return {};
}
auto selector = V1_1::utils::make_selector(mBand, info.channel, info.subChannel);
@@ -191,13 +211,14 @@ Return<void> NativeCallback::tuneComplete_1_1(Result result, const ProgramSelect
ALOGV("%s(%d)", __func__, result);
mCallbackThread.enqueue([result, this](JNIEnv *env) {
- if (result == Result::OK) {
- env->CallVoidMethod(mJCallback, gjni.TunerCallback.onCurrentProgramInfoChanged);
- } else {
- TunerError cause = TunerError::CANCELLED;
- if (result == Result::TIMEOUT) cause = TunerError::SCAN_TIMEOUT;
- env->CallVoidMethod(mJCallback, gjni.TunerCallback.onError, cause);
- }
+ /* for HAL 1.1, onCurrentProgramInfoChanged will be called from currentProgramInfoChanged,
+ * so we don't need to handle success case here.
+ */
+ if (result == Result::OK) return;
+
+ TunerError cause = TunerError::CANCELLED;
+ if (result == Result::TIMEOUT) cause = TunerError::SCAN_TIMEOUT;
+ env->CallVoidMethod(mJCallback, gjni.TunerCallback.onError, cause);
});
return Return<void>();
@@ -208,11 +229,6 @@ Return<void> NativeCallback::afSwitch(const V1_0::ProgramInfo& info) {
return tuneComplete(Result::OK, info);
}
-Return<void> NativeCallback::afSwitch_1_1(const ProgramSelector& selector) {
- ALOGV("%s", __func__);
- return tuneComplete_1_1(Result::OK, selector);
-}
-
Return<void> NativeCallback::antennaStateChange(bool connected) {
ALOGV("%s(%d)", __func__, connected);
@@ -245,19 +261,32 @@ Return<void> NativeCallback::emergencyAnnouncement(bool active) {
Return<void> NativeCallback::newMetadata(uint32_t channel, uint32_t subChannel,
const hidl_vec<MetaData>& metadata) {
- // channel and subChannel are not used
ALOGV("%s(%d, %d)", __func__, channel, subChannel);
if (mHalRev > HalRevision::V1_0) {
ALOGW("1.0 callback was ignored");
- return Return<void>();
+ return {};
}
- mCallbackThread.enqueue([this, metadata](JNIEnv *env) {
- env->CallVoidMethod(mJCallback, gjni.TunerCallback.onCurrentProgramInfoChanged);
+ V1_0::ProgramInfo info;
+ {
+ lock_guard<mutex> lk(mMut);
+ info = mCurrentProgramInfo;
+ }
+ if (channel != info.channel || subChannel != info.subChannel) {
+ ALOGE("Channel mismatch on newMetadata callback (%d.%d != %d.%d)",
+ channel, subChannel, info.channel, info.subChannel);
+ return {};
+ }
+ info.metadata = metadata;
+
+ mCallbackThread.enqueue([this, info](JNIEnv *env) {
+ auto jInfo = convert::ProgramInfoFromHal(env, info, mBand);
+ env->CallVoidMethod(mJCallback, gjni.TunerCallback.onCurrentProgramInfoChanged,
+ jInfo.get());
});
- return Return<void>();
+ return {};
}
Return<void> NativeCallback::backgroundScanAvailable(bool isAvailable) {
@@ -297,11 +326,13 @@ Return<void> NativeCallback::programListChanged() {
return Return<void>();
}
-Return<void> NativeCallback::currentProgramInfoChanged() {
- ALOGV("%s", __func__);
+Return<void> NativeCallback::currentProgramInfoChanged(const ProgramInfo& info) {
+ ALOGV("%s(%s)", __func__, toString(info).substr(0, 100).c_str());
- mCallbackThread.enqueue([this](JNIEnv *env) {
- env->CallVoidMethod(mJCallback, gjni.TunerCallback.onCurrentProgramInfoChanged);
+ mCallbackThread.enqueue([this, info](JNIEnv *env) {
+ auto jInfo = convert::ProgramInfoFromHal(env, info);
+ env->CallVoidMethod(mJCallback, gjni.TunerCallback.onCurrentProgramInfoChanged,
+ jInfo.get());
});
return Return<void>();
@@ -380,7 +411,7 @@ void register_android_server_broadcastradio_TunerCallback(JavaVM *vm, JNIEnv *en
gjni.TunerCallback.onConfigurationChanged = GetMethodIDOrDie(env, tunerCbClass,
"onConfigurationChanged", "(Landroid/hardware/radio/RadioManager$BandConfig;)V");
gjni.TunerCallback.onCurrentProgramInfoChanged = GetMethodIDOrDie(env, tunerCbClass,
- "onCurrentProgramInfoChanged", "()V");
+ "onCurrentProgramInfoChanged", "(Landroid/hardware/radio/RadioManager$ProgramInfo;)V");
gjni.TunerCallback.onTrafficAnnouncement = GetMethodIDOrDie(env, tunerCbClass,
"onTrafficAnnouncement", "(Z)V");
gjni.TunerCallback.onEmergencyAnnouncement = GetMethodIDOrDie(env, tunerCbClass,