diff options
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, |