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());
+    }
+}