summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Tomasz Wasilczyk <twasilczyk@google.com> 2018-01-05 21:26:20 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2018-01-05 21:26:20 +0000
commit84c4e9f6a99cf19c23e47cf44b34f6e2142d7a1b (patch)
tree4abf9c7d6aeb453b6126a185b447bf775844e12e
parent25d2bf9c6ab1f97160676dbb7a80dd17e5010941 (diff)
parentca98cde254fef6c31634d8a3069a0d7b76ecf908 (diff)
Merge "Implement part of ITunerSession interface."
-rw-r--r--core/java/android/hardware/radio/RadioManager.java4
-rw-r--r--core/java/android/hardware/radio/TunerAdapter.java1
-rw-r--r--core/tests/BroadcastRadioTests/src/android/hardware/radio/tests/functional/RadioTunerTest.java18
-rw-r--r--services/core/java/com/android/server/broadcastradio/BroadcastRadioService.java2
-rw-r--r--services/core/java/com/android/server/broadcastradio/hal2/BroadcastRadioService.java12
-rw-r--r--services/core/java/com/android/server/broadcastradio/hal2/Convert.java2
-rw-r--r--services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java23
-rw-r--r--services/core/java/com/android/server/broadcastradio/hal2/TunerCallback.java4
-rw-r--r--services/core/java/com/android/server/broadcastradio/hal2/TunerSession.java168
9 files changed, 175 insertions, 59 deletions
diff --git a/core/java/android/hardware/radio/RadioManager.java b/core/java/android/hardware/radio/RadioManager.java
index 9b6515c9ebf1..6e383ae5b026 100644
--- a/core/java/android/hardware/radio/RadioManager.java
+++ b/core/java/android/hardware/radio/RadioManager.java
@@ -1654,8 +1654,8 @@ public class RadioManager {
TunerCallbackAdapter halCallback = new TunerCallbackAdapter(callback, handler);
try {
tuner = mService.openTuner(moduleId, config, withAudio, halCallback);
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to open tuner", e);
+ } catch (RemoteException | IllegalArgumentException ex) {
+ Log.e(TAG, "Failed to open tuner", ex);
return null;
}
if (tuner == null) {
diff --git a/core/java/android/hardware/radio/TunerAdapter.java b/core/java/android/hardware/radio/TunerAdapter.java
index 864d17c2de9f..a8a896a9c452 100644
--- a/core/java/android/hardware/radio/TunerAdapter.java
+++ b/core/java/android/hardware/radio/TunerAdapter.java
@@ -63,6 +63,7 @@ class TunerAdapter extends RadioTuner {
@Override
public int setConfiguration(RadioManager.BandConfig config) {
+ if (config == null) return RadioManager.STATUS_BAD_VALUE;
try {
mTuner.setConfiguration(config);
mBand = config.getType();
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 a8d516405ea2..896fd15d90cd 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
@@ -149,6 +149,10 @@ public class RadioTunerTest {
mRadioTuner = mRadioManager.openTuner(mModule.getId(),
mFmBandConfig, withAudio, mCallback, null);
+ if (!withAudio) {
+ // non-audio sessions might not be supported - if so, then skip the test
+ assumeNotNull(mRadioTuner);
+ }
assertNotNull(mRadioTuner);
verify(mCallback, timeout(kConfigCallbackTimeoutMs)).onConfigurationChanged(any());
resetCallback();
@@ -207,20 +211,8 @@ public class RadioTunerTest {
public void testSetBadConfiguration() throws Throwable {
openTuner();
- // set bad config
- Constructor<RadioManager.AmBandConfig> configConstr =
- RadioManager.AmBandConfig.class.getDeclaredConstructor(
- int.class, int.class, int.class, int.class, int.class, boolean.class);
- configConstr.setAccessible(true);
- RadioManager.AmBandConfig badConfig = configConstr.newInstance(
- 0 /*region*/, RadioManager.BAND_AM /*type*/,
- 10000 /*lowerLimit*/, 1 /*upperLimit*/, 100 /*spacing*/, false /*stereo*/);
- int ret = mRadioTuner.setConfiguration(badConfig);
- assertEquals(RadioManager.STATUS_BAD_VALUE, ret);
- verify(mCallback, never()).onConfigurationChanged(any());
-
// set null config
- ret = mRadioTuner.setConfiguration(null);
+ int ret = mRadioTuner.setConfiguration(null);
assertEquals(RadioManager.STATUS_BAD_VALUE, ret);
verify(mCallback, never()).onConfigurationChanged(any());
diff --git a/services/core/java/com/android/server/broadcastradio/BroadcastRadioService.java b/services/core/java/com/android/server/broadcastradio/BroadcastRadioService.java
index ef5166579cb3..7d3b670bdfa3 100644
--- a/services/core/java/com/android/server/broadcastradio/BroadcastRadioService.java
+++ b/services/core/java/com/android/server/broadcastradio/BroadcastRadioService.java
@@ -94,7 +94,7 @@ public class BroadcastRadioService extends SystemService {
}
synchronized (mLock) {
if (mHal2.hasModule(moduleId)) {
- return mHal2.openSession(moduleId, callback);
+ return mHal2.openSession(moduleId, bandConfig, withAudio, callback);
} else {
return mHal1.openTuner(moduleId, bandConfig, withAudio, callback);
}
diff --git a/services/core/java/com/android/server/broadcastradio/hal2/BroadcastRadioService.java b/services/core/java/com/android/server/broadcastradio/hal2/BroadcastRadioService.java
index 413a27ce9af0..9158ff0cb66f 100644
--- a/services/core/java/com/android/server/broadcastradio/hal2/BroadcastRadioService.java
+++ b/services/core/java/com/android/server/broadcastradio/hal2/BroadcastRadioService.java
@@ -17,6 +17,7 @@
package com.android.server.broadcastradio.hal2;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.hardware.radio.ITuner;
import android.hardware.radio.ITunerCallback;
import android.hardware.radio.RadioManager;
@@ -80,14 +81,21 @@ public class BroadcastRadioService {
return mModules.containsKey(id);
}
- public ITuner openSession(int moduleId, @NonNull ITunerCallback callback) {
+ public ITuner openSession(int moduleId, @Nullable RadioManager.BandConfig legacyConfig,
+ boolean withAudio, @NonNull ITunerCallback callback) {
Objects.requireNonNull(callback);
+ if (!withAudio) {
+ throw new IllegalArgumentException("Non-audio sessions not supported with HAL 2.x");
+ }
+
RadioModule module = mModules.get(moduleId);
if (module == null) {
throw new IllegalArgumentException("Invalid module ID");
}
- return module.openSession(callback);
+ TunerSession session = module.openSession(callback);
+ session.setConfiguration(legacyConfig);
+ return session;
}
}
diff --git a/services/core/java/com/android/server/broadcastradio/hal2/Convert.java b/services/core/java/com/android/server/broadcastradio/hal2/Convert.java
index 434e2620a324..2c129bbac33e 100644
--- a/services/core/java/com/android/server/broadcastradio/hal2/Convert.java
+++ b/services/core/java/com/android/server/broadcastradio/hal2/Convert.java
@@ -186,7 +186,7 @@ class Convert {
false, // isCaptureSupported
amfmConfigToBands(amfmConfig),
- true, // isBgScanSupported is deprecated
+ false, // isBgScanSupported is deprecated
supportedProgramTypes,
supportedIdentifierTypes,
vendorInfoFromHal(prop.vendorInfo));
diff --git a/services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java b/services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java
index 8a7ac7355b7e..45b21900ff33 100644
--- a/services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java
+++ b/services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java
@@ -63,7 +63,7 @@ class RadioModule {
}
}
- public @NonNull ITuner openSession(@NonNull android.hardware.radio.ITunerCallback userCb) {
+ public @NonNull TunerSession openSession(@NonNull android.hardware.radio.ITunerCallback userCb) {
TunerCallback cb = new TunerCallback(Objects.requireNonNull(userCb));
Mutable<ITunerSession> hwSession = new Mutable<>();
MutableInt halResult = new MutableInt(Result.UNKNOWN_ERROR);
@@ -81,25 +81,6 @@ class RadioModule {
Convert.throwOnError("openSession", halResult.value);
Objects.requireNonNull(hwSession.value);
- TunerSession session = new TunerSession(hwSession.value, cb);
-
- // send out legacy callback about band configuration
- RadioManager.BandDescriptor[] bands = mProperties.getBands();
- if (bands != null && bands.length > 0) {
- RadioManager.BandDescriptor descr = bands[0]; // just pick first
- Mutable<RadioManager.BandConfig> config = new Mutable<>();
- if (descr instanceof RadioManager.FmBandDescriptor) {
- config.value = new RadioManager.FmBandConfig((RadioManager.FmBandDescriptor)descr);
- } else if (descr instanceof RadioManager.AmBandDescriptor) {
- config.value = new RadioManager.AmBandConfig((RadioManager.AmBandDescriptor)descr);
- } else {
- Slog.w(TAG, "Descriptor is neither AM nor FM");
- }
- if (config.value != null) {
- TunerCallback.dispatch(() -> userCb.onConfigurationChanged(config.value));
- }
- }
-
- return session;
+ return new TunerSession(hwSession.value, cb);
}
}
diff --git a/services/core/java/com/android/server/broadcastradio/hal2/TunerCallback.java b/services/core/java/com/android/server/broadcastradio/hal2/TunerCallback.java
index 5ee6a4c693cd..c9084ee9517a 100644
--- a/services/core/java/com/android/server/broadcastradio/hal2/TunerCallback.java
+++ b/services/core/java/com/android/server/broadcastradio/hal2/TunerCallback.java
@@ -31,14 +31,14 @@ import java.util.Objects;
class TunerCallback extends ITunerCallback.Stub {
private static final String TAG = "BcRadio2Srv.cb";
- final android.hardware.radio.ITunerCallback mCb;
+ final android.hardware.radio.ITunerCallback mClientCb;
interface RunnableThrowingRemoteException {
void run() throws RemoteException;
}
TunerCallback(@NonNull android.hardware.radio.ITunerCallback clientCallback) {
- mCb = Objects.requireNonNull(clientCallback);
+ mClientCb = Objects.requireNonNull(clientCallback);
}
static void dispatch(RunnableThrowingRemoteException func) {
diff --git a/services/core/java/com/android/server/broadcastradio/hal2/TunerSession.java b/services/core/java/com/android/server/broadcastradio/hal2/TunerSession.java
index e8faf3dfa63f..c4ec94f1183b 100644
--- a/services/core/java/com/android/server/broadcastradio/hal2/TunerSession.java
+++ b/services/core/java/com/android/server/broadcastradio/hal2/TunerSession.java
@@ -18,10 +18,16 @@ package com.android.server.broadcastradio.hal2;
import android.annotation.NonNull;
import android.graphics.Bitmap;
+import android.hardware.broadcastradio.V2_0.ConfigFlag;
import android.hardware.broadcastradio.V2_0.ITunerSession;
+import android.hardware.broadcastradio.V2_0.Result;
import android.hardware.radio.ITuner;
import android.hardware.radio.ProgramSelector;
import android.hardware.radio.RadioManager;
+import android.media.AudioSystem;
+import android.os.RemoteException;
+import android.util.MutableBoolean;
+import android.util.MutableInt;
import android.util.Slog;
import java.util.List;
@@ -30,16 +36,23 @@ import java.util.Objects;
class TunerSession extends ITuner.Stub {
private static final String TAG = "BcRadio2Srv.session";
+ private static final String kAudioDeviceName = "Radio tuner source";
private final Object mLock = new Object();
private final ITunerSession mHwSession;
private final TunerCallback mCallback;
private boolean mIsClosed = false;
+ private boolean mIsAudioConnected = false;
+ private boolean mIsMuted = false;
+
+ // necessary only for older APIs compatibility
+ private RadioManager.BandConfig mDummyConfig = null;
TunerSession(@NonNull ITunerSession hwSession, @NonNull TunerCallback callback) {
mHwSession = Objects.requireNonNull(hwSession);
mCallback = Objects.requireNonNull(callback);
+ notifyAudioServiceLocked(true);
}
@Override
@@ -47,6 +60,7 @@ class TunerSession extends ITuner.Stub {
synchronized (mLock) {
if (mIsClosed) return;
mIsClosed = true;
+ notifyAudioServiceLocked(false);
}
}
@@ -61,77 +75,197 @@ class TunerSession extends ITuner.Stub {
}
}
+ private void notifyAudioServiceLocked(boolean connected) {
+ if (mIsAudioConnected == connected) return;
+
+ Slog.d(TAG, "Notifying AudioService about new state: " + connected);
+ int ret = AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_IN_FM_TUNER,
+ connected ? AudioSystem.DEVICE_STATE_AVAILABLE : AudioSystem.DEVICE_STATE_UNAVAILABLE,
+ null, kAudioDeviceName);
+
+ if (ret == AudioSystem.AUDIO_STATUS_OK) {
+ mIsAudioConnected = connected;
+ } else {
+ Slog.e(TAG, "Failed to notify AudioService about new state: " + connected);
+ }
+ }
+
@Override
- public void setConfiguration(RadioManager.BandConfig config) {}
+ public void setConfiguration(RadioManager.BandConfig config) {
+ synchronized (mLock) {
+ checkNotClosedLocked();
+ mDummyConfig = Objects.requireNonNull(config);
+ Slog.i(TAG, "Ignoring setConfiguration - not applicable for broadcastradio HAL 2.x");
+ TunerCallback.dispatch(() -> mCallback.mClientCb.onConfigurationChanged(config));
+ }
+ }
@Override
public RadioManager.BandConfig getConfiguration() {
- return null;
+ synchronized (mLock) {
+ checkNotClosedLocked();
+ return mDummyConfig;
+ }
}
@Override
- public void setMuted(boolean mute) {}
+ public void setMuted(boolean mute) {
+ synchronized (mLock) {
+ checkNotClosedLocked();
+ if (mIsMuted == mute) return;
+ mIsMuted = mute;
+ notifyAudioServiceLocked(!mute);
+ }
+ }
@Override
public boolean isMuted() {
- return false;
+ synchronized (mLock) {
+ checkNotClosedLocked();
+ return mIsMuted;
+ }
}
@Override
- public void step(boolean directionDown, boolean skipSubChannel) {}
+ public void step(boolean directionDown, boolean skipSubChannel) {
+ synchronized (mLock) {
+ checkNotClosedLocked();
+ }
+ }
@Override
- public void scan(boolean directionDown, boolean skipSubChannel) {}
+ public void scan(boolean directionDown, boolean skipSubChannel) {
+ synchronized (mLock) {
+ checkNotClosedLocked();
+ }
+ }
@Override
- public void tune(ProgramSelector selector) {}
+ public void tune(ProgramSelector selector) {
+ synchronized (mLock) {
+ checkNotClosedLocked();
+ }
+ }
@Override
- public void cancel() {}
+ public void cancel() {
+ synchronized (mLock) {
+ checkNotClosedLocked();
+ }
+ }
@Override
- public void cancelAnnouncement() {}
+ public void cancelAnnouncement() {
+ synchronized (mLock) {
+ checkNotClosedLocked();
+ }
+ }
@Override
public RadioManager.ProgramInfo getProgramInformation() {
- return null;
+ synchronized (mLock) {
+ checkNotClosedLocked();
+ return null;
+ }
}
@Override
public Bitmap getImage(int id) {
- return null;
+ synchronized (mLock) {
+ checkNotClosedLocked();
+ return null;
+ }
}
@Override
public boolean startBackgroundScan() {
+ Slog.i(TAG, "Explicit background scan trigger is not supported with HAL 2.x");
return false;
}
@Override
public List<RadioManager.ProgramInfo> getProgramList(Map vendorFilter) {
- return null;
+ synchronized (mLock) {
+ checkNotClosedLocked();
+ return null;
+ }
+ }
+
+ private boolean getConfigFlag(int flag) {
+ Slog.v(TAG, "getConfigFlag " + ConfigFlag.toString(flag));
+ synchronized (mLock) {
+ checkNotClosedLocked();
+
+ MutableInt halResult = new MutableInt(Result.UNKNOWN_ERROR);
+ MutableBoolean flagState = new MutableBoolean(false);
+ try {
+ mHwSession.getConfigFlag(flag, (int result, boolean value) -> {
+ halResult.value = result;
+ flagState.value = value;
+ });
+ } catch (RemoteException ex) {
+ throw new RuntimeException("Failed to get flag " + ConfigFlag.toString(flag), ex);
+ }
+ Convert.throwOnError("getConfigFlag", halResult.value);
+
+ return flagState.value;
+ }
+ }
+
+ private void setConfigFlag(int flag, boolean value) {
+ Slog.v(TAG, "setConfigFlag " + ConfigFlag.toString(flag) + " = " + value);
+ synchronized (mLock) {
+ checkNotClosedLocked();
+
+ int halResult;
+ try {
+ halResult = mHwSession.setConfigFlag(flag, value);
+ } catch (RemoteException ex) {
+ throw new RuntimeException("Failed to set flag " + ConfigFlag.toString(flag), ex);
+ }
+ Convert.throwOnError("setConfigFlag", halResult);
+ }
}
@Override
public boolean isAnalogForced() {
- return false;
+ try {
+ return getConfigFlag(ConfigFlag.FORCE_ANALOG);
+ } catch (UnsupportedOperationException ex) {
+ throw new IllegalStateException(ex);
+ }
}
@Override
- public void setAnalogForced(boolean isForced) {}
+ public void setAnalogForced(boolean isForced) {
+ try {
+ setConfigFlag(ConfigFlag.FORCE_ANALOG, isForced);
+ } catch (UnsupportedOperationException ex) {
+ throw new IllegalStateException(ex);
+ }
+ }
@Override
public Map setParameters(Map parameters) {
- return null;
+ synchronized (mLock) {
+ checkNotClosedLocked();
+ return null;
+ }
}
@Override
public Map getParameters(List<String> keys) {
- return null;
+ synchronized (mLock) {
+ checkNotClosedLocked();
+ return null;
+ }
}
@Override
public boolean isAntennaConnected() {
- return true;
+ synchronized (mLock) {
+ checkNotClosedLocked();
+ return true;
+ }
}
}