You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
313 lines
9.9 KiB
313 lines
9.9 KiB
4 months ago
|
/*
|
||
|
* 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.telephony.PhoneNumberUtils;
|
||
|
import android.util.ArrayMap;
|
||
|
import android.util.AttributeSet;
|
||
|
import android.view.ContextThemeWrapper;
|
||
|
import android.view.KeyEvent;
|
||
|
import android.view.LayoutInflater;
|
||
|
import android.view.View;
|
||
|
import android.view.View.OnClickListener;
|
||
|
import android.view.View.OnKeyListener;
|
||
|
import android.view.ViewGroup;
|
||
|
import android.widget.EditText;
|
||
|
import android.widget.LinearLayout;
|
||
|
import android.widget.TextView;
|
||
|
import com.android.dialer.common.LogUtil;
|
||
|
import com.android.dialer.dialpadview.DialpadKeyButton;
|
||
|
import com.android.dialer.dialpadview.DialpadKeyButton.OnPressedListener;
|
||
|
import com.android.dialer.dialpadview.DialpadView;
|
||
|
import com.android.dialer.logging.DialerImpression;
|
||
|
import com.android.dialer.logging.Logger;
|
||
|
import com.android.incallui.DialpadPresenter.DialpadUi;
|
||
|
import com.android.incallui.baseui.BaseFragment;
|
||
|
import java.util.Map;
|
||
|
|
||
|
/** Fragment for call control buttons */
|
||
|
public class DialpadFragment extends BaseFragment<DialpadPresenter, DialpadUi>
|
||
|
implements DialpadUi, OnKeyListener, OnClickListener, OnPressedListener {
|
||
|
|
||
|
/** Hash Map to map a view id to a character */
|
||
|
private static final Map<Integer, Character> displayMap = new ArrayMap<>();
|
||
|
|
||
|
/** Set up the static maps */
|
||
|
static {
|
||
|
// Map the buttons to the display characters
|
||
|
displayMap.put(R.id.one, '1');
|
||
|
displayMap.put(R.id.two, '2');
|
||
|
displayMap.put(R.id.three, '3');
|
||
|
displayMap.put(R.id.four, '4');
|
||
|
displayMap.put(R.id.five, '5');
|
||
|
displayMap.put(R.id.six, '6');
|
||
|
displayMap.put(R.id.seven, '7');
|
||
|
displayMap.put(R.id.eight, '8');
|
||
|
displayMap.put(R.id.nine, '9');
|
||
|
displayMap.put(R.id.zero, '0');
|
||
|
displayMap.put(R.id.pound, '#');
|
||
|
displayMap.put(R.id.star, '*');
|
||
|
}
|
||
|
|
||
|
private final int[] buttonIds =
|
||
|
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
|
||
|
};
|
||
|
private EditText dtmfDialerField;
|
||
|
// KeyListener used with the "dialpad digits" EditText widget.
|
||
|
private DtmfKeyListener dtmfKeyListener;
|
||
|
private DialpadView dialpadView;
|
||
|
private int currentTextColor;
|
||
|
private View endCallSpace;
|
||
|
private boolean shouldShowEndCallSpace = true;
|
||
|
|
||
|
@Override
|
||
|
public void onClick(View v) {
|
||
|
if (v.getId() == R.id.dialpad_back) {
|
||
|
Logger.get(getContext())
|
||
|
.logImpression(DialerImpression.Type.IN_CALL_DIALPAD_CLOSE_BUTTON_PRESSED);
|
||
|
getActivity().onBackPressed();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@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 (displayMap.containsKey(viewId)) {
|
||
|
switch (event.getAction()) {
|
||
|
case KeyEvent.ACTION_DOWN:
|
||
|
if (event.getRepeatCount() == 0) {
|
||
|
getPresenter().processDtmf(displayMap.get(viewId));
|
||
|
}
|
||
|
break;
|
||
|
case KeyEvent.ACTION_UP:
|
||
|
getPresenter().stopDtmf();
|
||
|
break;
|
||
|
default: // fall out
|
||
|
}
|
||
|
// do not return true [handled] here, since we want the
|
||
|
// press / click animation to be handled by the framework.
|
||
|
}
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public DialpadPresenter createPresenter() {
|
||
|
return new DialpadPresenter();
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public DialpadPresenter.DialpadUi getUi() {
|
||
|
return this;
|
||
|
}
|
||
|
|
||
|
// TODO(klp) Adds hardware keyboard listener
|
||
|
|
||
|
@Override
|
||
|
public View onCreateView(
|
||
|
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||
|
Context contextThemeWrapper = new ContextThemeWrapper(getActivity(), R.style.Dialer_ThemeBase);
|
||
|
LayoutInflater layoutInflater = inflater.cloneInContext(contextThemeWrapper);
|
||
|
final View parent = layoutInflater.inflate(R.layout.incall_dialpad_fragment, container, false);
|
||
|
dialpadView = (DialpadView) parent.findViewById(R.id.dialpad_view);
|
||
|
dialpadView.setCanDigitsBeEdited(false);
|
||
|
dialpadView.setBackgroundResource(R.color.incall_dialpad_background);
|
||
|
dtmfDialerField = (EditText) parent.findViewById(R.id.digits);
|
||
|
if (dtmfDialerField != null) {
|
||
|
LogUtil.i("DialpadFragment.onCreateView", "creating dtmfKeyListener");
|
||
|
dtmfKeyListener = new DtmfKeyListener(getPresenter());
|
||
|
dtmfDialerField.setKeyListener(dtmfKeyListener);
|
||
|
// remove the long-press context menus that support
|
||
|
// the edit (copy / paste / select) functions.
|
||
|
dtmfDialerField.setLongClickable(false);
|
||
|
dtmfDialerField.setElegantTextHeight(false);
|
||
|
configureKeypadListeners();
|
||
|
}
|
||
|
View backButton = dialpadView.findViewById(R.id.dialpad_back);
|
||
|
backButton.setVisibility(View.VISIBLE);
|
||
|
backButton.setOnClickListener(this);
|
||
|
endCallSpace = dialpadView.findViewById(R.id.end_call_space);
|
||
|
|
||
|
return parent;
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void onResume() {
|
||
|
super.onResume();
|
||
|
updateColors();
|
||
|
endCallSpace.setVisibility(shouldShowEndCallSpace ? View.VISIBLE : View.GONE);
|
||
|
}
|
||
|
|
||
|
public void updateColors() {
|
||
|
int textColor = InCallPresenter.getInstance().getThemeColorManager().getPrimaryColor();
|
||
|
|
||
|
if (currentTextColor == textColor) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
DialpadKeyButton dialpadKey;
|
||
|
for (int i = 0; i < buttonIds.length; i++) {
|
||
|
dialpadKey = (DialpadKeyButton) dialpadView.findViewById(buttonIds[i]);
|
||
|
((TextView) dialpadKey.findViewById(R.id.dialpad_key_number)).setTextColor(textColor);
|
||
|
}
|
||
|
|
||
|
currentTextColor = textColor;
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void onDestroyView() {
|
||
|
dtmfKeyListener = null;
|
||
|
super.onDestroyView();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Getter for Dialpad text.
|
||
|
*
|
||
|
* @return String containing current Dialpad EditText text.
|
||
|
*/
|
||
|
public String getDtmfText() {
|
||
|
return dtmfDialerField.getText().toString();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Sets the Dialpad text field with some text.
|
||
|
*
|
||
|
* @param text Text to set Dialpad EditText to.
|
||
|
*/
|
||
|
public void setDtmfText(String text) {
|
||
|
dtmfDialerField.setText(PhoneNumberUtils.createTtsSpannable(text));
|
||
|
}
|
||
|
|
||
|
/** 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 (dtmfDialerField != 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.)
|
||
|
dtmfDialerField.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 (dtmfKeyListener != null) {
|
||
|
return dtmfKeyListener.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 (dtmfKeyListener != null) {
|
||
|
return dtmfKeyListener.onKeyUp(event);
|
||
|
} else {
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void configureKeypadListeners() {
|
||
|
DialpadKeyButton dialpadKey;
|
||
|
for (int i = 0; i < buttonIds.length; i++) {
|
||
|
dialpadKey = (DialpadKeyButton) dialpadView.findViewById(buttonIds[i]);
|
||
|
dialpadKey.setOnKeyListener(this);
|
||
|
dialpadKey.setOnClickListener(this);
|
||
|
dialpadKey.setOnPressedListener(this);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void onPressed(View view, boolean pressed) {
|
||
|
if (pressed && displayMap.containsKey(view.getId())) {
|
||
|
Logger.get(getContext())
|
||
|
.logImpression(DialerImpression.Type.IN_CALL_DIALPAD_NUMBER_BUTTON_PRESSED);
|
||
|
Log.d(this, "onPressed: " + pressed + " " + displayMap.get(view.getId()));
|
||
|
getPresenter().processDtmf(displayMap.get(view.getId()));
|
||
|
}
|
||
|
if (!pressed) {
|
||
|
Log.d(this, "onPressed: " + pressed);
|
||
|
getPresenter().stopDtmf();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public void setShouldShowEndCallSpace(boolean show) {
|
||
|
shouldShowEndCallSpace = show;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 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());
|
||
|
}
|
||
|
}
|
||
|
}
|