diff --git a/core/java/android/hardware/radio/ITuner.aidl b/core/java/android/hardware/radio/ITuner.aidl index c08f41ff17ed5..e09720dccece6 100644 --- a/core/java/android/hardware/radio/ITuner.aidl +++ b/core/java/android/hardware/radio/ITuner.aidl @@ -30,4 +30,11 @@ interface ITuner { RadioManager.BandConfig getConfiguration(); int getProgramInformation(out RadioManager.ProgramInfo[] infoOut); + + /** + * @throws IllegalStateException if tuner was opened without audio + */ + void setMuted(boolean mute); + + boolean isMuted(); } diff --git a/core/java/android/hardware/radio/TunerAdapter.java b/core/java/android/hardware/radio/TunerAdapter.java index 1156fe808719a..0dddf3b41a648 100644 --- a/core/java/android/hardware/radio/TunerAdapter.java +++ b/core/java/android/hardware/radio/TunerAdapter.java @@ -21,7 +21,6 @@ import android.annotation.Nullable; import android.os.RemoteException; import android.util.Log; -import java.util.ArrayList; import java.util.List; /** @@ -65,7 +64,8 @@ class TunerAdapter extends RadioTuner { Log.e(TAG, "Can't set configuration", e); return RadioManager.STATUS_BAD_VALUE; } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + Log.e(TAG, "service died", e); + return RadioManager.STATUS_DEAD_OBJECT; } } @@ -78,20 +78,33 @@ class TunerAdapter extends RadioTuner { config[0] = mTuner.getConfiguration(); return RadioManager.STATUS_OK; } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + Log.e(TAG, "service died", e); + return RadioManager.STATUS_DEAD_OBJECT; } } @Override public int setMute(boolean mute) { - // TODO(b/36863239): forward to mTuner - throw new RuntimeException("Not implemented"); + try { + mTuner.setMuted(mute); + } catch (IllegalStateException e) { + Log.e(TAG, "Can't set muted", e); + return RadioManager.STATUS_ERROR; + } catch (RemoteException e) { + Log.e(TAG, "service died", e); + return RadioManager.STATUS_DEAD_OBJECT; + } + return RadioManager.STATUS_OK; } @Override public boolean getMute() { - // TODO(b/36863239): forward to mTuner - throw new RuntimeException("Not implemented"); + try { + return mTuner.isMuted(); + } catch (RemoteException e) { + Log.e(TAG, "service died", e); + return true; + } } @Override @@ -126,7 +139,8 @@ class TunerAdapter extends RadioTuner { try { return mTuner.getProgramInformation(info); } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + Log.e(TAG, "service died", e); + return RadioManager.STATUS_DEAD_OBJECT; } } diff --git a/services/core/java/com/android/server/radio/Tuner.java b/services/core/java/com/android/server/radio/Tuner.java index a06d8c6a8c8da..0f4088310a593 100644 --- a/services/core/java/com/android/server/radio/Tuner.java +++ b/services/core/java/com/android/server/radio/Tuner.java @@ -32,10 +32,13 @@ class Tuner extends ITuner.Stub { private final long mNativeContext; private final Object mLock = new Object(); + private boolean mIsMuted = false; private int mRegion; // TODO(b/36863239): find better solution to manage regions + private final boolean mWithAudio; - Tuner(@NonNull ITunerCallback clientCallback, int region) { + Tuner(@NonNull ITunerCallback clientCallback, int region, boolean withAudio) { mRegion = region; + mWithAudio = withAudio; mNativeContext = nativeInit(clientCallback); } @@ -86,4 +89,29 @@ class Tuner extends ITuner.Stub { Slog.d(TAG, "getProgramInformation()"); return RadioManager.STATUS_INVALID_OPERATION; } + + @Override + public void setMuted(boolean mute) { + if (!mWithAudio) { + throw new IllegalStateException("Can't operate on mute - no audio requested"); + } + synchronized (mLock) { + if (mIsMuted == mute) return; + mIsMuted = mute; + + // TODO(b/34348946): notifify audio policy manager of media activity on radio audio + // device. This task is pulled directly from previous implementation of native service. + } + } + + @Override + public boolean isMuted() { + if (!mWithAudio) { + Slog.w(TAG, "Tuner did not request audio, pretending it was muted"); + return true; + } + synchronized (mLock) { + return mIsMuted; + } + } } diff --git a/services/core/jni/com_android_server_radio_RadioService.cpp b/services/core/jni/com_android_server_radio_RadioService.cpp index a6bcdbb390123..8b53b1b582fee 100644 --- a/services/core/jni/com_android_server_radio_RadioService.cpp +++ b/services/core/jni/com_android_server_radio_RadioService.cpp @@ -136,7 +136,7 @@ static jobject nativeOpenTuner(JNIEnv *env, jobject obj, long nativeContext, jin Region region; BandConfig bandConfigHal = convert::BandConfigToHal(env, bandConfig, region); - jobject tuner = env->NewObject(gTunerClass, gTunerCstor, callback, region); + jobject tuner = env->NewObject(gTunerClass, gTunerCstor, callback, region, withAudio); if (tuner == nullptr) { ALOGE("Unable to create new tuner object."); return nullptr; @@ -184,7 +184,7 @@ void register_android_server_radio_RadioService(JNIEnv *env) { auto tunerClass = FindClassOrDie(env, "com/android/server/radio/Tuner"); gTunerClass = MakeGlobalRefOrDie(env, tunerClass); gTunerCstor = GetMethodIDOrDie(env, tunerClass, "", - "(Landroid/hardware/radio/ITunerCallback;I)V"); + "(Landroid/hardware/radio/ITunerCallback;IZ)V"); auto serviceClass = FindClassOrDie(env, "com/android/server/radio/RadioService"); gServiceClass = MakeGlobalRefOrDie(env, serviceClass); diff --git a/tests/radio/src/android/hardware/radio/tests/RadioTest.java b/tests/radio/src/android/hardware/radio/tests/RadioTest.java index 7ab5618e7e516..82b29035b0be8 100644 --- a/tests/radio/src/android/hardware/radio/tests/RadioTest.java +++ b/tests/radio/src/android/hardware/radio/tests/RadioTest.java @@ -92,6 +92,10 @@ public class RadioTest { } private void openTuner() { + openTuner(true); + } + + private void openTuner(boolean withAudio) { assertNull(mRadioTuner); // find FM band and build its config @@ -109,7 +113,8 @@ public class RadioTest { mAmBandConfig = new RadioManager.AmBandConfig.Builder(mAmBandDescriptor).build(); mFmBandConfig = new RadioManager.FmBandConfig.Builder(mFmBandDescriptor).build(); - mRadioTuner = mRadioManager.openTuner(module.getId(), mFmBandConfig, true, mCallback, null); + mRadioTuner = mRadioManager.openTuner(module.getId(), + mFmBandConfig, withAudio, mCallback, null); assertNotNull(mRadioTuner); verify(mCallback, timeout(kConfigCallbacktimeoutNs).times(1)).onConfigurationChanged(any()); verify(mCallback, never()).onError(anyInt()); @@ -178,4 +183,33 @@ public class RadioTest { verify(mCallback, never()).onError(anyInt()); } + + @Test + public void testMute() { + openTuner(); + + boolean isMuted = mRadioTuner.getMute(); + assertFalse(isMuted); + + int ret = mRadioTuner.setMute(true); + assertEquals(RadioManager.STATUS_OK, ret); + isMuted = mRadioTuner.getMute(); + assertTrue(isMuted); + + ret = mRadioTuner.setMute(false); + assertEquals(RadioManager.STATUS_OK, ret); + isMuted = mRadioTuner.getMute(); + assertFalse(isMuted); + } + + @Test + public void testMuteNoAudio() { + openTuner(false); + + int ret = mRadioTuner.setMute(false); + assertEquals(RadioManager.STATUS_ERROR, ret); + + boolean isMuted = mRadioTuner.getMute(); + assertTrue(isMuted); + } }