17d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon/*
27d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Copyright (C) 2008 The Android Open Source Project
37d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon *
47d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Licensed under the Apache License, Version 2.0 (the "License");
57d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * you may not use this file except in compliance with the License.
67d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * You may obtain a copy of the License at
77d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon *
87d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon *      http://www.apache.org/licenses/LICENSE-2.0
97d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon *
107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Unless required by applicable law or agreed to in writing, software
117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * distributed under the License is distributed on an "AS IS" BASIS,
127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * See the License for the specific language governing permissions and
147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * limitations under the License.
157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */
167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon
177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonpackage com.android.phone;
187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon
197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.app.Activity;
207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.app.AlertDialog;
217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.app.Dialog;
227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.app.StatusBarManager;
237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.content.BroadcastReceiver;
247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.content.Context;
257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.content.Intent;
267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.content.IntentFilter;
277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.content.res.Resources;
287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.media.AudioManager;
297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.media.ToneGenerator;
307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.net.Uri;
317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.os.Bundle;
327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.provider.Settings;
337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.telephony.PhoneNumberUtils;
347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.text.Editable;
357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.text.TextUtils;
367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.text.TextWatcher;
377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.text.method.DialerKeyListener;
387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.util.Log;
397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.view.KeyEvent;
407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.view.MotionEvent;
417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.view.View;
427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.view.WindowManager;
437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.view.accessibility.AccessibilityManager;
447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.widget.EditText;
457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon
467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport com.android.phone.common.HapticFeedback;
477d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon
487d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon
497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon/**
507d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * EmergencyDialer is a special dialer that is used ONLY for dialing emergency calls.
517d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon *
527d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * It's a simplified version of the regular dialer (i.e. the TwelveKeyDialer
537d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * activity from apps/Contacts) that:
547d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon *   1. Allows ONLY emergency calls to be dialed
557d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon *   2. Disallows voicemail functionality
567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon *   3. Uses the FLAG_SHOW_WHEN_LOCKED window manager flag to allow this
577d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon *      activity to stay in front of the keyguard.
587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon *
597d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * TODO: Even though this is an ultra-simplified version of the normal
607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * dialer, there's still lots of code duplication between this class and
617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * the TwelveKeyDialer class from apps/Contacts.  Could the common code be
627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * moved into a shared base class that would live in the framework?
637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Or could we figure out some way to move *this* class into apps/Contacts
647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * also?
657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */
667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonpublic class EmergencyDialer extends Activity implements View.OnClickListener,
677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        View.OnLongClickListener, View.OnHoverListener, View.OnKeyListener, TextWatcher {
687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    // Keys used with onSaveInstanceState().
697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    private static final String LAST_NUMBER = "lastNumber";
707d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon
717d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    // Intent action for this activity.
727d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    public static final String ACTION_DIAL = "com.android.phone.EmergencyDialer.DIAL";
737d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon
747d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    // List of dialer button IDs.
757d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    private static final int[] DIALER_KEYS = new int[] {
767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            R.id.one, R.id.two, R.id.three,
777d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            R.id.four, R.id.five, R.id.six,
787d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            R.id.seven, R.id.eight, R.id.nine,
797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            R.id.star, R.id.zero, R.id.pound };
807d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon
817d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    // Debug constants.
827d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    private static final boolean DBG = false;
837d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    private static final String LOG_TAG = "EmergencyDialer";
847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon
857d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    private PhoneGlobals mApp;
867d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    private StatusBarManager mStatusBarManager;
877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    private AccessibilityManager mAccessibilityManager;
887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon
897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    /** The length of DTMF tones in milliseconds */
907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    private static final int TONE_LENGTH_MS = 150;
917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon
927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    /** The DTMF tone volume relative to other sounds in the stream */
937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    private static final int TONE_RELATIVE_VOLUME = 80;
947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon
957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    /** Stream type used to play the DTMF tones off call, and mapped to the volume control keys */
967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    private static final int DIAL_TONE_STREAM_TYPE = AudioManager.STREAM_DTMF;
977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon
987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    private static final int BAD_EMERGENCY_NUMBER_DIALOG = 0;
997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon
100fc309815886e9b4bf9d5dfb76a8c7cffe2ab1fd1Santos Cordon    // private static final int USER_ACTIVITY_TIMEOUT_WHEN_NO_PROX_SENSOR = 15000; // millis
1017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon
1027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    EditText mDigits;
1037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    private View mDialButton;
1047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    private View mDelete;
1057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon
1067d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    private ToneGenerator mToneGenerator;
1077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    private Object mToneGeneratorLock = new Object();
1087d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon
1097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    // determines if we want to playback local DTMF tones.
1107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    private boolean mDTMFToneEnabled;
1117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon
1127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    // Haptic feedback (vibration) for dialer key presses.
1137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    private HapticFeedback mHaptic = new HapticFeedback();
1147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon
1157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    // close activity when screen turns off
1167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
1177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        @Override
1187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        public void onReceive(Context context, Intent intent) {
1197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            if (Intent.ACTION_SCREEN_OFF.equals(intent.getAction())) {
1207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                finish();
1217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            }
1227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        }
1237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    };
1247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon
1257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    private String mLastNumber; // last number we tried to dial. Used to restore error dialog.
1267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon
1277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    @Override
1287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
1297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        // Do nothing
1307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    }
1317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon
1327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    @Override
1337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    public void onTextChanged(CharSequence input, int start, int before, int changeCount) {
1347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        // Do nothing
1357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    }
1367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon
1377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    @Override
1387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    public void afterTextChanged(Editable input) {
1397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        // Check for special sequences, in particular the "**04" or "**05"
1407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        // sequences that allow you to enter PIN or PUK-related codes.
1417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        //
1427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        // But note we *don't* allow most other special sequences here,
1437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        // like "secret codes" (*#*#<code>#*#*) or IMEI display ("*#06#"),
1447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        // since those shouldn't be available if the device is locked.
1457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        //
1467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        // So we call SpecialCharSequenceMgr.handleCharsForLockedDevice()
1477d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        // here, not the regular handleChars() method.
1487d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        if (SpecialCharSequenceMgr.handleCharsForLockedDevice(this, input.toString(), this)) {
1497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            // A special sequence was entered, clear the digits
1507d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            mDigits.getText().clear();
1517d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        }
1527d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon
1537d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        updateDialAndDeleteButtonStateEnabledAttr();
1547d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    }
1557d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon
1567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    @Override
1577d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    protected void onCreate(Bundle icicle) {
1587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        super.onCreate(icicle);
1597d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon
1607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        mApp = PhoneGlobals.getInstance();
1617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        mStatusBarManager = (StatusBarManager) getSystemService(Context.STATUS_BAR_SERVICE);
1627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        mAccessibilityManager = (AccessibilityManager) getSystemService(ACCESSIBILITY_SERVICE);
1637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon
1647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        // Allow this activity to be displayed in front of the keyguard / lockscreen.
1657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        WindowManager.LayoutParams lp = getWindow().getAttributes();
1667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        lp.flags |= WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
167fc309815886e9b4bf9d5dfb76a8c7cffe2ab1fd1Santos Cordon
168fc309815886e9b4bf9d5dfb76a8c7cffe2ab1fd1Santos Cordon        // When no proximity sensor is available, use a shorter timeout.
16907fae161a1eb1b2b9e00a8377658baa52465c3aaChristine Chen        // TODO: Do we enable this for non proximity devices any more?
170fc309815886e9b4bf9d5dfb76a8c7cffe2ab1fd1Santos Cordon        // lp.userActivityTimeout = USER_ACTIVITY_TIMEOUT_WHEN_NO_PROX_SENSOR;
171fc309815886e9b4bf9d5dfb76a8c7cffe2ab1fd1Santos Cordon
1727d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        getWindow().setAttributes(lp);
1737d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon
1747d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        setContentView(R.layout.emergency_dialer);
1757d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon
1767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        mDigits = (EditText) findViewById(R.id.digits);
1777d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        mDigits.setKeyListener(DialerKeyListener.getInstance());
1787d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        mDigits.setOnClickListener(this);
1797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        mDigits.setOnKeyListener(this);
1807d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        mDigits.setLongClickable(false);
1817d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        if (mAccessibilityManager.isEnabled()) {
1827d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            // The text view must be selected to send accessibility events.
1837d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            mDigits.setSelected(true);
1847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        }
1857d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        maybeAddNumberFormatting();
1867d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon
1877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        // Check for the presence of the keypad
1887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        View view = findViewById(R.id.one);
1897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        if (view != null) {
1907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            setupKeypad();
1917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        }
1927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon
1937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        mDelete = findViewById(R.id.deleteButton);
1947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        mDelete.setOnClickListener(this);
1957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        mDelete.setOnLongClickListener(this);
1967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon
1977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        mDialButton = findViewById(R.id.dialButton);
1987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon
1997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        // Check whether we should show the onscreen "Dial" button and co.
2007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        Resources res = getResources();
2017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        if (res.getBoolean(R.bool.config_show_onscreen_dial_button)) {
2027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            mDialButton.setOnClickListener(this);
2037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        } else {
2047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            mDialButton.setVisibility(View.GONE);
2057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        }
2067d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon
2077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        if (icicle != null) {
2087d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            super.onRestoreInstanceState(icicle);
2097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        }
2107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon
2117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        // Extract phone number from intent
2127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        Uri data = getIntent().getData();
2137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        if (data != null && (Constants.SCHEME_TEL.equals(data.getScheme()))) {
2147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            String number = PhoneNumberUtils.getNumberFromIntent(getIntent(), this);
2157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            if (number != null) {
2167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                mDigits.setText(number);
2177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            }
2187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        }
2197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon
2207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        // if the mToneGenerator creation fails, just continue without it.  It is
2217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        // a local audio signal, and is not as important as the dtmf tone itself.
2227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        synchronized (mToneGeneratorLock) {
2237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            if (mToneGenerator == null) {
2247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                try {
2257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                    mToneGenerator = new ToneGenerator(DIAL_TONE_STREAM_TYPE, TONE_RELATIVE_VOLUME);
2267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                } catch (RuntimeException e) {
2277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                    Log.w(LOG_TAG, "Exception caught while creating local tone generator: " + e);
2287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                    mToneGenerator = null;
2297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                }
2307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            }
2317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        }
2327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon
2337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        final IntentFilter intentFilter = new IntentFilter();
2347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
2357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        registerReceiver(mBroadcastReceiver, intentFilter);
2367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon
2377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        try {
2387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            mHaptic.init(this, res.getBoolean(R.bool.config_enable_dialer_key_vibration));
2397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        } catch (Resources.NotFoundException nfe) {
2407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon             Log.e(LOG_TAG, "Vibrate control bool missing.", nfe);
2417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        }
2427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    }
2437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon
2447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    @Override
2457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    protected void onDestroy() {
2467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        super.onDestroy();
2477d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        synchronized (mToneGeneratorLock) {
2487d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            if (mToneGenerator != null) {
2497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                mToneGenerator.release();
2507d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                mToneGenerator = null;
2517d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            }
2527d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        }
2537d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        unregisterReceiver(mBroadcastReceiver);
2547d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    }
2557d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon
2567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    @Override
2577d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    protected void onRestoreInstanceState(Bundle icicle) {
2587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        mLastNumber = icicle.getString(LAST_NUMBER);
2597d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    }
2607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon
2617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    @Override
2627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    protected void onSaveInstanceState(Bundle outState) {
2637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        super.onSaveInstanceState(outState);
2647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        outState.putString(LAST_NUMBER, mLastNumber);
2657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    }
2667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon
2677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    /**
2687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon     * Explicitly turn off number formatting, since it gets in the way of the emergency
2697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon     * number detector
2707d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon     */
2717d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    protected void maybeAddNumberFormatting() {
2727d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        // Do nothing.
2737d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    }
2747d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon
2757d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    @Override
2767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    protected void onPostCreate(Bundle savedInstanceState) {
2777d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        super.onPostCreate(savedInstanceState);
2787d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon
2797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        // This can't be done in onCreate(), since the auto-restoring of the digits
2807d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        // will play DTMF tones for all the old digits if it is when onRestoreSavedInstanceState()
2817d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        // is called. This method will be called every time the activity is created, and
2827d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        // will always happen after onRestoreSavedInstanceState().
2837d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        mDigits.addTextChangedListener(this);
2847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    }
2857d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon
2867d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    private void setupKeypad() {
2877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        // Setup the listeners for the buttons
2887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        for (int id : DIALER_KEYS) {
2897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            final View key = findViewById(id);
2907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            key.setOnClickListener(this);
2917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            key.setOnHoverListener(this);
2927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        }
2937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon
2947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        View view = findViewById(R.id.zero);
2957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        view.setOnLongClickListener(this);
2967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    }
2977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon
2987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    /**
2997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon     * handle key events
3007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon     */
3017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    @Override
3027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    public boolean onKeyDown(int keyCode, KeyEvent event) {
3037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        switch (keyCode) {
3047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            // Happen when there's a "Call" hard button.
3057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            case KeyEvent.KEYCODE_CALL: {
3067d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                if (TextUtils.isEmpty(mDigits.getText().toString())) {
3077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                    // if we are adding a call from the InCallScreen and the phone
3087d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                    // number entered is empty, we just close the dialer to expose
3097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                    // the InCallScreen under it.
3107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                    finish();
3117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                } else {
3127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                    // otherwise, we place the call.
3137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                    placeCall();
3147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                }
3157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                return true;
3167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            }
3177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        }
3187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        return super.onKeyDown(keyCode, event);
3197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    }
3207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon
3217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    private void keyPressed(int keyCode) {
3227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        mHaptic.vibrate();
3237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        KeyEvent event = new KeyEvent(KeyEvent.ACTION_DOWN, keyCode);
3247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        mDigits.onKeyDown(keyCode, event);
3257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    }
3267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon
3277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    @Override
3287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    public boolean onKey(View view, int keyCode, KeyEvent event) {
3297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        switch (view.getId()) {
3307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            case R.id.digits:
3317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                // Happen when "Done" button of the IME is pressed. This can happen when this
3327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                // Activity is forced into landscape mode due to a desk dock.
3337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                if (keyCode == KeyEvent.KEYCODE_ENTER
3347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                        && event.getAction() == KeyEvent.ACTION_UP) {
3357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                    placeCall();
3367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                    return true;
3377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                }
3387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                break;
3397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        }
3407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        return false;
3417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    }
3427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon
3437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    @Override
3447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    public void onClick(View view) {
3457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        switch (view.getId()) {
3467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            case R.id.one: {
3477d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                playTone(ToneGenerator.TONE_DTMF_1);
3487d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                keyPressed(KeyEvent.KEYCODE_1);
3497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                return;
3507d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            }
3517d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            case R.id.two: {
3527d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                playTone(ToneGenerator.TONE_DTMF_2);
3537d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                keyPressed(KeyEvent.KEYCODE_2);
3547d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                return;
3557d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            }
3567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            case R.id.three: {
3577d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                playTone(ToneGenerator.TONE_DTMF_3);
3587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                keyPressed(KeyEvent.KEYCODE_3);
3597d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                return;
3607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            }
3617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            case R.id.four: {
3627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                playTone(ToneGenerator.TONE_DTMF_4);
3637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                keyPressed(KeyEvent.KEYCODE_4);
3647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                return;
3657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            }
3667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            case R.id.five: {
3677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                playTone(ToneGenerator.TONE_DTMF_5);
3687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                keyPressed(KeyEvent.KEYCODE_5);
3697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                return;
3707d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            }
3717d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            case R.id.six: {
3727d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                playTone(ToneGenerator.TONE_DTMF_6);
3737d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                keyPressed(KeyEvent.KEYCODE_6);
3747d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                return;
3757d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            }
3767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            case R.id.seven: {
3777d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                playTone(ToneGenerator.TONE_DTMF_7);
3787d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                keyPressed(KeyEvent.KEYCODE_7);
3797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                return;
3807d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            }
3817d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            case R.id.eight: {
3827d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                playTone(ToneGenerator.TONE_DTMF_8);
3837d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                keyPressed(KeyEvent.KEYCODE_8);
3847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                return;
3857d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            }
3867d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            case R.id.nine: {
3877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                playTone(ToneGenerator.TONE_DTMF_9);
3887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                keyPressed(KeyEvent.KEYCODE_9);
3897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                return;
3907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            }
3917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            case R.id.zero: {
3927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                playTone(ToneGenerator.TONE_DTMF_0);
3937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                keyPressed(KeyEvent.KEYCODE_0);
3947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                return;
3957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            }
3967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            case R.id.pound: {
3977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                playTone(ToneGenerator.TONE_DTMF_P);
3987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                keyPressed(KeyEvent.KEYCODE_POUND);
3997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                return;
4007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            }
4017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            case R.id.star: {
4027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                playTone(ToneGenerator.TONE_DTMF_S);
4037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                keyPressed(KeyEvent.KEYCODE_STAR);
4047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                return;
4057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            }
4067d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            case R.id.deleteButton: {
4077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                keyPressed(KeyEvent.KEYCODE_DEL);
4087d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                return;
4097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            }
4107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            case R.id.dialButton: {
4117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                mHaptic.vibrate();  // Vibrate here too, just like we do for the regular keys
4127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                placeCall();
4137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                return;
4147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            }
4157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            case R.id.digits: {
4167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                if (mDigits.length() != 0) {
4177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                    mDigits.setCursorVisible(true);
4187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                }
4197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                return;
4207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            }
4217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        }
4227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    }
4237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon
4247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    /**
4257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon     * Implemented for {@link android.view.View.OnHoverListener}. Handles touch
4267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon     * events for accessibility when touch exploration is enabled.
4277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon     */
4287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    @Override
4297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    public boolean onHover(View v, MotionEvent event) {
4307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        // When touch exploration is turned on, lifting a finger while inside
4317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        // the button's hover target bounds should perform a click action.
4327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        if (mAccessibilityManager.isEnabled()
4337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                && mAccessibilityManager.isTouchExplorationEnabled()) {
4347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon
4357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            switch (event.getActionMasked()) {
4367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                case MotionEvent.ACTION_HOVER_ENTER:
4377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                    // Lift-to-type temporarily disables double-tap activation.
4387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                    v.setClickable(false);
4397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                    break;
4407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                case MotionEvent.ACTION_HOVER_EXIT:
4417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                    final int left = v.getPaddingLeft();
4427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                    final int right = (v.getWidth() - v.getPaddingRight());
4437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                    final int top = v.getPaddingTop();
4447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                    final int bottom = (v.getHeight() - v.getPaddingBottom());
4457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                    final int x = (int) event.getX();
4467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                    final int y = (int) event.getY();
4477d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                    if ((x > left) && (x < right) && (y > top) && (y < bottom)) {
4487d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                        v.performClick();
4497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                    }
4507d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                    v.setClickable(true);
4517d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                    break;
4527d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            }
4537d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        }
4547d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon
4557d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        return false;
4567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    }
4577d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon
4587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    /**
4597d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon     * called for long touch events
4607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon     */
4617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    @Override
4627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    public boolean onLongClick(View view) {
4637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        int id = view.getId();
4647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        switch (id) {
4657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            case R.id.deleteButton: {
4667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                mDigits.getText().clear();
4677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                // TODO: The framework forgets to clear the pressed
4687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                // status of disabled button. Until this is fixed,
4697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                // clear manually the pressed status. b/2133127
4707d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                mDelete.setPressed(false);
4717d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                return true;
4727d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            }
4737d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            case R.id.zero: {
4747d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                keyPressed(KeyEvent.KEYCODE_PLUS);
4757d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                return true;
4767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            }
4777d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        }
4787d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        return false;
4797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    }
4807d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon
4817d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    @Override
4827d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    protected void onResume() {
4837d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        super.onResume();
4847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon
4857d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        // retrieve the DTMF tone play back setting.
4867d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        mDTMFToneEnabled = Settings.System.getInt(getContentResolver(),
4877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                Settings.System.DTMF_TONE_WHEN_DIALING, 1) == 1;
4887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon
4897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        // Retrieve the haptic feedback setting.
4907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        mHaptic.checkSystemSetting();
4917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon
4927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        // if the mToneGenerator creation fails, just continue without it.  It is
4937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        // a local audio signal, and is not as important as the dtmf tone itself.
4947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        synchronized (mToneGeneratorLock) {
4957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            if (mToneGenerator == null) {
4967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                try {
4977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                    mToneGenerator = new ToneGenerator(AudioManager.STREAM_DTMF,
4987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                            TONE_RELATIVE_VOLUME);
4997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                } catch (RuntimeException e) {
5007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                    Log.w(LOG_TAG, "Exception caught while creating local tone generator: " + e);
5017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                    mToneGenerator = null;
5027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                }
5037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            }
5047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        }
5057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon
5067d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        // Disable the status bar and set the poke lock timeout to medium.
5077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        // There is no need to do anything with the wake lock.
5087d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        if (DBG) Log.d(LOG_TAG, "disabling status bar, set to long timeout");
5097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        mStatusBarManager.disable(StatusBarManager.DISABLE_EXPAND);
5107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon
5117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        updateDialAndDeleteButtonStateEnabledAttr();
5127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    }
5137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon
5147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    @Override
5157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    public void onPause() {
5167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        // Reenable the status bar and set the poke lock timeout to default.
5177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        // There is no need to do anything with the wake lock.
5187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        if (DBG) Log.d(LOG_TAG, "reenabling status bar and closing the dialer");
5197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        mStatusBarManager.disable(StatusBarManager.DISABLE_NONE);
5207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon
5217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        super.onPause();
5227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon
5237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        synchronized (mToneGeneratorLock) {
5247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            if (mToneGenerator != null) {
5257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                mToneGenerator.release();
5267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                mToneGenerator = null;
5277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            }
5287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        }
5297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    }
5307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon
5317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    /**
5327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon     * place the call, but check to make sure it is a viable number.
5337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon     */
5347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    private void placeCall() {
5357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        mLastNumber = mDigits.getText().toString();
5367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        if (PhoneNumberUtils.isLocalEmergencyNumber(mLastNumber, this)) {
5377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            if (DBG) Log.d(LOG_TAG, "placing call to " + mLastNumber);
5387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon
5397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            // place the call if it is a valid number
5407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            if (mLastNumber == null || !TextUtils.isGraphic(mLastNumber)) {
5417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                // There is no number entered.
5427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                playTone(ToneGenerator.TONE_PROP_NACK);
5437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                return;
5447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            }
5457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            Intent intent = new Intent(Intent.ACTION_CALL_EMERGENCY);
5467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            intent.setData(Uri.fromParts(Constants.SCHEME_TEL, mLastNumber, null));
5477d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
5487d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            startActivity(intent);
5497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            finish();
5507d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        } else {
5517d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            if (DBG) Log.d(LOG_TAG, "rejecting bad requested number " + mLastNumber);
5527d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon
5537d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            // erase the number and throw up an alert dialog.
5547d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            mDigits.getText().delete(0, mDigits.getText().length());
5557d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            showDialog(BAD_EMERGENCY_NUMBER_DIALOG);
5567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        }
5577d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    }
5587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon
5597d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    /**
5607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon     * Plays the specified tone for TONE_LENGTH_MS milliseconds.
5617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon     *
5627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon     * The tone is played locally, using the audio stream for phone calls.
5637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon     * Tones are played only if the "Audible touch tones" user preference
5647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon     * is checked, and are NOT played if the device is in silent mode.
5657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon     *
5667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon     * @param tone a tone code from {@link ToneGenerator}
5677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon     */
5687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    void playTone(int tone) {
5697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        // if local tone playback is disabled, just return.
5707d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        if (!mDTMFToneEnabled) {
5717d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            return;
5727d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        }
5737d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon
5747d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        // Also do nothing if the phone is in silent mode.
5757d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        // We need to re-check the ringer mode for *every* playTone()
5767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        // call, rather than keeping a local flag that's updated in
5777d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        // onResume(), since it's possible to toggle silent mode without
5787d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        // leaving the current activity (via the ENDCALL-longpress menu.)
5797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
5807d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        int ringerMode = audioManager.getRingerMode();
5817d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        if ((ringerMode == AudioManager.RINGER_MODE_SILENT)
5827d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            || (ringerMode == AudioManager.RINGER_MODE_VIBRATE)) {
5837d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            return;
5847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        }
5857d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon
5867d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        synchronized (mToneGeneratorLock) {
5877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            if (mToneGenerator == null) {
5887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                Log.w(LOG_TAG, "playTone: mToneGenerator == null, tone: " + tone);
5897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                return;
5907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            }
5917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon
5927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            // Start the new tone (will stop any playing tone)
5937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            mToneGenerator.startTone(tone, TONE_LENGTH_MS);
5947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        }
5957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    }
5967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon
5977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    private CharSequence createErrorMessage(String number) {
5987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        if (!TextUtils.isEmpty(number)) {
5997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            return getString(R.string.dial_emergency_error, mLastNumber);
6007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        } else {
6017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            return getText(R.string.dial_emergency_empty_error).toString();
6027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        }
6037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    }
6047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon
6057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    @Override
6067d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    protected Dialog onCreateDialog(int id) {
6077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        AlertDialog dialog = null;
6087d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        if (id == BAD_EMERGENCY_NUMBER_DIALOG) {
6097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            // construct dialog
6107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            dialog = new AlertDialog.Builder(this)
6117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                    .setTitle(getText(R.string.emergency_enable_radio_dialog_title))
6127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                    .setMessage(createErrorMessage(mLastNumber))
6137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                    .setPositiveButton(R.string.ok, null)
6147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon                    .setCancelable(true).create();
6157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon
6167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            // blur stuff behind the dialog
6177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            dialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND);
6187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        }
6197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        return dialog;
6207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    }
6217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon
6227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    @Override
6237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    protected void onPrepareDialog(int id, Dialog dialog) {
6247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        super.onPrepareDialog(id, dialog);
6257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        if (id == BAD_EMERGENCY_NUMBER_DIALOG) {
6267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            AlertDialog alert = (AlertDialog) dialog;
6277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon            alert.setMessage(createErrorMessage(mLastNumber));
6287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        }
6297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    }
6307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon
6317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    /**
6327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon     * Update the enabledness of the "Dial" and "Backspace" buttons if applicable.
6337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon     */
6347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    private void updateDialAndDeleteButtonStateEnabledAttr() {
6357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        final boolean notEmpty = mDigits.length() != 0;
6367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon
6377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        mDialButton.setEnabled(notEmpty);
6387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon        mDelete.setEnabled(notEmpty);
6397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon    }
6407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon}
641