InCallTonePlayer.java revision 7062bb96f567e7dc9c7bf933b7bee17bb2c8108c
1a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon/* 2a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon * Copyright 2014, The Android Open Source Project 3a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon * 4a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon * Licensed under the Apache License, Version 2.0 (the "License"); 5a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon * you may not use this file except in compliance with the License. 6a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon * You may obtain a copy of the License at 7a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon * 8a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon * http://www.apache.org/licenses/LICENSE-2.0 9a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon * 10a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon * Unless required by applicable law or agreed to in writing, software 11a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon * distributed under the License is distributed on an "AS IS" BASIS, 12a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon * See the License for the specific language governing permissions and 14a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon * limitations under the License. 15a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon */ 16a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon 177cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunnpackage com.android.server.telecom; 18a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon 19a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordonimport android.media.AudioManager; 20a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordonimport android.media.ToneGenerator; 21a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordonimport android.os.Handler; 22a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordonimport android.os.Looper; 23a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon 24a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon/** 25a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon * Play a call-related tone (ringback, busy signal, etc.) through ToneGenerator. To use, create an 26a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon * instance using InCallTonePlayer.Factory (passing in the TONE_* constant for the tone you want) 27a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon * and start() it. Implemented on top of {@link Thread} so that the tone plays in its own thread. 28a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon */ 29a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordonpublic final class InCallTonePlayer extends Thread { 30a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon 31a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon /** 32a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon * Factory used to create InCallTonePlayers. Exists to aid with testing mocks. 33a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon */ 34a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon public static class Factory { 35a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon private final CallAudioManager mCallAudioManager; 36a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon 37a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon Factory(CallAudioManager callAudioManager) { 38a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon mCallAudioManager = callAudioManager; 39a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon } 40a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon 41a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon InCallTonePlayer createPlayer(int tone) { 42a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon return new InCallTonePlayer(tone, mCallAudioManager); 43a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon } 44a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon } 45a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon 46a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon // The possible tones that we can play. 47c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon public static final int TONE_INVALID = 0; 48c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon public static final int TONE_BUSY = 1; 49c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon public static final int TONE_CALL_ENDED = 2; 50c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon public static final int TONE_OTA_CALL_ENDED = 3; 51c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon public static final int TONE_CALL_WAITING = 4; 52c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon public static final int TONE_CDMA_DROP = 5; 53c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon public static final int TONE_CONGESTION = 6; 54c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon public static final int TONE_INTERCEPT = 7; 55c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon public static final int TONE_OUT_OF_SERVICE = 8; 56c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon public static final int TONE_REDIAL = 9; 57c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon public static final int TONE_REORDER = 10; 58c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon public static final int TONE_RING_BACK = 11; 59c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon public static final int TONE_UNOBTAINABLE_NUMBER = 12; 60c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon public static final int TONE_VOICE_PRIVACY = 13; 61a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon 62a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon private static final int RELATIVE_VOLUME_EMERGENCY = 100; 63a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon private static final int RELATIVE_VOLUME_HIPRI = 80; 64a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon private static final int RELATIVE_VOLUME_LOPRI = 50; 65a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon 66a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon // Buffer time (in msec) to add on to the tone timeout value. Needed mainly when the timeout 67a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon // value for a tone is exact duration of the tone itself. 688c85dee84fbbd8c36cf1c7b061001c6129623f92Sailesh Nepal private static final int TIMEOUT_BUFFER_MILLIS = 20; 69a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon 70a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon // The tone state. 71a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon private static final int STATE_OFF = 0; 72a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon private static final int STATE_ON = 1; 73a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon private static final int STATE_STOPPED = 2; 74a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon 75a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon /** 76a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon * Keeps count of the number of actively playing tones so that we can notify CallAudioManager 77a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon * when we need focus and when it can be release. This should only be manipulated from the main 78a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon * thread. 79a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon */ 80a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon private static int sTonesPlaying = 0; 81a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon 82a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon private final CallAudioManager mCallAudioManager; 83a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon 84a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon private final Handler mMainThreadHandler = new Handler(Looper.getMainLooper()); 85a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon 86a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon /** The ID of the tone to play. */ 87a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon private final int mToneId; 88a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon 89a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon /** Current state of the tone player. */ 90a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon private int mState; 91a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon 92a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon /** 93a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon * Initializes the tone player. Private; use the {@link Factory} to create tone players. 94a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon * 95a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon * @param toneId ID of the tone to play, see TONE_* constants. 96a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon */ 97a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon private InCallTonePlayer(int toneId, CallAudioManager callAudioManager) { 98a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon mState = STATE_OFF; 99a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon mToneId = toneId; 100a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon mCallAudioManager = callAudioManager; 101a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon } 102a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon 103a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon /** {@inheritDoc} */ 104a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon @Override 105a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon public void run() { 106a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon ToneGenerator toneGenerator = null; 107a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon try { 108a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon Log.d(this, "run(toneId = %s)", mToneId); 109a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon 110a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon final int toneType; // Passed to ToneGenerator.startTone. 111a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon final int toneVolume; // Passed to the ToneGenerator constructor. 1128c85dee84fbbd8c36cf1c7b061001c6129623f92Sailesh Nepal final int toneLengthMillis; 113a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon 114a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon switch (mToneId) { 115c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon case TONE_BUSY: 116c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon // TODO: CDMA-specific tones 117c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon toneType = ToneGenerator.TONE_SUP_BUSY; 118c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon toneVolume = RELATIVE_VOLUME_HIPRI; 1198c85dee84fbbd8c36cf1c7b061001c6129623f92Sailesh Nepal toneLengthMillis = 4000; 120c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon break; 121c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon case TONE_CALL_ENDED: 122c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon toneType = ToneGenerator.TONE_PROP_PROMPT; 123c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon toneVolume = RELATIVE_VOLUME_HIPRI; 1247062bb96f567e7dc9c7bf933b7bee17bb2c8108cYorke Lee toneLengthMillis = 200; 125c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon break; 126c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon case TONE_OTA_CALL_ENDED: 127c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon // TODO: fill in 128c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon throw new IllegalStateException("OTA Call ended NYI."); 129c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon case TONE_CALL_WAITING: 13040f78c210512570f14cdfde9613dd85c510a1c0cSantos Cordon toneType = ToneGenerator.TONE_SUP_CALL_WAITING; 13140f78c210512570f14cdfde9613dd85c510a1c0cSantos Cordon toneVolume = RELATIVE_VOLUME_HIPRI; 13240f78c210512570f14cdfde9613dd85c510a1c0cSantos Cordon toneLengthMillis = Integer.MAX_VALUE - TIMEOUT_BUFFER_MILLIS; 13340f78c210512570f14cdfde9613dd85c510a1c0cSantos Cordon break; 134c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon case TONE_CDMA_DROP: 135c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon toneType = ToneGenerator.TONE_CDMA_CALLDROP_LITE; 136c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon toneVolume = RELATIVE_VOLUME_LOPRI; 1378c85dee84fbbd8c36cf1c7b061001c6129623f92Sailesh Nepal toneLengthMillis = 375; 138c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon break; 139c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon case TONE_CONGESTION: 140c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon toneType = ToneGenerator.TONE_SUP_CONGESTION; 141c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon toneVolume = RELATIVE_VOLUME_HIPRI; 1428c85dee84fbbd8c36cf1c7b061001c6129623f92Sailesh Nepal toneLengthMillis = 4000; 143c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon break; 144c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon case TONE_INTERCEPT: 145c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon toneType = ToneGenerator.TONE_CDMA_ABBR_INTERCEPT; 146c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon toneVolume = RELATIVE_VOLUME_LOPRI; 1478c85dee84fbbd8c36cf1c7b061001c6129623f92Sailesh Nepal toneLengthMillis = 500; 148c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon break; 149c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon case TONE_OUT_OF_SERVICE: 150c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon toneType = ToneGenerator.TONE_CDMA_CALLDROP_LITE; 151c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon toneVolume = RELATIVE_VOLUME_LOPRI; 1528c85dee84fbbd8c36cf1c7b061001c6129623f92Sailesh Nepal toneLengthMillis = 375; 153c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon break; 154c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon case TONE_REDIAL: 155c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon toneType = ToneGenerator.TONE_CDMA_ALERT_AUTOREDIAL_LITE; 156c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon toneVolume = RELATIVE_VOLUME_LOPRI; 1578c85dee84fbbd8c36cf1c7b061001c6129623f92Sailesh Nepal toneLengthMillis = 5000; 158c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon break; 159c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon case TONE_REORDER: 160c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon toneType = ToneGenerator.TONE_CDMA_REORDER; 161c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon toneVolume = RELATIVE_VOLUME_HIPRI; 1627062bb96f567e7dc9c7bf933b7bee17bb2c8108cYorke Lee toneLengthMillis = 4000; 163c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon break; 164a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon case TONE_RING_BACK: 165a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon toneType = ToneGenerator.TONE_SUP_RINGTONE; 166a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon toneVolume = RELATIVE_VOLUME_HIPRI; 1678c85dee84fbbd8c36cf1c7b061001c6129623f92Sailesh Nepal toneLengthMillis = Integer.MAX_VALUE - TIMEOUT_BUFFER_MILLIS; 168a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon break; 169c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon case TONE_UNOBTAINABLE_NUMBER: 170c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon toneType = ToneGenerator.TONE_SUP_ERROR; 171c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon toneVolume = RELATIVE_VOLUME_HIPRI; 1728c85dee84fbbd8c36cf1c7b061001c6129623f92Sailesh Nepal toneLengthMillis = 4000; 173c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon break; 174c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon case TONE_VOICE_PRIVACY: 175c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon // TODO: fill in. 176c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon throw new IllegalStateException("Voice privacy tone NYI."); 177a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon default: 178a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon throw new IllegalStateException("Bad toneId: " + mToneId); 179a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon } 180a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon 181a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon int stream = AudioManager.STREAM_VOICE_CALL; 182c7e85d4fa0bb3325133a79d4c89f3149e0af430eSantos Cordon if (mCallAudioManager.isBluetoothAudioOn()) { 183c7e85d4fa0bb3325133a79d4c89f3149e0af430eSantos Cordon stream = AudioManager.STREAM_BLUETOOTH_SCO; 184c7e85d4fa0bb3325133a79d4c89f3149e0af430eSantos Cordon } 185a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon 186a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon // If the ToneGenerator creation fails, just continue without it. It is a local audio 187a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon // signal, and is not as important. 188a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon try { 189a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon Log.v(this, "Creating generator"); 190a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon toneGenerator = new ToneGenerator(stream, toneVolume); 191a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon } catch (RuntimeException e) { 192a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon Log.w(this, "Failed to create ToneGenerator.", e); 193a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon return; 194a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon } 195a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon 196df39986de36d40aaa45e61d19a21eca536765ca5Santos Cordon // TODO: Certain CDMA tones need to check the ringer-volume state before 197a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon // playing. See CallNotifier.InCallTonePlayer. 198a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon 199df39986de36d40aaa45e61d19a21eca536765ca5Santos Cordon // TODO: Some tones play through the end of a call so we need to inform 200a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon // CallAudioManager that we want focus the same way that Ringer does. 201a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon 202a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon synchronized (this) { 203a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon if (mState != STATE_STOPPED) { 204a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon mState = STATE_ON; 205a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon toneGenerator.startTone(toneType); 206a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon try { 207a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon Log.v(this, "Starting tone %d...waiting for %d ms.", mToneId, 2088c85dee84fbbd8c36cf1c7b061001c6129623f92Sailesh Nepal toneLengthMillis + TIMEOUT_BUFFER_MILLIS); 2098c85dee84fbbd8c36cf1c7b061001c6129623f92Sailesh Nepal wait(toneLengthMillis + TIMEOUT_BUFFER_MILLIS); 210a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon } catch (InterruptedException e) { 211a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon Log.w(this, "wait interrupted", e); 212a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon } 213a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon } 214a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon } 215a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon mState = STATE_OFF; 216a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon } finally { 217a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon if (toneGenerator != null) { 218a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon toneGenerator.release(); 219a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon } 220a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon cleanUpTonePlayer(); 221a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon } 222a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon } 223a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon 224a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon void startTone() { 225a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon ThreadUtil.checkOnMainThread(); 226a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon 227a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon sTonesPlaying++; 228a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon if (sTonesPlaying == 1) { 229a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon mCallAudioManager.setIsTonePlaying(true); 230a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon } 231a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon 232a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon start(); 233a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon } 234a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon 235a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon /** 236a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon * Stops the tone. 237a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon */ 238a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon void stopTone() { 239a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon synchronized (this) { 240a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon if (mState == STATE_ON) { 241a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon Log.d(this, "Stopping the tone %d.", mToneId); 242a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon notify(); 243a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon } 244a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon mState = STATE_STOPPED; 245a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon } 246a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon } 247a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon 248a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon private void cleanUpTonePlayer() { 249a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon // Release focus on the main thread. 250a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon mMainThreadHandler.post(new Runnable() { 251a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon @Override public void run() { 252a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon if (sTonesPlaying == 0) { 253a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon Log.wtf(this, "Over-releasing focus for tone player."); 254a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon } else if (--sTonesPlaying == 0) { 255a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon mCallAudioManager.setIsTonePlaying(false); 256a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon } 257a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon } 258a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon }); 259a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon } 260a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon} 261