Merge "Deprecate onMetadataChanged."
diff --git a/api/system-current.txt b/api/system-current.txt
index d176e39..6979527 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -17490,7 +17490,7 @@
method public void onControlChanged(boolean);
method public void onEmergencyAnnouncement(boolean);
method public void onError(int);
- method public void onMetadataChanged(android.hardware.radio.RadioMetadata);
+ method public deprecated void onMetadataChanged(android.hardware.radio.RadioMetadata);
method public void onProgramInfoChanged(android.hardware.radio.RadioManager.ProgramInfo);
method public void onProgramListChanged();
method public void onTrafficAnnouncement(boolean);
diff --git a/core/java/android/hardware/radio/ITunerCallback.aidl b/core/java/android/hardware/radio/ITunerCallback.aidl
index aed114e..c3bbaec 100644
--- a/core/java/android/hardware/radio/ITunerCallback.aidl
+++ b/core/java/android/hardware/radio/ITunerCallback.aidl
@@ -23,8 +23,7 @@
oneway interface ITunerCallback {
void onError(int status);
void onConfigurationChanged(in RadioManager.BandConfig config);
- void onProgramInfoChanged(in RadioManager.ProgramInfo info);
- void onMetadataChanged(in RadioMetadata metadata);
+ void onProgramInfoChanged();
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 8ef5705..1de80b17 100644
--- a/core/java/android/hardware/radio/RadioManager.java
+++ b/core/java/android/hardware/radio/RadioManager.java
@@ -1560,7 +1560,7 @@
Log.d(TAG, "Opening tuner " + moduleId + "...");
ITuner tuner;
- ITunerCallback halCallback = new TunerCallbackAdapter(callback, handler);
+ TunerCallbackAdapter halCallback = new TunerCallbackAdapter(callback, handler);
try {
tuner = mService.openTuner(moduleId, config, withAudio, halCallback);
} catch (RemoteException e) {
@@ -1571,6 +1571,7 @@
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/RadioTuner.java b/core/java/android/hardware/radio/RadioTuner.java
index f659273..8e0b0f6 100644
--- a/core/java/android/hardware/radio/RadioTuner.java
+++ b/core/java/android/hardware/radio/RadioTuner.java
@@ -330,20 +330,24 @@
* or {@link RadioTuner#setConfiguration(RadioManager.BandConfig)}
*/
public void onConfigurationChanged(RadioManager.BandConfig config) {}
+
/**
- * onProgramInfoChanged() is called upon successful completion of
- * {@link RadioTuner#step(int, boolean)}, {@link RadioTuner#scan(int, boolean)},
- * {@link RadioTuner#tune(int, int)} or when a switching to alternate frequency occurs.
- * Note that if metadata only are updated, {@link #onMetadataChanged(RadioMetadata)} will
- * be called.
+ * Called when program info (including metadata) for the current program has changed.
+ *
+ * It happens either upon successful completion of {@link RadioTuner#step(int, boolean)},
+ * {@link RadioTuner#scan(int, boolean)}, {@link RadioTuner#tune(int, int)}; when
+ * a switching to alternate frequency occurs; or when metadata is updated.
*/
public void onProgramInfoChanged(RadioManager.ProgramInfo info) {}
+
/**
- * onMetadataChanged() is called when new meta data are received on current program.
- * Meta data are also received in {@link RadioManager.ProgramInfo} when
- * {@link #onProgramInfoChanged(RadioManager.ProgramInfo)} is called.
+ * Called when metadata is updated for the current program.
+ *
+ * @deprecated Use {@link #onProgramInfoChanged(RadioManager.ProgramInfo)} instead.
*/
+ @Deprecated
public void onMetadataChanged(RadioMetadata metadata) {}
+
/**
* onTrafficAnnouncement() is called when a traffic announcement starts and stops.
*/
@@ -386,7 +390,7 @@
/**
* Called when available program list changed.
*
- * Use getProgramList() to get the actual list.
+ * Use {@link RadioTuner#getProgramList(String)} to get an actual list.
*/
public void onProgramListChanged() {}
}
diff --git a/core/java/android/hardware/radio/TunerCallbackAdapter.java b/core/java/android/hardware/radio/TunerCallbackAdapter.java
index 155ffa7..8c3826c 100644
--- a/core/java/android/hardware/radio/TunerCallbackAdapter.java
+++ b/core/java/android/hardware/radio/TunerCallbackAdapter.java
@@ -20,13 +20,21 @@
import android.annotation.Nullable;
import android.os.Handler;
import android.os.Looper;
+import android.os.RemoteException;
+import android.util.Log;
/**
* Implements the ITunerCallback interface by forwarding calls to RadioTuner.Callback.
*/
class TunerCallbackAdapter extends ITunerCallback.Stub {
+ private static final String TAG = "radio.TunerCallbackAdapter";
+
@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;
@@ -37,6 +45,14 @@
}
}
+ public void attachTuner(@NonNull ITuner tuner) {
+ synchronized (mLock) {
+ if (mTuner != null) throw new IllegalStateException();
+ mTuner = tuner;
+ if (mPendingProgramInfoChanged) onProgramInfoChanged();
+ }
+ }
+
@Override
public void onError(int status) {
mHandler.post(() -> mCallback.onError(status));
@@ -48,13 +64,28 @@
}
@Override
- public void onProgramInfoChanged(RadioManager.ProgramInfo info) {
- mHandler.post(() -> mCallback.onProgramInfoChanged(info));
- }
+ public void onProgramInfoChanged() {
+ synchronized (mLock) {
+ if (mTuner == null) {
+ mPendingProgramInfoChanged = true;
+ return;
+ }
+ }
- @Override
- public void onMetadataChanged(RadioMetadata metadata) {
- mHandler.post(() -> mCallback.onMetadataChanged(metadata));
+ RadioManager.ProgramInfo info;
+ try {
+ info = mTuner.getProgramInformation();
+ } catch (RemoteException e) {
+ Log.e(TAG, "service died", e);
+ return;
+ }
+
+ mHandler.post(() -> {
+ mCallback.onProgramInfoChanged(info);
+
+ RadioMetadata metadata = info.getMetadata();
+ if (metadata != null) mCallback.onMetadataChanged(metadata);
+ });
}
@Override
diff --git a/services/core/java/com/android/server/radio/TunerCallback.java b/services/core/java/com/android/server/radio/TunerCallback.java
index 9430dc9..62110cf 100644
--- a/services/core/java/com/android/server/radio/TunerCallback.java
+++ b/services/core/java/com/android/server/radio/TunerCallback.java
@@ -86,13 +86,8 @@
}
@Override
- public void onProgramInfoChanged(RadioManager.ProgramInfo info) {
- dispatch(() -> mClientCallback.onProgramInfoChanged(info));
- }
-
- @Override
- public void onMetadataChanged(RadioMetadata metadata) {
- dispatch(() -> mClientCallback.onMetadataChanged(metadata));
+ public void onProgramInfoChanged() {
+ dispatch(() -> mClientCallback.onProgramInfoChanged());
}
@Override
diff --git a/services/core/jni/com_android_server_radio_TunerCallback.cpp b/services/core/jni/com_android_server_radio_TunerCallback.cpp
index 8df92ae7..815a212 100644
--- a/services/core/jni/com_android_server_radio_TunerCallback.cpp
+++ b/services/core/jni/com_android_server_radio_TunerCallback.cpp
@@ -22,9 +22,10 @@
#include "com_android_server_radio_convert.h"
#include "com_android_server_radio_Tuner.h"
+#include <JNIHelp.h>
+#include <Utils.h>
#include <core_jni_helpers.h>
#include <utils/Log.h>
-#include <JNIHelp.h>
namespace android {
namespace server {
@@ -37,11 +38,13 @@
namespace V1_0 = hardware::broadcastradio::V1_0;
namespace V1_1 = hardware::broadcastradio::V1_1;
+using V1_0::Band;
using V1_0::BandConfig;
using V1_0::MetaData;
using V1_0::Result;
using V1_1::ITunerCallback;
using V1_1::ProgramListResult;
+using V1_1::ProgramSelector;
static JavaVM *gvm = nullptr;
@@ -53,7 +56,6 @@
jmethodID onError;
jmethodID onConfigurationChanged;
jmethodID onProgramInfoChanged;
- jmethodID onMetadataChanged;
jmethodID onTrafficAnnouncement;
jmethodID onEmergencyAnnouncement;
jmethodID onAntennaState;
@@ -82,6 +84,8 @@
NativeCallbackThread mCallbackThread;
HalRevision mHalRev;
+ Band mBand;
+
DISALLOW_COPY_AND_ASSIGN(NativeCallback);
public:
@@ -99,11 +103,12 @@
virtual Return<void> emergencyAnnouncement(bool active);
virtual Return<void> newMetadata(uint32_t channel, uint32_t subChannel,
const hidl_vec<MetaData>& metadata);
- virtual Return<void> tuneComplete_1_1(Result result, const V1_1::ProgramInfo& info);
- virtual Return<void> afSwitch_1_1(const V1_1::ProgramInfo& info);
+ 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> programInfoChanged();
};
struct TunerCallbackContext {
@@ -171,24 +176,20 @@
ALOGV("tuneComplete(%d)", result);
if (mHalRev > HalRevision::V1_0) {
- ALOGD("1.0 callback was ignored");
+ ALOGW("1.0 callback was ignored");
return Return<void>();
}
- V1_1::ProgramInfo info_1_1 {
- .base = info,
- };
- return tuneComplete_1_1(result, info_1_1);
+ auto selector = V1_1::utils::make_selector(mBand, info.channel, info.subChannel);
+ return tuneComplete_1_1(result, selector);
}
-Return<void> NativeCallback::tuneComplete_1_1(Result result, const V1_1::ProgramInfo& info) {
+Return<void> NativeCallback::tuneComplete_1_1(Result result, const ProgramSelector& selector) {
ALOGV("tuneComplete_1_1(%d)", result);
- mCallbackThread.enqueue([result, info, this](JNIEnv *env) {
+ mCallbackThread.enqueue([result, this](JNIEnv *env) {
if (result == Result::OK) {
- auto jInfo = convert::ProgramInfoFromHal(env, info);
- if (jInfo == nullptr) return;
- env->CallVoidMethod(mJCallback, gjni.TunerCallback.onProgramInfoChanged, jInfo.get());
+ env->CallVoidMethod(mJCallback, gjni.TunerCallback.onProgramInfoChanged);
} else {
TunerError cause = TunerError::CANCELLED;
if (result == Result::TIMEOUT) cause = TunerError::SCAN_TIMEOUT;
@@ -204,9 +205,9 @@
return tuneComplete(Result::OK, info);
}
-Return<void> NativeCallback::afSwitch_1_1(const V1_1::ProgramInfo& info) {
+Return<void> NativeCallback::afSwitch_1_1(const ProgramSelector& selector) {
ALOGV("afSwitch_1_1()");
- return tuneComplete_1_1(Result::OK, info);
+ return tuneComplete_1_1(Result::OK, selector);
}
Return<void> NativeCallback::antennaStateChange(bool connected) {
@@ -244,10 +245,13 @@
// channel and subChannel are not used
ALOGV("newMetadata(%d, %d)", channel, subChannel);
+ if (mHalRev > HalRevision::V1_0) {
+ ALOGW("1.0 callback was ignored");
+ return Return<void>();
+ }
+
mCallbackThread.enqueue([this, metadata](JNIEnv *env) {
- auto jMetadata = convert::MetadataFromHal(env, metadata);
- if (jMetadata == nullptr) return;
- env->CallVoidMethod(mJCallback, gjni.TunerCallback.onMetadataChanged, jMetadata.get());
+ env->CallVoidMethod(mJCallback, gjni.TunerCallback.onProgramInfoChanged);
});
return Return<void>();
@@ -290,6 +294,16 @@
return Return<void>();
}
+Return<void> NativeCallback::programInfoChanged() {
+ ALOGV("programInfoChanged()");
+
+ mCallbackThread.enqueue([this](JNIEnv *env) {
+ env->CallVoidMethod(mJCallback, gjni.TunerCallback.onProgramInfoChanged);
+ });
+
+ return Return<void>();
+}
+
static TunerCallbackContext& getNativeContext(jlong nativeContextHandle) {
auto nativeContext = reinterpret_cast<TunerCallbackContext*>(nativeContextHandle);
LOG_ALWAYS_FATAL_IF(nativeContext == nullptr, "Native context not initialized");
@@ -363,9 +377,7 @@
gjni.TunerCallback.onConfigurationChanged = GetMethodIDOrDie(env, tunerCbClass,
"onConfigurationChanged", "(Landroid/hardware/radio/RadioManager$BandConfig;)V");
gjni.TunerCallback.onProgramInfoChanged = GetMethodIDOrDie(env, tunerCbClass,
- "onProgramInfoChanged", "(Landroid/hardware/radio/RadioManager$ProgramInfo;)V");
- gjni.TunerCallback.onMetadataChanged = GetMethodIDOrDie(env, tunerCbClass,
- "onMetadataChanged", "(Landroid/hardware/radio/RadioMetadata;)V");
+ "onProgramInfoChanged", "()V");
gjni.TunerCallback.onTrafficAnnouncement = GetMethodIDOrDie(env, tunerCbClass,
"onTrafficAnnouncement", "(Z)V");
gjni.TunerCallback.onEmergencyAnnouncement = GetMethodIDOrDie(env, tunerCbClass,
diff --git a/tests/radio/src/android/hardware/radio/tests/RadioTest.java b/tests/radio/src/android/hardware/radio/tests/RadioTest.java
index 0c6d0e2..aa5780a 100644
--- a/tests/radio/src/android/hardware/radio/tests/RadioTest.java
+++ b/tests/radio/src/android/hardware/radio/tests/RadioTest.java
@@ -44,6 +44,7 @@
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Mockito.after;
+import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.atMost;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.timeout;
@@ -110,7 +111,7 @@
mRadioTuner.close();
mRadioTuner = null;
}
- verifyNoMoreInteractions(mCallback);
+ resetCallback();
}
private void openTuner() {
@@ -118,6 +119,7 @@
}
private void resetCallback() {
+ verify(mCallback, atLeast(0)).onMetadataChanged(any());
verifyNoMoreInteractions(mCallback);
Mockito.reset(mCallback);
}