InCallTonePlayer.java revision e091ab90e37845cf4771051a6d2ce0ebadee4fe7
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 24d931a017a0abea32ad4485a91402b5f62b9ddb0eBrad Ebingerimport com.android.internal.annotations.VisibleForTesting; 25d931a017a0abea32ad4485a91402b5f62b9ddb0eBrad Ebinger 26a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon/** 27a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon * Play a call-related tone (ringback, busy signal, etc.) through ToneGenerator. To use, create an 28a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon * instance using InCallTonePlayer.Factory (passing in the TONE_* constant for the tone you want) 29a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon * and start() it. Implemented on top of {@link Thread} so that the tone plays in its own thread. 30a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon */ 31d931a017a0abea32ad4485a91402b5f62b9ddb0eBrad Ebingerpublic class InCallTonePlayer extends Thread { 32a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon 33a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon /** 34a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon * Factory used to create InCallTonePlayers. Exists to aid with testing mocks. 35a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon */ 36a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon public static class Factory { 37e091ab90e37845cf4771051a6d2ce0ebadee4fe7Hall Liu private CallAudioManager mCallAudioManager; 38f62630a57de0d52be2bdbc92a9bf8f305cc0892dHall Liu private final CallAudioRoutePeripheralAdapter mCallAudioRoutePeripheralAdapter; 39abcbce4441720c52a443d292d5adc2d95f446494Ihab Awad private final TelecomSystem.SyncRoot mLock; 40a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon 41e091ab90e37845cf4771051a6d2ce0ebadee4fe7Hall Liu Factory(CallAudioRoutePeripheralAdapter callAudioRoutePeripheralAdapter, 42f62630a57de0d52be2bdbc92a9bf8f305cc0892dHall Liu TelecomSystem.SyncRoot lock) { 43f62630a57de0d52be2bdbc92a9bf8f305cc0892dHall Liu mCallAudioRoutePeripheralAdapter = callAudioRoutePeripheralAdapter; 44abcbce4441720c52a443d292d5adc2d95f446494Ihab Awad mLock = lock; 45a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon } 46a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon 47e091ab90e37845cf4771051a6d2ce0ebadee4fe7Hall Liu public void setCallAudioManager(CallAudioManager callAudioManager) { 48e091ab90e37845cf4771051a6d2ce0ebadee4fe7Hall Liu mCallAudioManager = callAudioManager; 49e091ab90e37845cf4771051a6d2ce0ebadee4fe7Hall Liu } 50e091ab90e37845cf4771051a6d2ce0ebadee4fe7Hall Liu 51d931a017a0abea32ad4485a91402b5f62b9ddb0eBrad Ebinger public InCallTonePlayer createPlayer(int tone) { 52f62630a57de0d52be2bdbc92a9bf8f305cc0892dHall Liu return new InCallTonePlayer(tone, mCallAudioManager, 53f62630a57de0d52be2bdbc92a9bf8f305cc0892dHall Liu mCallAudioRoutePeripheralAdapter, mLock); 54a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon } 55a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon } 56a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon 57a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon // The possible tones that we can play. 58c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon public static final int TONE_INVALID = 0; 59c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon public static final int TONE_BUSY = 1; 60c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon public static final int TONE_CALL_ENDED = 2; 61c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon public static final int TONE_OTA_CALL_ENDED = 3; 62c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon public static final int TONE_CALL_WAITING = 4; 63c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon public static final int TONE_CDMA_DROP = 5; 64c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon public static final int TONE_CONGESTION = 6; 65c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon public static final int TONE_INTERCEPT = 7; 66c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon public static final int TONE_OUT_OF_SERVICE = 8; 67c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon public static final int TONE_REDIAL = 9; 68c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon public static final int TONE_REORDER = 10; 69c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon public static final int TONE_RING_BACK = 11; 70c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon public static final int TONE_UNOBTAINABLE_NUMBER = 12; 71c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon public static final int TONE_VOICE_PRIVACY = 13; 7286014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn public static final int TONE_VIDEO_UPGRADE = 14; 73a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon 74a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon private static final int RELATIVE_VOLUME_EMERGENCY = 100; 75a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon private static final int RELATIVE_VOLUME_HIPRI = 80; 76a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon private static final int RELATIVE_VOLUME_LOPRI = 50; 77a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon 78a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon // Buffer time (in msec) to add on to the tone timeout value. Needed mainly when the timeout 79a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon // value for a tone is exact duration of the tone itself. 808c85dee84fbbd8c36cf1c7b061001c6129623f92Sailesh Nepal private static final int TIMEOUT_BUFFER_MILLIS = 20; 81a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon 82a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon // The tone state. 83a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon private static final int STATE_OFF = 0; 84a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon private static final int STATE_ON = 1; 85a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon private static final int STATE_STOPPED = 2; 86a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon 87a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon /** 88a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon * Keeps count of the number of actively playing tones so that we can notify CallAudioManager 89a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon * when we need focus and when it can be release. This should only be manipulated from the main 90a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon * thread. 91a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon */ 92a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon private static int sTonesPlaying = 0; 93a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon 94a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon private final CallAudioManager mCallAudioManager; 95f62630a57de0d52be2bdbc92a9bf8f305cc0892dHall Liu private final CallAudioRoutePeripheralAdapter mCallAudioRoutePeripheralAdapter; 96a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon 97a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon private final Handler mMainThreadHandler = new Handler(Looper.getMainLooper()); 98a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon 99a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon /** The ID of the tone to play. */ 100a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon private final int mToneId; 101a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon 102a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon /** Current state of the tone player. */ 103a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon private int mState; 104a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon 105abcbce4441720c52a443d292d5adc2d95f446494Ihab Awad /** Telecom lock object. */ 106abcbce4441720c52a443d292d5adc2d95f446494Ihab Awad private final TelecomSystem.SyncRoot mLock; 107abcbce4441720c52a443d292d5adc2d95f446494Ihab Awad 108a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon /** 109a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon * Initializes the tone player. Private; use the {@link Factory} to create tone players. 110a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon * 111a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon * @param toneId ID of the tone to play, see TONE_* constants. 112a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon */ 113abcbce4441720c52a443d292d5adc2d95f446494Ihab Awad private InCallTonePlayer( 114abcbce4441720c52a443d292d5adc2d95f446494Ihab Awad int toneId, 115abcbce4441720c52a443d292d5adc2d95f446494Ihab Awad CallAudioManager callAudioManager, 116f62630a57de0d52be2bdbc92a9bf8f305cc0892dHall Liu CallAudioRoutePeripheralAdapter callAudioRoutePeripheralAdapter, 117abcbce4441720c52a443d292d5adc2d95f446494Ihab Awad TelecomSystem.SyncRoot lock) { 118a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon mState = STATE_OFF; 119a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon mToneId = toneId; 120a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon mCallAudioManager = callAudioManager; 121f62630a57de0d52be2bdbc92a9bf8f305cc0892dHall Liu mCallAudioRoutePeripheralAdapter = callAudioRoutePeripheralAdapter; 122abcbce4441720c52a443d292d5adc2d95f446494Ihab Awad mLock = lock; 123a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon } 124a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon 125a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon /** {@inheritDoc} */ 126a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon @Override 127a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon public void run() { 128a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon ToneGenerator toneGenerator = null; 129a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon try { 130a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon Log.d(this, "run(toneId = %s)", mToneId); 131a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon 132a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon final int toneType; // Passed to ToneGenerator.startTone. 133a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon final int toneVolume; // Passed to the ToneGenerator constructor. 1348c85dee84fbbd8c36cf1c7b061001c6129623f92Sailesh Nepal final int toneLengthMillis; 135a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon 136a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon switch (mToneId) { 137c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon case TONE_BUSY: 138c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon // TODO: CDMA-specific tones 139c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon toneType = ToneGenerator.TONE_SUP_BUSY; 140c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon toneVolume = RELATIVE_VOLUME_HIPRI; 1418c85dee84fbbd8c36cf1c7b061001c6129623f92Sailesh Nepal toneLengthMillis = 4000; 142c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon break; 143c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon case TONE_CALL_ENDED: 144c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon toneType = ToneGenerator.TONE_PROP_PROMPT; 145c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon toneVolume = RELATIVE_VOLUME_HIPRI; 1467062bb96f567e7dc9c7bf933b7bee17bb2c8108cYorke Lee toneLengthMillis = 200; 147c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon break; 148c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon case TONE_OTA_CALL_ENDED: 149c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon // TODO: fill in 150c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon throw new IllegalStateException("OTA Call ended NYI."); 151c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon case TONE_CALL_WAITING: 15240f78c210512570f14cdfde9613dd85c510a1c0cSantos Cordon toneType = ToneGenerator.TONE_SUP_CALL_WAITING; 15340f78c210512570f14cdfde9613dd85c510a1c0cSantos Cordon toneVolume = RELATIVE_VOLUME_HIPRI; 15440f78c210512570f14cdfde9613dd85c510a1c0cSantos Cordon toneLengthMillis = Integer.MAX_VALUE - TIMEOUT_BUFFER_MILLIS; 15540f78c210512570f14cdfde9613dd85c510a1c0cSantos Cordon break; 156c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon case TONE_CDMA_DROP: 157c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon toneType = ToneGenerator.TONE_CDMA_CALLDROP_LITE; 158c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon toneVolume = RELATIVE_VOLUME_LOPRI; 1598c85dee84fbbd8c36cf1c7b061001c6129623f92Sailesh Nepal toneLengthMillis = 375; 160c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon break; 161c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon case TONE_CONGESTION: 162c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon toneType = ToneGenerator.TONE_SUP_CONGESTION; 163c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon toneVolume = RELATIVE_VOLUME_HIPRI; 1648c85dee84fbbd8c36cf1c7b061001c6129623f92Sailesh Nepal toneLengthMillis = 4000; 165c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon break; 166c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon case TONE_INTERCEPT: 167c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon toneType = ToneGenerator.TONE_CDMA_ABBR_INTERCEPT; 168c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon toneVolume = RELATIVE_VOLUME_LOPRI; 1698c85dee84fbbd8c36cf1c7b061001c6129623f92Sailesh Nepal toneLengthMillis = 500; 170c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon break; 171c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon case TONE_OUT_OF_SERVICE: 172c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon toneType = ToneGenerator.TONE_CDMA_CALLDROP_LITE; 173c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon toneVolume = RELATIVE_VOLUME_LOPRI; 1748c85dee84fbbd8c36cf1c7b061001c6129623f92Sailesh Nepal toneLengthMillis = 375; 175c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon break; 176c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon case TONE_REDIAL: 177c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon toneType = ToneGenerator.TONE_CDMA_ALERT_AUTOREDIAL_LITE; 178c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon toneVolume = RELATIVE_VOLUME_LOPRI; 1798c85dee84fbbd8c36cf1c7b061001c6129623f92Sailesh Nepal toneLengthMillis = 5000; 180c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon break; 181c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon case TONE_REORDER: 182c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon toneType = ToneGenerator.TONE_CDMA_REORDER; 183c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon toneVolume = RELATIVE_VOLUME_HIPRI; 1847062bb96f567e7dc9c7bf933b7bee17bb2c8108cYorke Lee toneLengthMillis = 4000; 185c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon break; 186a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon case TONE_RING_BACK: 187a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon toneType = ToneGenerator.TONE_SUP_RINGTONE; 188a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon toneVolume = RELATIVE_VOLUME_HIPRI; 1898c85dee84fbbd8c36cf1c7b061001c6129623f92Sailesh Nepal toneLengthMillis = Integer.MAX_VALUE - TIMEOUT_BUFFER_MILLIS; 190a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon break; 191c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon case TONE_UNOBTAINABLE_NUMBER: 192c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon toneType = ToneGenerator.TONE_SUP_ERROR; 193c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon toneVolume = RELATIVE_VOLUME_HIPRI; 1948c85dee84fbbd8c36cf1c7b061001c6129623f92Sailesh Nepal toneLengthMillis = 4000; 195c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon break; 196c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon case TONE_VOICE_PRIVACY: 197c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon // TODO: fill in. 198c7b8ebabf904aa70a7a2a2a0ad01883088c56180Santos Cordon throw new IllegalStateException("Voice privacy tone NYI."); 19986014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn case TONE_VIDEO_UPGRADE: 20086014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn // Similar to the call waiting tone, but does not repeat. 20186014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn toneType = ToneGenerator.TONE_SUP_CALL_WAITING; 20286014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn toneVolume = RELATIVE_VOLUME_HIPRI; 20386014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn toneLengthMillis = 4000; 20486014fcf9ec86e198a1ebac7c46e0e5c630735d7Tyler Gunn break; 205a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon default: 206a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon throw new IllegalStateException("Bad toneId: " + mToneId); 207a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon } 208a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon 209a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon int stream = AudioManager.STREAM_VOICE_CALL; 210f62630a57de0d52be2bdbc92a9bf8f305cc0892dHall Liu if (mCallAudioRoutePeripheralAdapter.isBluetoothAudioOn()) { 211c7e85d4fa0bb3325133a79d4c89f3149e0af430eSantos Cordon stream = AudioManager.STREAM_BLUETOOTH_SCO; 212c7e85d4fa0bb3325133a79d4c89f3149e0af430eSantos Cordon } 213a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon 214a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon // If the ToneGenerator creation fails, just continue without it. It is a local audio 215a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon // signal, and is not as important. 216a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon try { 217a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon Log.v(this, "Creating generator"); 218a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon toneGenerator = new ToneGenerator(stream, toneVolume); 219a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon } catch (RuntimeException e) { 220a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon Log.w(this, "Failed to create ToneGenerator.", e); 221a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon return; 222a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon } 223a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon 224df39986de36d40aaa45e61d19a21eca536765ca5Santos Cordon // TODO: Certain CDMA tones need to check the ringer-volume state before 225a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon // playing. See CallNotifier.InCallTonePlayer. 226a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon 227df39986de36d40aaa45e61d19a21eca536765ca5Santos Cordon // TODO: Some tones play through the end of a call so we need to inform 228a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon // CallAudioManager that we want focus the same way that Ringer does. 229a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon 230a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon synchronized (this) { 231a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon if (mState != STATE_STOPPED) { 232a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon mState = STATE_ON; 233a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon toneGenerator.startTone(toneType); 234a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon try { 235a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon Log.v(this, "Starting tone %d...waiting for %d ms.", mToneId, 2368c85dee84fbbd8c36cf1c7b061001c6129623f92Sailesh Nepal toneLengthMillis + TIMEOUT_BUFFER_MILLIS); 2378c85dee84fbbd8c36cf1c7b061001c6129623f92Sailesh Nepal wait(toneLengthMillis + TIMEOUT_BUFFER_MILLIS); 238a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon } catch (InterruptedException e) { 239a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon Log.w(this, "wait interrupted", e); 240a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon } 241a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon } 242a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon } 243a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon mState = STATE_OFF; 244a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon } finally { 245a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon if (toneGenerator != null) { 246a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon toneGenerator.release(); 247a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon } 248a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon cleanUpTonePlayer(); 249a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon } 250a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon } 251d931a017a0abea32ad4485a91402b5f62b9ddb0eBrad Ebinger 252d931a017a0abea32ad4485a91402b5f62b9ddb0eBrad Ebinger @VisibleForTesting 253d931a017a0abea32ad4485a91402b5f62b9ddb0eBrad Ebinger public void startTone() { 254a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon sTonesPlaying++; 255a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon if (sTonesPlaying == 1) { 256a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon mCallAudioManager.setIsTonePlaying(true); 257a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon } 258a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon 259a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon start(); 260a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon } 261a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon 262a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon /** 263a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon * Stops the tone. 264a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon */ 265d931a017a0abea32ad4485a91402b5f62b9ddb0eBrad Ebinger @VisibleForTesting 266d931a017a0abea32ad4485a91402b5f62b9ddb0eBrad Ebinger public void stopTone() { 267a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon synchronized (this) { 268a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon if (mState == STATE_ON) { 269a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon Log.d(this, "Stopping the tone %d.", mToneId); 270a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon notify(); 271a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon } 272a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon mState = STATE_STOPPED; 273a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon } 274a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon } 275a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon 276a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon private void cleanUpTonePlayer() { 277a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon // Release focus on the main thread. 278a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon mMainThreadHandler.post(new Runnable() { 279a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon @Override public void run() { 280abcbce4441720c52a443d292d5adc2d95f446494Ihab Awad synchronized (mLock) { 281abcbce4441720c52a443d292d5adc2d95f446494Ihab Awad if (sTonesPlaying == 0) { 282abcbce4441720c52a443d292d5adc2d95f446494Ihab Awad Log.wtf(this, "Over-releasing focus for tone player."); 283abcbce4441720c52a443d292d5adc2d95f446494Ihab Awad } else if (--sTonesPlaying == 0) { 284abcbce4441720c52a443d292d5adc2d95f446494Ihab Awad mCallAudioManager.setIsTonePlaying(false); 285abcbce4441720c52a443d292d5adc2d95f446494Ihab Awad } 286a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon } 287a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon } 288a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon }); 289a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon } 290a56f276cafcad80ab3a28996b6a0d72cffa4b2bcSantos Cordon} 291