DtmfLocalTonePlayer.java revision 91d43cf9c985cc5a83795f256ef5c46ebb8fbdc1
192a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon/* 292a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon * Copyright 2014, The Android Open Source Project 392a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon * 492a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon * Licensed under the Apache License, Version 2.0 (the "License"); 592a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon * you may not use this file except in compliance with the License. 692a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon * You may obtain a copy of the License at 792a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon * 892a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon * http://www.apache.org/licenses/LICENSE-2.0 992a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon * 1092a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon * Unless required by applicable law or agreed to in writing, software 1192a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon * distributed under the License is distributed on an "AS IS" BASIS, 1292a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1392a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon * See the License for the specific language governing permissions and 1492a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon * limitations under the License. 1592a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon */ 1692a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon 177cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunnpackage com.android.server.telecom; 1892a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon 1991d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunnimport android.content.Context; 2092a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordonimport android.media.AudioManager; 2192a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordonimport android.media.ToneGenerator; 2292a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordonimport android.provider.Settings; 2392a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon 2491d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn// TODO: Needed for move to system service: import com.android.internal.R; 2592a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordonimport com.google.common.collect.ImmutableMap; 2692a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon 2792a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordonimport java.util.Map; 2892a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon 2992a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon/** 3092a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon * Plays DTMF tones locally for the caller to hear. In order to reduce (1) the amount of times we 3192a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon * check the "play local tones" setting and (2) the length of time we keep the tone generator, this 3292a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon * class employs a concept of a call "session" that starts and stops when the foreground call 3392a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon * changes. 3492a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon */ 3592a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordonclass DtmfLocalTonePlayer extends CallsManagerListenerBase { 3692a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon private static final Map<Character, Integer> TONE_MAP = 3792a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon ImmutableMap.<Character, Integer>builder() 3892a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon .put('1', ToneGenerator.TONE_DTMF_1) 3992a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon .put('2', ToneGenerator.TONE_DTMF_2) 4092a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon .put('3', ToneGenerator.TONE_DTMF_3) 4192a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon .put('4', ToneGenerator.TONE_DTMF_4) 4292a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon .put('5', ToneGenerator.TONE_DTMF_5) 4392a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon .put('6', ToneGenerator.TONE_DTMF_6) 4492a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon .put('7', ToneGenerator.TONE_DTMF_7) 4592a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon .put('8', ToneGenerator.TONE_DTMF_8) 4692a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon .put('9', ToneGenerator.TONE_DTMF_9) 4792a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon .put('0', ToneGenerator.TONE_DTMF_0) 4892a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon .put('#', ToneGenerator.TONE_DTMF_P) 4992a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon .put('*', ToneGenerator.TONE_DTMF_S) 5092a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon .build(); 5192a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon 5292a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon /** Generator used to actually play the tone. */ 5392a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon private ToneGenerator mToneGenerator; 5492a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon 5592a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon /** The current call associated with an existing dtmf session. */ 5692a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon private Call mCall; 5792a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon 5891d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn /** The context. */ 5991d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn private final Context mContext; 6091d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn 6191d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn public DtmfLocalTonePlayer(Context context) { 6291d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn mContext = context; 6391d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn } 6491d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn 6592a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon /** {@inheritDoc} */ 6692a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon @Override 6792a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon public void onForegroundCallChanged(Call oldForegroundCall, Call newForegroundCall) { 68acb91eb8e9d0f08a7ccce72062a7eb2cf958aa51Jay Shrauner endDtmfSession(oldForegroundCall); 69acb91eb8e9d0f08a7ccce72062a7eb2cf958aa51Jay Shrauner startDtmfSession(newForegroundCall); 7092a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon } 7192a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon 7292a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon /** 7392a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon * Starts playing the dtmf tone specified by c. 7492a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon * 7592a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon * @param call The associated call. 7692a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon * @param c The digit to play. 7792a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon */ 7892a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon void playTone(Call call, char c) { 7992a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon // Do nothing if it is not the right call. 8092a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon if (mCall != call) { 8192a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon return; 8292a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon } 8392a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon 8492a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon if (mToneGenerator == null) { 8592a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon Log.d(this, "playTone: mToneGenerator == null, %c.", c); 8692a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon } else { 8792a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon Log.d(this, "starting local tone: %c.", c); 8892a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon if (TONE_MAP.containsKey(c)) { 8992a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon mToneGenerator.startTone(TONE_MAP.get(c), -1 /* toneDuration */); 9092a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon } 9192a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon } 9292a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon } 9392a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon 9492a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon /** 9592a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon * Stops any currently playing dtmf tone. 9692a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon * 9792a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon * @param call The associated call. 9892a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon */ 9992a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon void stopTone(Call call) { 10092a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon // Do nothing if it's not the right call. 10192a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon if (mCall != call) { 10292a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon return; 10392a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon } 10492a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon 10592a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon if (mToneGenerator == null) { 10692a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon Log.d(this, "stopTone: mToneGenerator == null."); 10792a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon } else { 10892a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon Log.d(this, "stopping local tone."); 10992a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon mToneGenerator.stopTone(); 11092a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon } 11192a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon } 11292a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon 11392a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon /** 11492a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon * Runs initialization requires to play local tones during a call. 11592a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon * 11692a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon * @param call The call associated with this dtmf session. 11792a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon */ 11892a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon private void startDtmfSession(Call call) { 119acb91eb8e9d0f08a7ccce72062a7eb2cf958aa51Jay Shrauner if (call == null) { 120acb91eb8e9d0f08a7ccce72062a7eb2cf958aa51Jay Shrauner return; 121acb91eb8e9d0f08a7ccce72062a7eb2cf958aa51Jay Shrauner } 12291d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn final Context context = call.getContext(); 12392a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon final boolean areLocalTonesEnabled; 12491d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn if (context.getResources().getBoolean(R.bool.allow_local_dtmf_tones)) { 12592a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon areLocalTonesEnabled = Settings.System.getInt( 12691d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn context.getContentResolver(), Settings.System.DTMF_TONE_WHEN_DIALING, 1) == 1; 12792a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon } else { 12892a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon areLocalTonesEnabled = false; 12992a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon } 13092a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon 13192a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon mCall = call; 13292a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon 13392a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon if (areLocalTonesEnabled) { 13492a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon if (mToneGenerator == null) { 13592a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon try { 13692a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon mToneGenerator = new ToneGenerator(AudioManager.STREAM_DTMF, 80); 13792a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon } catch (RuntimeException e) { 13892a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon Log.e(this, e, "Error creating local tone generator."); 13992a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon mToneGenerator = null; 14092a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon } 14192a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon } 14292a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon } 14392a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon } 14492a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon 14592a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon /** 14692a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon * Releases resources needed for playing local dtmf tones. 14792a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon * 14892a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon * @param call The call associated with the session to end. 14992a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon */ 15092a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon private void endDtmfSession(Call call) { 151acb91eb8e9d0f08a7ccce72062a7eb2cf958aa51Jay Shrauner if (call != null && mCall == call) { 15292a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon // Do a stopTone() in case the sessions ends before we are told to stop the tone. 15392a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon stopTone(call); 15492a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon 15592a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon mCall = null; 15692a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon 15792a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon if (mToneGenerator != null) { 15892a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon mToneGenerator.release(); 15992a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon mToneGenerator = null; 16092a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon } 16192a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon } 16292a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon } 16392a2d811b6206eec84b3c21100dd64f660dae3a2Santos Cordon} 164