Don't play the end call tone when the ringer is silenced.
Test: Manual test with device in silence and regular modes.
Test: Added new unit tests.
Bug: 74724897
Change-Id: I27b9fbfe34108d3e22f79673d3090df31f744165
diff --git a/src/com/android/server/telecom/CallsManager.java b/src/com/android/server/telecom/CallsManager.java
index d99a51a..101ecf8 100644
--- a/src/com/android/server/telecom/CallsManager.java
+++ b/src/com/android/server/telecom/CallsManager.java
@@ -437,7 +437,8 @@
(resourceId, attributes) -> MediaPlayer.create(mContext, resourceId, attributes,
audioManager.generateAudioSessionId());
InCallTonePlayer.Factory playerFactory = new InCallTonePlayer.Factory(
- callAudioRoutePeripheralAdapter, lock, toneGeneratorFactory, mediaPlayerFactory);
+ callAudioRoutePeripheralAdapter, lock, toneGeneratorFactory, mediaPlayerFactory,
+ () -> audioManager.getStreamVolume(AudioManager.STREAM_RING) > 0);
SystemSettingsUtil systemSettingsUtil = new SystemSettingsUtil();
RingtoneFactory ringtoneFactory = new RingtoneFactory(this, context);
diff --git a/src/com/android/server/telecom/InCallTonePlayer.java b/src/com/android/server/telecom/InCallTonePlayer.java
index 8314dd9..1c9801c 100644
--- a/src/com/android/server/telecom/InCallTonePlayer.java
+++ b/src/com/android/server/telecom/InCallTonePlayer.java
@@ -49,14 +49,16 @@
private final TelecomSystem.SyncRoot mLock;
private final ToneGeneratorFactory mToneGeneratorFactory;
private final MediaPlayerFactory mMediaPlayerFactory;
+ private final AudioManagerAdapter mAudioManagerAdapter;
- Factory(CallAudioRoutePeripheralAdapter callAudioRoutePeripheralAdapter,
+ public Factory(CallAudioRoutePeripheralAdapter callAudioRoutePeripheralAdapter,
TelecomSystem.SyncRoot lock, ToneGeneratorFactory toneGeneratorFactory,
- MediaPlayerFactory mediaPlayerFactory) {
+ MediaPlayerFactory mediaPlayerFactory, AudioManagerAdapter audioManagerAdapter) {
mCallAudioRoutePeripheralAdapter = callAudioRoutePeripheralAdapter;
mLock = lock;
mToneGeneratorFactory = toneGeneratorFactory;
mMediaPlayerFactory = mediaPlayerFactory;
+ mAudioManagerAdapter = audioManagerAdapter;
}
public void setCallAudioManager(CallAudioManager callAudioManager) {
@@ -66,7 +68,7 @@
public InCallTonePlayer createPlayer(int tone) {
return new InCallTonePlayer(tone, mCallAudioManager,
mCallAudioRoutePeripheralAdapter, mLock, mToneGeneratorFactory,
- mMediaPlayerFactory);
+ mMediaPlayerFactory, mAudioManagerAdapter);
}
}
@@ -78,6 +80,10 @@
MediaPlayer get (int resourceId, AudioAttributes attributes);
}
+ public interface AudioManagerAdapter {
+ boolean isVolumeOverZero();
+ }
+
// The possible tones that we can play.
public static final int TONE_INVALID = 0;
public static final int TONE_BUSY = 1;
@@ -140,6 +146,7 @@
private final ToneGeneratorFactory mToneGenerator;
private final MediaPlayerFactory mMediaPlayerFactory;
+ private final AudioManagerAdapter mAudioManagerAdapter;
/**
* Initializes the tone player. Private; use the {@link Factory} to create tone players.
@@ -152,7 +159,8 @@
CallAudioRoutePeripheralAdapter callAudioRoutePeripheralAdapter,
TelecomSystem.SyncRoot lock,
ToneGeneratorFactory toneGeneratorFactory,
- MediaPlayerFactory mediaPlayerFactor) {
+ MediaPlayerFactory mediaPlayerFactor,
+ AudioManagerAdapter audioManagerAdapter) {
mState = STATE_OFF;
mToneId = toneId;
mCallAudioManager = callAudioManager;
@@ -160,6 +168,7 @@
mLock = lock;
mToneGenerator = toneGeneratorFactory;
mMediaPlayerFactory = mediaPlayerFactor;
+ mAudioManagerAdapter = audioManagerAdapter;
}
/** {@inheritDoc} */
@@ -378,6 +387,12 @@
@VisibleForTesting
public void startTone() {
+ // Skip playing the end call tone if the volume is silenced.
+ if (mToneId == TONE_CALL_ENDED && !mAudioManagerAdapter.isVolumeOverZero()) {
+ Log.i(this, "startTone: skip end-call tone as device is silenced.");
+ return;
+ }
+
sTonesPlaying++;
if (sTonesPlaying == 1) {
mCallAudioManager.setIsTonePlaying(true);
diff --git a/tests/src/com/android/server/telecom/tests/InCallTonePlayerTest.java b/tests/src/com/android/server/telecom/tests/InCallTonePlayerTest.java
new file mode 100644
index 0000000..af5c36b
--- /dev/null
+++ b/tests/src/com/android/server/telecom/tests/InCallTonePlayerTest.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.telecom.tests;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.timeout;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import com.android.server.telecom.CallAudioManager;
+import com.android.server.telecom.CallAudioRoutePeripheralAdapter;
+import com.android.server.telecom.InCallTonePlayer;
+import com.android.server.telecom.TelecomSystem;
+
+import android.media.MediaPlayer;
+import android.media.ToneGenerator;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import org.mockito.Mock;
+
+@RunWith(JUnit4.class)
+public class InCallTonePlayerTest extends TelecomTestCase {
+
+ private InCallTonePlayer.Factory mFactory;
+
+ @Mock
+ private CallAudioRoutePeripheralAdapter mCallAudioRoutePeripheralAdapter;
+
+ @Mock
+ private TelecomSystem.SyncRoot mLock;
+
+ @Mock
+ private ToneGenerator mToneGenerator;
+
+ @Mock
+ private InCallTonePlayer.ToneGeneratorFactory mToneGeneratorFactory;
+
+ private MediaPlayer mMediaPlayer;
+
+ @Mock
+ private InCallTonePlayer.MediaPlayerFactory mMediaPlayerFactory;
+
+ @Mock
+ private InCallTonePlayer.AudioManagerAdapter mAudioManagerAdapter;
+
+ @Mock
+ private CallAudioManager mCallAudioManager;
+
+ @Override
+ @Before
+ public void setUp() throws Exception {
+ super.setUp();
+ mFactory = new InCallTonePlayer.Factory(mCallAudioRoutePeripheralAdapter, mLock,
+ mToneGeneratorFactory, mMediaPlayerFactory, mAudioManagerAdapter);
+ mFactory.setCallAudioManager(mCallAudioManager);
+
+ when(mToneGeneratorFactory.get(anyInt(), anyInt())).thenReturn(mToneGenerator);
+
+ mMediaPlayer = new MediaPlayer();
+ when(mMediaPlayerFactory.get(anyInt(), any())).thenReturn(mMediaPlayer);
+ }
+
+ @SmallTest
+ @Test
+ public void testNoEndCallToneInSilence() {
+ when(mAudioManagerAdapter.isVolumeOverZero()).thenReturn(false);
+ InCallTonePlayer player = mFactory.createPlayer(InCallTonePlayer.TONE_CALL_ENDED);
+ player.startTone();
+
+ // Verify we didn't play a tone.
+ verify(mCallAudioManager, never()).setIsTonePlaying(eq(true));
+ verify(mMediaPlayerFactory, never()).get(anyInt(), any());
+ }
+
+ @SmallTest
+ @Test
+ public void testEndCallToneWhenNotSilenced() {
+ when(mAudioManagerAdapter.isVolumeOverZero()).thenReturn(true);
+ InCallTonePlayer player = mFactory.createPlayer(InCallTonePlayer.TONE_CALL_ENDED);
+ player.startTone();
+
+ // Verify we did play a tone.
+ verify(mCallAudioManager).setIsTonePlaying(eq(true));
+ verify(mMediaPlayerFactory ,timeout(5000)).get(anyInt(), any());
+ }
+}