blob: b2aacf71d9d4839dd4aa5f8dbd533eb1ea50f3e1 [file] [log] [blame]
Eric Erfanianccca3152017-02-22 16:32:36 -08001/*
2 * Copyright (C) 2013 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.incallui;
18
19import android.content.Context;
20import android.os.Bundle;
Eric Erfanianccca3152017-02-22 16:32:36 -080021import android.util.ArrayMap;
22import android.util.AttributeSet;
23import android.view.KeyEvent;
24import android.view.LayoutInflater;
25import android.view.View;
26import android.view.View.OnClickListener;
27import android.view.View.OnKeyListener;
28import android.view.ViewGroup;
29import android.widget.EditText;
30import android.widget.LinearLayout;
31import android.widget.TextView;
32import com.android.contacts.common.compat.PhoneNumberUtilsCompat;
maxwelb5e22e802017-11-27 17:01:07 -080033import com.android.dialer.common.LogUtil;
Eric Erfanianccca3152017-02-22 16:32:36 -080034import com.android.dialer.dialpadview.DialpadKeyButton;
35import com.android.dialer.dialpadview.DialpadKeyButton.OnPressedListener;
36import com.android.dialer.dialpadview.DialpadView;
Eric Erfanianfc0eb8c2017-08-31 06:57:16 -070037import com.android.dialer.logging.DialerImpression;
38import com.android.dialer.logging.Logger;
Eric Erfanianccca3152017-02-22 16:32:36 -080039import com.android.incallui.DialpadPresenter.DialpadUi;
40import com.android.incallui.baseui.BaseFragment;
41import java.util.Map;
42
43/** Fragment for call control buttons */
44public class DialpadFragment extends BaseFragment<DialpadPresenter, DialpadUi>
45 implements DialpadUi, OnKeyListener, OnClickListener, OnPressedListener {
46
47 /** Hash Map to map a view id to a character */
48 private static final Map<Integer, Character> mDisplayMap = new ArrayMap<>();
49
50 /** Set up the static maps */
51 static {
52 // Map the buttons to the display characters
53 mDisplayMap.put(R.id.one, '1');
54 mDisplayMap.put(R.id.two, '2');
55 mDisplayMap.put(R.id.three, '3');
56 mDisplayMap.put(R.id.four, '4');
57 mDisplayMap.put(R.id.five, '5');
58 mDisplayMap.put(R.id.six, '6');
59 mDisplayMap.put(R.id.seven, '7');
60 mDisplayMap.put(R.id.eight, '8');
61 mDisplayMap.put(R.id.nine, '9');
62 mDisplayMap.put(R.id.zero, '0');
63 mDisplayMap.put(R.id.pound, '#');
64 mDisplayMap.put(R.id.star, '*');
65 }
66
67 private final int[] mButtonIds =
68 new int[] {
69 R.id.zero,
70 R.id.one,
71 R.id.two,
72 R.id.three,
73 R.id.four,
74 R.id.five,
75 R.id.six,
76 R.id.seven,
77 R.id.eight,
78 R.id.nine,
79 R.id.star,
80 R.id.pound
81 };
82 private EditText mDtmfDialerField;
83 // KeyListener used with the "dialpad digits" EditText widget.
maxwelb5e22e802017-11-27 17:01:07 -080084 private DtmfKeyListener mDtmfKeyListener;
Eric Erfanianccca3152017-02-22 16:32:36 -080085 private DialpadView mDialpadView;
86 private int mCurrentTextColor;
87
88 @Override
89 public void onClick(View v) {
90 if (v.getId() == R.id.dialpad_back) {
Eric Erfanianfc0eb8c2017-08-31 06:57:16 -070091 Logger.get(getContext())
92 .logImpression(DialerImpression.Type.IN_CALL_DIALPAD_CLOSE_BUTTON_PRESSED);
Eric Erfanianccca3152017-02-22 16:32:36 -080093 getActivity().onBackPressed();
94 }
95 }
96
97 @Override
98 public boolean onKey(View v, int keyCode, KeyEvent event) {
99 Log.d(this, "onKey: keyCode " + keyCode + ", view " + v);
100
101 if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER || keyCode == KeyEvent.KEYCODE_ENTER) {
102 int viewId = v.getId();
103 if (mDisplayMap.containsKey(viewId)) {
104 switch (event.getAction()) {
105 case KeyEvent.ACTION_DOWN:
106 if (event.getRepeatCount() == 0) {
107 getPresenter().processDtmf(mDisplayMap.get(viewId));
108 }
109 break;
110 case KeyEvent.ACTION_UP:
111 getPresenter().stopDtmf();
112 break;
Eric Erfanianfc0eb8c2017-08-31 06:57:16 -0700113 default: // fall out
Eric Erfanianccca3152017-02-22 16:32:36 -0800114 }
115 // do not return true [handled] here, since we want the
116 // press / click animation to be handled by the framework.
117 }
118 }
119 return false;
120 }
121
122 @Override
123 public DialpadPresenter createPresenter() {
124 return new DialpadPresenter();
125 }
126
127 @Override
128 public DialpadPresenter.DialpadUi getUi() {
129 return this;
130 }
131
Eric Erfanianfc0eb8c2017-08-31 06:57:16 -0700132 // TODO(klp) Adds hardware keyboard listener
Eric Erfanianccca3152017-02-22 16:32:36 -0800133
134 @Override
135 public View onCreateView(
136 LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
137 final View parent = inflater.inflate(R.layout.incall_dialpad_fragment, container, false);
138 mDialpadView = (DialpadView) parent.findViewById(R.id.dialpad_view);
139 mDialpadView.setCanDigitsBeEdited(false);
140 mDialpadView.setBackgroundResource(R.color.incall_dialpad_background);
141 mDtmfDialerField = (EditText) parent.findViewById(R.id.digits);
142 if (mDtmfDialerField != null) {
maxwelb5e22e802017-11-27 17:01:07 -0800143 LogUtil.i("DialpadFragment.onCreateView", "creating dtmfKeyListener");
144 mDtmfKeyListener = new DtmfKeyListener(getPresenter());
145 mDtmfDialerField.setKeyListener(mDtmfKeyListener);
Eric Erfanianccca3152017-02-22 16:32:36 -0800146 // remove the long-press context menus that support
147 // the edit (copy / paste / select) functions.
148 mDtmfDialerField.setLongClickable(false);
149 mDtmfDialerField.setElegantTextHeight(false);
150 configureKeypadListeners();
151 }
152 View backButton = mDialpadView.findViewById(R.id.dialpad_back);
153 backButton.setVisibility(View.VISIBLE);
154 backButton.setOnClickListener(this);
155
156 return parent;
157 }
158
159 @Override
160 public void onResume() {
161 super.onResume();
162 updateColors();
163 }
164
165 public void updateColors() {
166 int textColor = InCallPresenter.getInstance().getThemeColorManager().getPrimaryColor();
167
168 if (mCurrentTextColor == textColor) {
169 return;
170 }
171
172 DialpadKeyButton dialpadKey;
173 for (int i = 0; i < mButtonIds.length; i++) {
174 dialpadKey = (DialpadKeyButton) mDialpadView.findViewById(mButtonIds[i]);
175 ((TextView) dialpadKey.findViewById(R.id.dialpad_key_number)).setTextColor(textColor);
176 }
177
178 mCurrentTextColor = textColor;
179 }
180
181 @Override
182 public void onDestroyView() {
maxwelb5e22e802017-11-27 17:01:07 -0800183 mDtmfKeyListener = null;
Eric Erfanianccca3152017-02-22 16:32:36 -0800184 super.onDestroyView();
185 }
186
187 /**
188 * Getter for Dialpad text.
189 *
190 * @return String containing current Dialpad EditText text.
191 */
192 public String getDtmfText() {
193 return mDtmfDialerField.getText().toString();
194 }
195
196 /**
197 * Sets the Dialpad text field with some text.
198 *
199 * @param text Text to set Dialpad EditText to.
200 */
201 public void setDtmfText(String text) {
202 mDtmfDialerField.setText(PhoneNumberUtilsCompat.createTtsSpannable(text));
203 }
204
Eric Erfanianccca3152017-02-22 16:32:36 -0800205 /** Starts the slide up animation for the Dialpad keys when the Dialpad is revealed. */
206 public void animateShowDialpad() {
207 final DialpadView dialpadView = (DialpadView) getView().findViewById(R.id.dialpad_view);
208 dialpadView.animateShow();
209 }
210
211 @Override
212 public void appendDigitsToField(char digit) {
213 if (mDtmfDialerField != null) {
214 // TODO: maybe *don't* manually append this digit if
215 // mDialpadDigits is focused and this key came from the HW
216 // keyboard, since in that case the EditText field will
217 // get the key event directly and automatically appends
218 // whetever the user types.
219 // (Or, a cleaner fix would be to just make mDialpadDigits
220 // *not* handle HW key presses. That seems to be more
221 // complicated than just setting focusable="false" on it,
222 // though.)
223 mDtmfDialerField.getText().append(digit);
224 }
225 }
226
227 /** Called externally (from InCallScreen) to play a DTMF Tone. */
228 /* package */ boolean onDialerKeyDown(KeyEvent event) {
229 Log.d(this, "Notifying dtmf key down.");
maxwelb5e22e802017-11-27 17:01:07 -0800230 if (mDtmfKeyListener != null) {
231 return mDtmfKeyListener.onKeyDown(event);
Eric Erfanianccca3152017-02-22 16:32:36 -0800232 } else {
233 return false;
234 }
235 }
236
237 /** Called externally (from InCallScreen) to cancel the last DTMF Tone played. */
238 public boolean onDialerKeyUp(KeyEvent event) {
239 Log.d(this, "Notifying dtmf key up.");
maxwelb5e22e802017-11-27 17:01:07 -0800240 if (mDtmfKeyListener != null) {
241 return mDtmfKeyListener.onKeyUp(event);
Eric Erfanianccca3152017-02-22 16:32:36 -0800242 } else {
243 return false;
244 }
245 }
246
247 private void configureKeypadListeners() {
248 DialpadKeyButton dialpadKey;
249 for (int i = 0; i < mButtonIds.length; i++) {
250 dialpadKey = (DialpadKeyButton) mDialpadView.findViewById(mButtonIds[i]);
251 dialpadKey.setOnKeyListener(this);
252 dialpadKey.setOnClickListener(this);
253 dialpadKey.setOnPressedListener(this);
254 }
255 }
256
257 @Override
258 public void onPressed(View view, boolean pressed) {
259 if (pressed && mDisplayMap.containsKey(view.getId())) {
Eric Erfanianfc0eb8c2017-08-31 06:57:16 -0700260 Logger.get(getContext())
261 .logImpression(DialerImpression.Type.IN_CALL_DIALPAD_NUMBER_BUTTON_PRESSED);
Eric Erfanianccca3152017-02-22 16:32:36 -0800262 Log.d(this, "onPressed: " + pressed + " " + mDisplayMap.get(view.getId()));
263 getPresenter().processDtmf(mDisplayMap.get(view.getId()));
264 }
265 if (!pressed) {
266 Log.d(this, "onPressed: " + pressed);
267 getPresenter().stopDtmf();
268 }
269 }
270
271 /**
272 * LinearLayout with getter and setter methods for the translationY property using floats, for
273 * animation purposes.
274 */
275 public static class DialpadSlidingLinearLayout extends LinearLayout {
276
277 public DialpadSlidingLinearLayout(Context context) {
278 super(context);
279 }
280
281 public DialpadSlidingLinearLayout(Context context, AttributeSet attrs) {
282 super(context, attrs);
283 }
284
285 public DialpadSlidingLinearLayout(Context context, AttributeSet attrs, int defStyle) {
286 super(context, attrs, defStyle);
287 }
288
289 public float getYFraction() {
290 final int height = getHeight();
291 if (height == 0) {
292 return 0;
293 }
294 return getTranslationY() / height;
295 }
296
297 public void setYFraction(float yFraction) {
298 setTranslationY(yFraction * getHeight());
299 }
300 }
Eric Erfanianccca3152017-02-22 16:32:36 -0800301}