13d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer/*
23d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer * Copyright (C) 2015 The Android Open Source Project
33d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer *
43d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer * Licensed under the Apache License, Version 2.0 (the "License");
53d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer * you may not use this file except in compliance with the License.
63d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer * You may obtain a copy of the License at
73d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer *
83d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer *      http://www.apache.org/licenses/LICENSE-2.0
93d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer *
103d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer * Unless required by applicable law or agreed to in writing, software
113d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer * distributed under the License is distributed on an "AS IS" BASIS,
123d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer * See the License for the specific language governing permissions and
143d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer * limitations under the License.
153d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer */
163d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyerpackage com.android.car.dialer;
173d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer
183d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyerimport android.content.Context;
193d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyerimport android.media.AudioManager;
203d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyerimport android.media.ToneGenerator;
213d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyerimport android.os.Bundle;
2217d5ac7d0b429687765e940279726623f5f5f823Anthony Chenimport android.support.annotation.Nullable;
233d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyerimport android.support.v4.app.Fragment;
243d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyerimport android.text.TextUtils;
253d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyerimport android.util.Log;
2617d5ac7d0b429687765e940279726623f5f5f823Anthony Chenimport android.util.SparseArray;
2717d5ac7d0b429687765e940279726623f5f5f823Anthony Chenimport android.util.SparseIntArray;
283d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyerimport android.view.KeyEvent;
293d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyerimport android.view.LayoutInflater;
303d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyerimport android.view.View;
313d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyerimport android.view.ViewGroup;
323d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyerimport android.widget.TextView;
3317d5ac7d0b429687765e940279726623f5f5f823Anthony Chen
349c60bc83bd37ae212e66f2e27b821cebbe7beeb2Rakesh Iyerimport com.android.car.apps.common.FabDrawable;
353d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyerimport com.android.car.dialer.telecom.TelecomUtils;
363d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyerimport com.android.car.dialer.telecom.UiCallManager;
373d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyerimport com.android.car.dialer.telecom.UiCallManager.CallListener;
383d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer
393d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer/**
403d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer * Fragment that controls the dialpad.
413d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer */
423d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyerpublic class DialerFragment extends Fragment {
433d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer    private static final String TAG = "Em.DialerFragment";
443d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer    private static final String INPUT_ACTIVE_KEY = "INPUT_ACTIVE_KEY";
4517d5ac7d0b429687765e940279726623f5f5f823Anthony Chen    private static final String DIAL_NUMBER_KEY = "DIAL_NUMBER_KEY";
4617d5ac7d0b429687765e940279726623f5f5f823Anthony Chen
4717d5ac7d0b429687765e940279726623f5f5f823Anthony Chen    private static final int TONE_LENGTH_MS = 150;
483d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer    private static final int TONE_RELATIVE_VOLUME = 80;
493d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer    private static final int MAX_DIAL_NUMBER = 20;
503d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer
5117d5ac7d0b429687765e940279726623f5f5f823Anthony Chen    private static final SparseIntArray mToneMap = new SparseIntArray();
5217d5ac7d0b429687765e940279726623f5f5f823Anthony Chen    private static final SparseArray<String> mDialValueMap = new SparseArray<>();
533d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer
543d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer    static {
553d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer        mToneMap.put(KeyEvent.KEYCODE_1, ToneGenerator.TONE_DTMF_1);
563d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer        mToneMap.put(KeyEvent.KEYCODE_2, ToneGenerator.TONE_DTMF_2);
573d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer        mToneMap.put(KeyEvent.KEYCODE_3, ToneGenerator.TONE_DTMF_3);
583d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer        mToneMap.put(KeyEvent.KEYCODE_4, ToneGenerator.TONE_DTMF_4);
593d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer        mToneMap.put(KeyEvent.KEYCODE_5, ToneGenerator.TONE_DTMF_5);
603d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer        mToneMap.put(KeyEvent.KEYCODE_6, ToneGenerator.TONE_DTMF_6);
613d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer        mToneMap.put(KeyEvent.KEYCODE_7, ToneGenerator.TONE_DTMF_7);
623d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer        mToneMap.put(KeyEvent.KEYCODE_8, ToneGenerator.TONE_DTMF_8);
633d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer        mToneMap.put(KeyEvent.KEYCODE_9, ToneGenerator.TONE_DTMF_9);
643d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer        mToneMap.put(KeyEvent.KEYCODE_0, ToneGenerator.TONE_DTMF_0);
653d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer        mToneMap.put(KeyEvent.KEYCODE_STAR, ToneGenerator.TONE_DTMF_S);
663d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer        mToneMap.put(KeyEvent.KEYCODE_POUND, ToneGenerator.TONE_DTMF_P);
6717d5ac7d0b429687765e940279726623f5f5f823Anthony Chen
6817d5ac7d0b429687765e940279726623f5f5f823Anthony Chen        mDialValueMap.put(KeyEvent.KEYCODE_1, "1");
6917d5ac7d0b429687765e940279726623f5f5f823Anthony Chen        mDialValueMap.put(KeyEvent.KEYCODE_2, "2");
7017d5ac7d0b429687765e940279726623f5f5f823Anthony Chen        mDialValueMap.put(KeyEvent.KEYCODE_3, "3");
7117d5ac7d0b429687765e940279726623f5f5f823Anthony Chen        mDialValueMap.put(KeyEvent.KEYCODE_4, "4");
7217d5ac7d0b429687765e940279726623f5f5f823Anthony Chen        mDialValueMap.put(KeyEvent.KEYCODE_5, "5");
7317d5ac7d0b429687765e940279726623f5f5f823Anthony Chen        mDialValueMap.put(KeyEvent.KEYCODE_6, "6");
7417d5ac7d0b429687765e940279726623f5f5f823Anthony Chen        mDialValueMap.put(KeyEvent.KEYCODE_7, "7");
7517d5ac7d0b429687765e940279726623f5f5f823Anthony Chen        mDialValueMap.put(KeyEvent.KEYCODE_8, "8");
7617d5ac7d0b429687765e940279726623f5f5f823Anthony Chen        mDialValueMap.put(KeyEvent.KEYCODE_9, "9");
7717d5ac7d0b429687765e940279726623f5f5f823Anthony Chen        mDialValueMap.put(KeyEvent.KEYCODE_0, "0");
7817d5ac7d0b429687765e940279726623f5f5f823Anthony Chen        mDialValueMap.put(KeyEvent.KEYCODE_STAR, "*");
7917d5ac7d0b429687765e940279726623f5f5f823Anthony Chen        mDialValueMap.put(KeyEvent.KEYCODE_POUND, "#");
803d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer    }
813d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer
823d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer    private Context mContext;
836ed89513a64aeaadc55268607e556c8299d4d6b4Srinivas Visvanathan    private UiCallManager mUiCallManager;
8412dfdbe03ce5b195151a45893a933c049c74d58aSrinivas Visvanathan    private final StringBuffer mNumber = new StringBuffer(MAX_DIAL_NUMBER);
853d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer    private ToneGenerator mToneGenerator;
863d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer    private final Object mToneGeneratorLock = new Object();
873d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer    private TextView mNumberView;
883d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer    private boolean mShowInput = true;
893d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer    private Runnable mPendingRunnable;
903d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer
913d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer    private DialerBackButtonListener mBackListener;
923d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer
933d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer    /**
943d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer     * Interface for a class that will be notified when the back button of the dialer has been
953d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer     * clicked.
963d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer     */
973d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer    public interface DialerBackButtonListener {
983d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer        /**
993d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer         * Called when the back button has been clicked on the dialer. This action should dismiss
1003d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer         * the dialer fragment.
1013d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer         */
1023d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer        void onDialerBackClick();
1033d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer    }
1043d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer
10517d5ac7d0b429687765e940279726623f5f5f823Anthony Chen    /**
10617d5ac7d0b429687765e940279726623f5f5f823Anthony Chen     * Creates a new instance of the {@link DialerFragment} and display the given number as the one
10717d5ac7d0b429687765e940279726623f5f5f823Anthony Chen     * to dial.
10817d5ac7d0b429687765e940279726623f5f5f823Anthony Chen     */
10917d5ac7d0b429687765e940279726623f5f5f823Anthony Chen    static DialerFragment newInstance(UiCallManager callManager,
11017d5ac7d0b429687765e940279726623f5f5f823Anthony Chen            DialerBackButtonListener listener, @Nullable String dialNumber) {
1116ed89513a64aeaadc55268607e556c8299d4d6b4Srinivas Visvanathan        DialerFragment fragment = new DialerFragment();
1126ed89513a64aeaadc55268607e556c8299d4d6b4Srinivas Visvanathan        fragment.mUiCallManager = callManager;
11317d5ac7d0b429687765e940279726623f5f5f823Anthony Chen        fragment.mBackListener = listener;
1146ed89513a64aeaadc55268607e556c8299d4d6b4Srinivas Visvanathan
11517d5ac7d0b429687765e940279726623f5f5f823Anthony Chen        if (!TextUtils.isEmpty(dialNumber)) {
11617d5ac7d0b429687765e940279726623f5f5f823Anthony Chen            Bundle args = new Bundle();
11717d5ac7d0b429687765e940279726623f5f5f823Anthony Chen            args.putString(DIAL_NUMBER_KEY, dialNumber);
11817d5ac7d0b429687765e940279726623f5f5f823Anthony Chen            fragment.setArguments(args);
11917d5ac7d0b429687765e940279726623f5f5f823Anthony Chen        }
12017d5ac7d0b429687765e940279726623f5f5f823Anthony Chen
12117d5ac7d0b429687765e940279726623f5f5f823Anthony Chen        return fragment;
1223d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer    }
1233d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer
1243d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer    @Override
1253d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer    public void onCreate(Bundle savedInstanceState) {
1263d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer        super.onCreate(savedInstanceState);
1273d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer        if (savedInstanceState != null && savedInstanceState.containsKey(INPUT_ACTIVE_KEY)) {
1283d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer            mShowInput = savedInstanceState.getBoolean(INPUT_ACTIVE_KEY);
1293d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer        }
13017d5ac7d0b429687765e940279726623f5f5f823Anthony Chen
13117d5ac7d0b429687765e940279726623f5f5f823Anthony Chen        Bundle args = getArguments();
13217d5ac7d0b429687765e940279726623f5f5f823Anthony Chen        if (args != null) {
13317d5ac7d0b429687765e940279726623f5f5f823Anthony Chen            setDialNumber(args.getString(DIAL_NUMBER_KEY));
13417d5ac7d0b429687765e940279726623f5f5f823Anthony Chen        }
1353d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer    }
1363d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer
1373d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer    @Override
1383d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer    public View onCreateView(LayoutInflater inflater, ViewGroup container,
1393d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer            Bundle savedInstanceState) {
1403d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer        if (Log.isLoggable(TAG, Log.DEBUG)) {
1413d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer            Log.d(TAG, "onCreateView");
1423d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer        }
1433d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer
1446f8e1dbe4629b499128dade1e6d83e37147403c4Srinivas Visvanathan        mContext = getContext();
1453d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer        View view = inflater.inflate(R.layout.dialer_fragment, container, false);
1463d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer
1473d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer        if (Log.isLoggable(TAG, Log.VERBOSE)) {
1483d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer            Log.v(TAG, "onCreateView: inflated successfully");
1493d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer        }
1503d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer
15117d5ac7d0b429687765e940279726623f5f5f823Anthony Chen        view.findViewById(R.id.exit_dialer_button).setOnClickListener(v -> {
1526f8e1dbe4629b499128dade1e6d83e37147403c4Srinivas Visvanathan            if (mBackListener != null) {
1536f8e1dbe4629b499128dade1e6d83e37147403c4Srinivas Visvanathan                mBackListener.onDialerBackClick();
1543d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer            }
1553d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer        });
1563d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer
1573d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer        mNumberView = (TextView) view.findViewById(R.id.number);
1583d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer
1593d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer        if (Log.isLoggable(TAG, Log.VERBOSE)) {
160676781bf09b69966f83ba99c1b7ee0c7d6ae00e4Rakesh Iyer            Log.v(TAG, "mShowInput: " + mShowInput);
1613d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer        }
1623d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer
163676781bf09b69966f83ba99c1b7ee0c7d6ae00e4Rakesh Iyer        FabDrawable answerCallDrawable = new FabDrawable(mContext);
16417d5ac7d0b429687765e940279726623f5f5f823Anthony Chen        answerCallDrawable.setFabAndStrokeColor(getContext().getColor(R.color.phone_call));
16517d5ac7d0b429687765e940279726623f5f5f823Anthony Chen
16617d5ac7d0b429687765e940279726623f5f5f823Anthony Chen        View callButton = view.findViewById(R.id.call);
167676781bf09b69966f83ba99c1b7ee0c7d6ae00e4Rakesh Iyer        callButton.setBackground(answerCallDrawable);
168676781bf09b69966f83ba99c1b7ee0c7d6ae00e4Rakesh Iyer        callButton.setVisibility(View.VISIBLE);
169676781bf09b69966f83ba99c1b7ee0c7d6ae00e4Rakesh Iyer        callButton.setOnClickListener((unusedView) -> {
170676781bf09b69966f83ba99c1b7ee0c7d6ae00e4Rakesh Iyer            if (Log.isLoggable(TAG, Log.DEBUG)) {
171676781bf09b69966f83ba99c1b7ee0c7d6ae00e4Rakesh Iyer                Log.d(TAG, "Call button clicked, placing a call: " + mNumber.toString());
172676781bf09b69966f83ba99c1b7ee0c7d6ae00e4Rakesh Iyer            }
173676781bf09b69966f83ba99c1b7ee0c7d6ae00e4Rakesh Iyer
174676781bf09b69966f83ba99c1b7ee0c7d6ae00e4Rakesh Iyer            if (!TextUtils.isEmpty(mNumber.toString())) {
175676781bf09b69966f83ba99c1b7ee0c7d6ae00e4Rakesh Iyer                mUiCallManager.safePlaceCall(mNumber.toString(), false);
176676781bf09b69966f83ba99c1b7ee0c7d6ae00e4Rakesh Iyer            }
177676781bf09b69966f83ba99c1b7ee0c7d6ae00e4Rakesh Iyer        });
17817d5ac7d0b429687765e940279726623f5f5f823Anthony Chen
179676781bf09b69966f83ba99c1b7ee0c7d6ae00e4Rakesh Iyer        View deleteButton = view.findViewById(R.id.delete);
180676781bf09b69966f83ba99c1b7ee0c7d6ae00e4Rakesh Iyer        deleteButton.setVisibility(View.VISIBLE);
18117d5ac7d0b429687765e940279726623f5f5f823Anthony Chen        deleteButton.setOnClickListener(v -> {
182676781bf09b69966f83ba99c1b7ee0c7d6ae00e4Rakesh Iyer            if (mNumber.length() != 0) {
183676781bf09b69966f83ba99c1b7ee0c7d6ae00e4Rakesh Iyer                mNumber.deleteCharAt(mNumber.length() - 1);
184676781bf09b69966f83ba99c1b7ee0c7d6ae00e4Rakesh Iyer                mNumberView.setText(getFormattedNumber(mNumber.toString()));
185676781bf09b69966f83ba99c1b7ee0c7d6ae00e4Rakesh Iyer            }
186676781bf09b69966f83ba99c1b7ee0c7d6ae00e4Rakesh Iyer        });
1873d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer
18817d5ac7d0b429687765e940279726623f5f5f823Anthony Chen        setupKeypadClickListeners(view);
1893d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer
1903d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer        return view;
1913d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer    }
1923d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer
1933d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer    /**
1943d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer     * The default click listener for all dialpad buttons. This click listener will append its
1953d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer     * associated value to {@link #mNumber}.
1963d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer     */
1973d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer    private class DialpadClickListener implements View.OnClickListener {
19817d5ac7d0b429687765e940279726623f5f5f823Anthony Chen        private final int mTone;
19917d5ac7d0b429687765e940279726623f5f5f823Anthony Chen        private final String mValue;
2003d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer
20117d5ac7d0b429687765e940279726623f5f5f823Anthony Chen        DialpadClickListener(int keyCode) {
20217d5ac7d0b429687765e940279726623f5f5f823Anthony Chen            mTone = mToneMap.get(keyCode);
20317d5ac7d0b429687765e940279726623f5f5f823Anthony Chen            mValue = mDialValueMap.get(keyCode);
2043d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer        }
2053d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer
2063d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer        @Override
2073d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer        public void onClick(View v) {
2083d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer            mNumber.append(mValue);
2093d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer            mNumberView.setText(getFormattedNumber(mNumber.toString()));
21017d5ac7d0b429687765e940279726623f5f5f823Anthony Chen            playTone(mTone);
2113d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer        }
21217d5ac7d0b429687765e940279726623f5f5f823Anthony Chen    }
2133d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer
21417d5ac7d0b429687765e940279726623f5f5f823Anthony Chen    private void setupKeypadClickListeners(View parent) {
21517d5ac7d0b429687765e940279726623f5f5f823Anthony Chen        parent.findViewById(R.id.zero).setOnClickListener(
21617d5ac7d0b429687765e940279726623f5f5f823Anthony Chen                new DialpadClickListener(KeyEvent.KEYCODE_0));
21717d5ac7d0b429687765e940279726623f5f5f823Anthony Chen        parent.findViewById(R.id.one).setOnClickListener(
21817d5ac7d0b429687765e940279726623f5f5f823Anthony Chen                new DialpadClickListener(KeyEvent.KEYCODE_1));
21917d5ac7d0b429687765e940279726623f5f5f823Anthony Chen        parent.findViewById(R.id.two).setOnClickListener(
22017d5ac7d0b429687765e940279726623f5f5f823Anthony Chen                new DialpadClickListener(KeyEvent.KEYCODE_2));
22117d5ac7d0b429687765e940279726623f5f5f823Anthony Chen        parent.findViewById(R.id.three).setOnClickListener(
22217d5ac7d0b429687765e940279726623f5f5f823Anthony Chen                new DialpadClickListener(KeyEvent.KEYCODE_3));
22317d5ac7d0b429687765e940279726623f5f5f823Anthony Chen        parent.findViewById(R.id.four).setOnClickListener(
22417d5ac7d0b429687765e940279726623f5f5f823Anthony Chen                new DialpadClickListener(KeyEvent.KEYCODE_4));
22517d5ac7d0b429687765e940279726623f5f5f823Anthony Chen        parent.findViewById(R.id.five).setOnClickListener(
22617d5ac7d0b429687765e940279726623f5f5f823Anthony Chen                new DialpadClickListener(KeyEvent.KEYCODE_5));
22717d5ac7d0b429687765e940279726623f5f5f823Anthony Chen        parent.findViewById(R.id.six).setOnClickListener(
22817d5ac7d0b429687765e940279726623f5f5f823Anthony Chen                new DialpadClickListener(KeyEvent.KEYCODE_6));
22917d5ac7d0b429687765e940279726623f5f5f823Anthony Chen        parent.findViewById(R.id.seven).setOnClickListener(
23017d5ac7d0b429687765e940279726623f5f5f823Anthony Chen                new DialpadClickListener(KeyEvent.KEYCODE_7));
23117d5ac7d0b429687765e940279726623f5f5f823Anthony Chen        parent.findViewById(R.id.eight).setOnClickListener(
23217d5ac7d0b429687765e940279726623f5f5f823Anthony Chen                new DialpadClickListener(KeyEvent.KEYCODE_8));
23317d5ac7d0b429687765e940279726623f5f5f823Anthony Chen        parent.findViewById(R.id.nine).setOnClickListener(
23417d5ac7d0b429687765e940279726623f5f5f823Anthony Chen                new DialpadClickListener(KeyEvent.KEYCODE_9));
23517d5ac7d0b429687765e940279726623f5f5f823Anthony Chen        parent.findViewById(R.id.star).setOnClickListener(
23617d5ac7d0b429687765e940279726623f5f5f823Anthony Chen                new DialpadClickListener(KeyEvent.KEYCODE_STAR));
23717d5ac7d0b429687765e940279726623f5f5f823Anthony Chen        parent.findViewById(R.id.pound).setOnClickListener(
23817d5ac7d0b429687765e940279726623f5f5f823Anthony Chen                new DialpadClickListener(KeyEvent.KEYCODE_POUND));
2393d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer    }
2403d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer
2413d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer    @Override
2423d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer    public void onResume() {
2433d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer        super.onResume();
2443d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer        synchronized (mToneGeneratorLock) {
2453d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer            if (mToneGenerator == null) {
2463d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer                mToneGenerator = new ToneGenerator(AudioManager.STREAM_MUSIC, TONE_RELATIVE_VOLUME);
2473d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer            }
2483d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer        }
2496ed89513a64aeaadc55268607e556c8299d4d6b4Srinivas Visvanathan        mUiCallManager.addListener(mCallListener);
2503d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer
2513d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer        if (mPendingRunnable != null) {
2523d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer            mPendingRunnable.run();
2533d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer            mPendingRunnable = null;
2543d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer        }
2553d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer    }
2563d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer
2573d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer    @Override
2583d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer    public void onPause() {
2593d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer        super.onPause();
2606ed89513a64aeaadc55268607e556c8299d4d6b4Srinivas Visvanathan        mUiCallManager.removeListener(mCallListener);
2613d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer        stopTone();
2623d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer        synchronized (mToneGeneratorLock) {
2633d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer            if (mToneGenerator != null) {
2643d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer                mToneGenerator.release();
2653d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer                mToneGenerator = null;
2663d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer            }
2673d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer        }
2683d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer    }
2693d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer
2703d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer    @Override
2713d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer    public void onDestroyView() {
2723d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer        super.onDestroyView();
2733d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer        mContext = null;
2743d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer        mNumberView = null;
2753d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer    }
2763d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer
27717d5ac7d0b429687765e940279726623f5f5f823Anthony Chen    private void setDialNumber(final String number) {
2783d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer        if (TextUtils.isEmpty(number)) {
2793d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer            return;
2803d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer        }
2813d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer
2823d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer        if (mContext != null && mNumberView != null) {
2833d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer            setDialNumberInternal(number);
2843d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer        } else {
2856f8e1dbe4629b499128dade1e6d83e37147403c4Srinivas Visvanathan            mPendingRunnable = () -> setDialNumberInternal(number);
2863d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer        }
2873d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer    }
2883d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer
2893d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer    private void setDialNumberInternal(final String number) {
29012dfdbe03ce5b195151a45893a933c049c74d58aSrinivas Visvanathan        // Clear existing content in mNumber.
29112dfdbe03ce5b195151a45893a933c049c74d58aSrinivas Visvanathan        mNumber.setLength(0);
2923d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer        mNumber.append(number);
2933d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer        mNumberView.setText(getFormattedNumber(mNumber.toString()));
2943d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer    }
2953d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer
29617d5ac7d0b429687765e940279726623f5f5f823Anthony Chen    private void playTone(int tone) {
29717d5ac7d0b429687765e940279726623f5f5f823Anthony Chen        synchronized (mToneGeneratorLock) {
29817d5ac7d0b429687765e940279726623f5f5f823Anthony Chen            if (mToneGenerator == null) {
29917d5ac7d0b429687765e940279726623f5f5f823Anthony Chen                Log.w(TAG, "playTone: mToneGenerator == null, tone: " + tone);
30017d5ac7d0b429687765e940279726623f5f5f823Anthony Chen                return;
30117d5ac7d0b429687765e940279726623f5f5f823Anthony Chen            }
30217d5ac7d0b429687765e940279726623f5f5f823Anthony Chen
30317d5ac7d0b429687765e940279726623f5f5f823Anthony Chen            // Start the new tone (will stop any playing tone)
30417d5ac7d0b429687765e940279726623f5f5f823Anthony Chen            mToneGenerator.startTone(tone, TONE_LENGTH_MS);
30517d5ac7d0b429687765e940279726623f5f5f823Anthony Chen        }
30617d5ac7d0b429687765e940279726623f5f5f823Anthony Chen    }
30717d5ac7d0b429687765e940279726623f5f5f823Anthony Chen
3083d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer    private void stopTone() {
3093d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer        synchronized (mToneGeneratorLock) {
3103d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer            if (mToneGenerator == null) {
3113d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer                Log.w(TAG, "stopTone: mToneGenerator == null");
3123d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer                return;
3133d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer            }
3143d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer            mToneGenerator.stopTone();
3153d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer        }
3163d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer    }
3173d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer
3183d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer    private String getFormattedNumber(String number) {
3193d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer        return TelecomUtils.getFormattedNumber(mContext, number);
3203d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer    }
3213d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer
3223d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer    private final CallListener mCallListener = new CallListener() {
3233d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer        @Override
3243d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer        public void dispatchPhoneKeyEvent(KeyEvent event) {
3253d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer            if (event.getKeyCode() == KeyEvent.KEYCODE_CALL &&
3263d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer                    event.getAction() == KeyEvent.ACTION_UP &&
3273d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer                    !TextUtils.isEmpty(mNumber.toString())) {
3286ed89513a64aeaadc55268607e556c8299d4d6b4Srinivas Visvanathan                mUiCallManager.safePlaceCall(mNumber.toString(), false);
3293d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer            }
3303d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer        }
3313d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer    };
3323d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer}
333