diff options
Diffstat (limited to 'InCallUI/src/com/android/incallui/DialpadFragment.java')
-rw-r--r-- | InCallUI/src/com/android/incallui/DialpadFragment.java | 563 |
1 files changed, 0 insertions, 563 deletions
diff --git a/InCallUI/src/com/android/incallui/DialpadFragment.java b/InCallUI/src/com/android/incallui/DialpadFragment.java deleted file mode 100644 index ad288bdc6..000000000 --- a/InCallUI/src/com/android/incallui/DialpadFragment.java +++ /dev/null @@ -1,563 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.incallui; - -import android.content.Context; -import android.os.Bundle; -import android.os.Handler; -import android.os.Looper; -import android.text.Editable; -import android.text.method.DialerKeyListener; -import android.util.AttributeSet; -import android.view.KeyEvent; -import android.view.LayoutInflater; -import android.view.MotionEvent; -import android.view.View; -import android.view.ViewGroup; -import android.view.accessibility.AccessibilityManager; -import android.widget.EditText; -import android.widget.LinearLayout; -import android.widget.TextView; - -import com.android.contacts.common.compat.PhoneNumberUtilsCompat; -import com.android.dialer.R; -import com.android.phone.common.dialpad.DialpadKeyButton; -import com.android.phone.common.dialpad.DialpadView; - -import java.util.HashMap; - -/** - * Fragment for call control buttons - */ -public class DialpadFragment extends BaseFragment<DialpadPresenter, DialpadPresenter.DialpadUi> - implements DialpadPresenter.DialpadUi, View.OnTouchListener, View.OnKeyListener, - View.OnHoverListener, View.OnClickListener { - - private static final int ACCESSIBILITY_DTMF_STOP_DELAY_MILLIS = 50; - - private final int[] mButtonIds = new int[] {R.id.zero, R.id.one, R.id.two, R.id.three, - R.id.four, R.id.five, R.id.six, R.id.seven, R.id.eight, R.id.nine, R.id.star, - R.id.pound}; - - /** - * LinearLayout with getter and setter methods for the translationY property using floats, - * for animation purposes. - */ - public static class DialpadSlidingLinearLayout extends LinearLayout { - - public DialpadSlidingLinearLayout(Context context) { - super(context); - } - - public DialpadSlidingLinearLayout(Context context, AttributeSet attrs) { - super(context, attrs); - } - - public DialpadSlidingLinearLayout(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - } - - public float getYFraction() { - final int height = getHeight(); - if (height == 0) return 0; - return getTranslationY() / height; - } - - public void setYFraction(float yFraction) { - setTranslationY(yFraction * getHeight()); - } - } - - private EditText mDtmfDialerField; - - /** Hash Map to map a view id to a character*/ - private static final HashMap<Integer, Character> mDisplayMap = - new HashMap<Integer, Character>(); - - private static final Handler sHandler = new Handler(Looper.getMainLooper()); - - - /** Set up the static maps*/ - static { - // Map the buttons to the display characters - mDisplayMap.put(R.id.one, '1'); - mDisplayMap.put(R.id.two, '2'); - mDisplayMap.put(R.id.three, '3'); - mDisplayMap.put(R.id.four, '4'); - mDisplayMap.put(R.id.five, '5'); - mDisplayMap.put(R.id.six, '6'); - mDisplayMap.put(R.id.seven, '7'); - mDisplayMap.put(R.id.eight, '8'); - mDisplayMap.put(R.id.nine, '9'); - mDisplayMap.put(R.id.zero, '0'); - mDisplayMap.put(R.id.pound, '#'); - mDisplayMap.put(R.id.star, '*'); - } - - // KeyListener used with the "dialpad digits" EditText widget. - private DTMFKeyListener mDialerKeyListener; - - private DialpadView mDialpadView; - - private int mCurrentTextColor; - - /** - * Our own key listener, specialized for dealing with DTMF codes. - * 1. Ignore the backspace since it is irrelevant. - * 2. Allow ONLY valid DTMF characters to generate a tone and be - * sent as a DTMF code. - * 3. All other remaining characters are handled by the superclass. - * - * This code is purely here to handle events from the hardware keyboard - * while the DTMF dialpad is up. - */ - private class DTMFKeyListener extends DialerKeyListener { - - private DTMFKeyListener() { - super(); - } - - /** - * Overriden to return correct DTMF-dialable characters. - */ - @Override - protected char[] getAcceptedChars(){ - return DTMF_CHARACTERS; - } - - /** special key listener ignores backspace. */ - @Override - public boolean backspace(View view, Editable content, int keyCode, - KeyEvent event) { - return false; - } - - /** - * Return true if the keyCode is an accepted modifier key for the - * dialer (ALT or SHIFT). - */ - private boolean isAcceptableModifierKey(int keyCode) { - switch (keyCode) { - case KeyEvent.KEYCODE_ALT_LEFT: - case KeyEvent.KEYCODE_ALT_RIGHT: - case KeyEvent.KEYCODE_SHIFT_LEFT: - case KeyEvent.KEYCODE_SHIFT_RIGHT: - return true; - default: - return false; - } - } - - /** - * Overriden so that with each valid button press, we start sending - * a dtmf code and play a local dtmf tone. - */ - @Override - public boolean onKeyDown(View view, Editable content, - int keyCode, KeyEvent event) { - // if (DBG) log("DTMFKeyListener.onKeyDown, keyCode " + keyCode + ", view " + view); - - // find the character - char c = (char) lookup(event, content); - - // if not a long press, and parent onKeyDown accepts the input - if (event.getRepeatCount() == 0 && super.onKeyDown(view, content, keyCode, event)) { - - boolean keyOK = ok(getAcceptedChars(), c); - - // if the character is a valid dtmf code, start playing the tone and send the - // code. - if (keyOK) { - Log.d(this, "DTMFKeyListener reading '" + c + "' from input."); - getPresenter().processDtmf(c); - } else { - Log.d(this, "DTMFKeyListener rejecting '" + c + "' from input."); - } - return true; - } - return false; - } - - /** - * Overriden so that with each valid button up, we stop sending - * a dtmf code and the dtmf tone. - */ - @Override - public boolean onKeyUp(View view, Editable content, - int keyCode, KeyEvent event) { - // if (DBG) log("DTMFKeyListener.onKeyUp, keyCode " + keyCode + ", view " + view); - - super.onKeyUp(view, content, keyCode, event); - - // find the character - char c = (char) lookup(event, content); - - boolean keyOK = ok(getAcceptedChars(), c); - - if (keyOK) { - Log.d(this, "Stopping the tone for '" + c + "'"); - getPresenter().stopDtmf(); - return true; - } - - return false; - } - - /** - * Handle individual keydown events when we DO NOT have an Editable handy. - */ - public boolean onKeyDown(KeyEvent event) { - char c = lookup(event); - Log.d(this, "DTMFKeyListener.onKeyDown: event '" + c + "'"); - - // if not a long press, and parent onKeyDown accepts the input - if (event.getRepeatCount() == 0 && c != 0) { - // if the character is a valid dtmf code, start playing the tone and send the - // code. - if (ok(getAcceptedChars(), c)) { - Log.d(this, "DTMFKeyListener reading '" + c + "' from input."); - getPresenter().processDtmf(c); - return true; - } else { - Log.d(this, "DTMFKeyListener rejecting '" + c + "' from input."); - } - } - return false; - } - - /** - * Handle individual keyup events. - * - * @param event is the event we are trying to stop. If this is null, - * then we just force-stop the last tone without checking if the event - * is an acceptable dialer event. - */ - public boolean onKeyUp(KeyEvent event) { - if (event == null) { - //the below piece of code sends stopDTMF event unnecessarily even when a null event - //is received, hence commenting it. - /*if (DBG) log("Stopping the last played tone."); - stopTone();*/ - return true; - } - - char c = lookup(event); - Log.d(this, "DTMFKeyListener.onKeyUp: event '" + c + "'"); - - // TODO: stopTone does not take in character input, we may want to - // consider checking for this ourselves. - if (ok(getAcceptedChars(), c)) { - Log.d(this, "Stopping the tone for '" + c + "'"); - getPresenter().stopDtmf(); - return true; - } - - return false; - } - - /** - * Find the Dialer Key mapped to this event. - * - * @return The char value of the input event, otherwise - * 0 if no matching character was found. - */ - private char lookup(KeyEvent event) { - // This code is similar to {@link DialerKeyListener#lookup(KeyEvent, Spannable) lookup} - int meta = event.getMetaState(); - int number = event.getNumber(); - - if (!((meta & (KeyEvent.META_ALT_ON | KeyEvent.META_SHIFT_ON)) == 0) || (number == 0)) { - int match = event.getMatch(getAcceptedChars(), meta); - number = (match != 0) ? match : number; - } - - return (char) number; - } - - /** - * Check to see if the keyEvent is dialable. - */ - boolean isKeyEventAcceptable (KeyEvent event) { - return (ok(getAcceptedChars(), lookup(event))); - } - - /** - * Overrides the characters used in {@link DialerKeyListener#CHARACTERS} - * These are the valid dtmf characters. - */ - public final char[] DTMF_CHARACTERS = new char[] { - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '#', '*' - }; - } - - @Override - public void onClick(View v) { - final AccessibilityManager accessibilityManager = (AccessibilityManager) - v.getContext().getSystemService(Context.ACCESSIBILITY_SERVICE); - // When accessibility is on, simulate press and release to preserve the - // semantic meaning of performClick(). Required for Braille support. - if (accessibilityManager.isEnabled()) { - final int id = v.getId(); - // Checking the press state prevents double activation. - if (!v.isPressed() && mDisplayMap.containsKey(id)) { - getPresenter().processDtmf(mDisplayMap.get(id)); - sHandler.postDelayed(new Runnable() { - @Override - public void run() { - getPresenter().stopDtmf(); - } - }, ACCESSIBILITY_DTMF_STOP_DELAY_MILLIS); - } - } - if (v.getId() == R.id.dialpad_back) { - getActivity().onBackPressed(); - } - } - - @Override - public boolean onHover(View v, MotionEvent event) { - // When touch exploration is turned on, lifting a finger while inside - // the button's hover target bounds should perform a click action. - final AccessibilityManager accessibilityManager = (AccessibilityManager) - v.getContext().getSystemService(Context.ACCESSIBILITY_SERVICE); - - if (accessibilityManager.isEnabled() - && accessibilityManager.isTouchExplorationEnabled()) { - final int left = v.getPaddingLeft(); - final int right = (v.getWidth() - v.getPaddingRight()); - final int top = v.getPaddingTop(); - final int bottom = (v.getHeight() - v.getPaddingBottom()); - - switch (event.getActionMasked()) { - case MotionEvent.ACTION_HOVER_ENTER: - // Lift-to-type temporarily disables double-tap activation. - v.setClickable(false); - break; - case MotionEvent.ACTION_HOVER_EXIT: - final int x = (int) event.getX(); - final int y = (int) event.getY(); - if ((x > left) && (x < right) && (y > top) && (y < bottom)) { - v.performClick(); - } - v.setClickable(true); - break; - } - } - - return false; - } - - @Override - public boolean onKey(View v, int keyCode, KeyEvent event) { - Log.d(this, "onKey: keyCode " + keyCode + ", view " + v); - - if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER || keyCode == KeyEvent.KEYCODE_ENTER) { - int viewId = v.getId(); - if (mDisplayMap.containsKey(viewId)) { - switch (event.getAction()) { - case KeyEvent.ACTION_DOWN: - if (event.getRepeatCount() == 0) { - getPresenter().processDtmf(mDisplayMap.get(viewId)); - } - break; - case KeyEvent.ACTION_UP: - getPresenter().stopDtmf(); - break; - } - // do not return true [handled] here, since we want the - // press / click animation to be handled by the framework. - } - } - return false; - } - - @Override - public boolean onTouch(View v, MotionEvent event) { - Log.d(this, "onTouch"); - int viewId = v.getId(); - - // if the button is recognized - if (mDisplayMap.containsKey(viewId)) { - switch (event.getAction()) { - case MotionEvent.ACTION_DOWN: - // Append the character mapped to this button, to the display. - // start the tone - getPresenter().processDtmf(mDisplayMap.get(viewId)); - break; - case MotionEvent.ACTION_UP: - case MotionEvent.ACTION_CANCEL: - // stop the tone on ANY other event, except for MOVE. - getPresenter().stopDtmf(); - break; - } - // do not return true [handled] here, since we want the - // press / click animation to be handled by the framework. - } - return false; - } - - // TODO(klp) Adds hardware keyboard listener - - @Override - public DialpadPresenter createPresenter() { - return new DialpadPresenter(); - } - - @Override - public DialpadPresenter.DialpadUi getUi() { - return this; - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - final View parent = inflater.inflate( - R.layout.incall_dialpad_fragment, container, false); - mDialpadView = (DialpadView) parent.findViewById(R.id.dialpad_view); - mDialpadView.setCanDigitsBeEdited(false); - mDialpadView.setBackgroundResource(R.color.incall_dialpad_background); - mDtmfDialerField = (EditText) parent.findViewById(R.id.digits); - if (mDtmfDialerField != null) { - mDialerKeyListener = new DTMFKeyListener(); - mDtmfDialerField.setKeyListener(mDialerKeyListener); - // remove the long-press context menus that support - // the edit (copy / paste / select) functions. - mDtmfDialerField.setLongClickable(false); - mDtmfDialerField.setElegantTextHeight(false); - configureKeypadListeners(); - } - View backButton = mDialpadView.findViewById(R.id.dialpad_back); - backButton.setVisibility(View.VISIBLE); - backButton.setOnClickListener(this); - - return parent; - } - - @Override - public void onResume() { - super.onResume(); - updateColors(); - } - - public void updateColors() { - int textColor = InCallPresenter.getInstance().getThemeColors().mPrimaryColor; - - if (mCurrentTextColor == textColor) { - return; - } - - DialpadKeyButton dialpadKey; - for (int i = 0; i < mButtonIds.length; i++) { - dialpadKey = (DialpadKeyButton) mDialpadView.findViewById(mButtonIds[i]); - ((TextView) dialpadKey.findViewById(R.id.dialpad_key_number)).setTextColor(textColor); - } - - mCurrentTextColor = textColor; - } - - @Override - public void onDestroyView() { - mDialerKeyListener = null; - super.onDestroyView(); - } - - /** - * Getter for Dialpad text. - * - * @return String containing current Dialpad EditText text. - */ - public String getDtmfText() { - return mDtmfDialerField.getText().toString(); - } - - /** - * Sets the Dialpad text field with some text. - * - * @param text Text to set Dialpad EditText to. - */ - public void setDtmfText(String text) { - mDtmfDialerField.setText(PhoneNumberUtilsCompat.createTtsSpannable(text)); - } - - @Override - public void setVisible(boolean on) { - if (on) { - getView().setVisibility(View.VISIBLE); - } else { - getView().setVisibility(View.INVISIBLE); - } - } - - /** - * Starts the slide up animation for the Dialpad keys when the Dialpad is revealed. - */ - public void animateShowDialpad() { - final DialpadView dialpadView = (DialpadView) getView().findViewById(R.id.dialpad_view); - dialpadView.animateShow(); - } - - @Override - public void appendDigitsToField(char digit) { - if (mDtmfDialerField != null) { - // TODO: maybe *don't* manually append this digit if - // mDialpadDigits is focused and this key came from the HW - // keyboard, since in that case the EditText field will - // get the key event directly and automatically appends - // whetever the user types. - // (Or, a cleaner fix would be to just make mDialpadDigits - // *not* handle HW key presses. That seems to be more - // complicated than just setting focusable="false" on it, - // though.) - mDtmfDialerField.getText().append(digit); - } - } - - /** - * Called externally (from InCallScreen) to play a DTMF Tone. - */ - /* package */ boolean onDialerKeyDown(KeyEvent event) { - Log.d(this, "Notifying dtmf key down."); - if (mDialerKeyListener != null) { - return mDialerKeyListener.onKeyDown(event); - } else { - return false; - } - } - - /** - * Called externally (from InCallScreen) to cancel the last DTMF Tone played. - */ - public boolean onDialerKeyUp(KeyEvent event) { - Log.d(this, "Notifying dtmf key up."); - if (mDialerKeyListener != null) { - return mDialerKeyListener.onKeyUp(event); - } else { - return false; - } - } - - private void configureKeypadListeners() { - DialpadKeyButton dialpadKey; - for (int i = 0; i < mButtonIds.length; i++) { - dialpadKey = (DialpadKeyButton) mDialpadView.findViewById(mButtonIds[i]); - dialpadKey.setOnTouchListener(this); - dialpadKey.setOnKeyListener(this); - dialpadKey.setOnHoverListener(this); - dialpadKey.setOnClickListener(this); - } - } -} |