blob: e18f59c6fc0c5a3129ddea5d371d738d8b794ba6 [file] [log] [blame]
Santos Cordon92a2d812014-04-30 15:19:01 -07001/*
2 * Copyright 2014, The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.telecomm;
18
19import android.media.AudioManager;
20import android.media.ToneGenerator;
21import android.provider.Settings;
22
23import com.google.common.base.Preconditions;
24import com.google.common.collect.ImmutableMap;
25
26import java.util.Map;
27
28/**
29 * Plays DTMF tones locally for the caller to hear. In order to reduce (1) the amount of times we
30 * check the "play local tones" setting and (2) the length of time we keep the tone generator, this
31 * class employs a concept of a call "session" that starts and stops when the foreground call
32 * changes.
33 */
34class DtmfLocalTonePlayer extends CallsManagerListenerBase {
35 private static final Map<Character, Integer> TONE_MAP =
36 ImmutableMap.<Character, Integer>builder()
37 .put('1', ToneGenerator.TONE_DTMF_1)
38 .put('2', ToneGenerator.TONE_DTMF_2)
39 .put('3', ToneGenerator.TONE_DTMF_3)
40 .put('4', ToneGenerator.TONE_DTMF_4)
41 .put('5', ToneGenerator.TONE_DTMF_5)
42 .put('6', ToneGenerator.TONE_DTMF_6)
43 .put('7', ToneGenerator.TONE_DTMF_7)
44 .put('8', ToneGenerator.TONE_DTMF_8)
45 .put('9', ToneGenerator.TONE_DTMF_9)
46 .put('0', ToneGenerator.TONE_DTMF_0)
47 .put('#', ToneGenerator.TONE_DTMF_P)
48 .put('*', ToneGenerator.TONE_DTMF_S)
49 .build();
50
51 /** Generator used to actually play the tone. */
52 private ToneGenerator mToneGenerator;
53
54 /** The current call associated with an existing dtmf session. */
55 private Call mCall;
56
57 /** {@inheritDoc} */
58 @Override
59 public void onForegroundCallChanged(Call oldForegroundCall, Call newForegroundCall) {
60 if (oldForegroundCall != null) {
61 endDtmfSession(oldForegroundCall);
62 }
63
64 if (newForegroundCall != null) {
65 startDtmfSession(newForegroundCall);
66 }
67 }
68
69 /**
70 * Starts playing the dtmf tone specified by c.
71 *
72 * @param call The associated call.
73 * @param c The digit to play.
74 */
75 void playTone(Call call, char c) {
76 // Do nothing if it is not the right call.
77 if (mCall != call) {
78 return;
79 }
80
81 if (mToneGenerator == null) {
82 Log.d(this, "playTone: mToneGenerator == null, %c.", c);
83 } else {
84 Log.d(this, "starting local tone: %c.", c);
85 if (TONE_MAP.containsKey(c)) {
86 mToneGenerator.startTone(TONE_MAP.get(c), -1 /* toneDuration */);
87 }
88 }
89 }
90
91 /**
92 * Stops any currently playing dtmf tone.
93 *
94 * @param call The associated call.
95 */
96 void stopTone(Call call) {
97 // Do nothing if it's not the right call.
98 if (mCall != call) {
99 return;
100 }
101
102 if (mToneGenerator == null) {
103 Log.d(this, "stopTone: mToneGenerator == null.");
104 } else {
105 Log.d(this, "stopping local tone.");
106 mToneGenerator.stopTone();
107 }
108 }
109
110 /**
111 * Runs initialization requires to play local tones during a call.
112 *
113 * @param call The call associated with this dtmf session.
114 */
115 private void startDtmfSession(Call call) {
116 Preconditions.checkNotNull(call);
117 TelecommApp app = TelecommApp.getInstance();
118
119 final boolean areLocalTonesEnabled;
120 if (app.getResources().getBoolean(R.bool.allow_local_dtmf_tones)) {
121 areLocalTonesEnabled = Settings.System.getInt(
122 app.getContentResolver(), Settings.System.DTMF_TONE_WHEN_DIALING, 1) == 1;
123 } else {
124 areLocalTonesEnabled = false;
125 }
126
127 mCall = call;
128
129 if (areLocalTonesEnabled) {
130 if (mToneGenerator == null) {
131 try {
132 mToneGenerator = new ToneGenerator(AudioManager.STREAM_DTMF, 80);
133 } catch (RuntimeException e) {
134 Log.e(this, e, "Error creating local tone generator.");
135 mToneGenerator = null;
136 }
137 }
138 }
139 }
140
141 /**
142 * Releases resources needed for playing local dtmf tones.
143 *
144 * @param call The call associated with the session to end.
145 */
146 private void endDtmfSession(Call call) {
147 Preconditions.checkNotNull(call);
148 if (mCall == call) {
149 // Do a stopTone() in case the sessions ends before we are told to stop the tone.
150 stopTone(call);
151
152 mCall = null;
153
154 if (mToneGenerator != null) {
155 mToneGenerator.release();
156 mToneGenerator = null;
157 }
158 }
159 }
160}