1b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh/*
2b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * Copyright (c) 2008-2009, Motorola, Inc.
3b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh *
4b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * All rights reserved.
5b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh *
6b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * Redistribution and use in source and binary forms, with or without
7b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * modification, are permitted provided that the following conditions are met:
8b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh *
9b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * - Redistributions of source code must retain the above copyright notice,
10b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * this list of conditions and the following disclaimer.
11b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh *
12b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * - Redistributions in binary form must reproduce the above copyright notice,
13b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * this list of conditions and the following disclaimer in the documentation
14b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * and/or other materials provided with the distribution.
15b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh *
16b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * - Neither the name of the Motorola, Inc. nor the names of its contributors
17b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * may be used to endorse or promote products derived from this software
18b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * without specific prior written permission.
19b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh *
20b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
24b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * POSSIBILITY OF SUCH DAMAGE.
31b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh */
322c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
332c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fanpackage com.android.bluetooth.pbap;
342c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
352c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fanimport com.android.bluetooth.R;
362c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
372c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fanimport android.content.BroadcastReceiver;
382c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fanimport android.content.Context;
392c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fanimport android.content.DialogInterface;
402c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fanimport android.content.Intent;
412c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fanimport android.content.IntentFilter;
422c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fanimport android.os.Bundle;
43b0fa09caef6a0748a568dc2a89f5d94b85423bb2Lixin Yueimport android.os.Handler;
44b0fa09caef6a0748a568dc2a89f5d94b85423bb2Lixin Yueimport android.os.Message;
452c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fanimport android.preference.Preference;
462c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fanimport android.util.Log;
472c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fanimport android.view.View;
482c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fanimport android.widget.CheckBox;
492c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fanimport android.widget.CompoundButton;
502c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fanimport android.widget.EditText;
512c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fanimport android.widget.TextView;
522c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fanimport android.widget.Button;
532c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fanimport android.widget.CompoundButton.OnCheckedChangeListener;
542c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fanimport android.text.InputFilter;
552c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fanimport android.text.TextWatcher;
562c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fanimport android.text.InputFilter.LengthFilter;
572c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
582c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fanimport com.android.internal.app.AlertActivity;
592c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fanimport com.android.internal.app.AlertController;
602c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
612c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan/**
622c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan * PbapActivity shows two dialogues: One for accepting incoming pbap request and
632c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan * the other prompts the user to enter a session key for authentication with a
642c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan * remote Bluetooth device.
652c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan */
662c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fanpublic class BluetoothPbapActivity extends AlertActivity implements
672c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        DialogInterface.OnClickListener, Preference.OnPreferenceChangeListener, TextWatcher {
682c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    private static final String TAG = "BluetoothPbapActivity";
692c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
70b0fa09caef6a0748a568dc2a89f5d94b85423bb2Lixin Yue    private static final boolean V = BluetoothPbapService.VERBOSE;
71b0fa09caef6a0748a568dc2a89f5d94b85423bb2Lixin Yue
722c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    private static final int BLUETOOTH_OBEX_AUTHKEY_MAX_LENGTH = 16;
732c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
747eab97d6be9228b1c210bbb171c3e5e88e02f3d8Matthew Xie    private static final int DIALOG_YES_NO_AUTH = 1;
752c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
76d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue    private static final String KEY_USER_TIMEOUT = "user_timeout";
77d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue
782c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    private View mView;
792c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
802c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    private EditText mKeyView;
812c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
822c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    private TextView messageView;
832c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
842c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    private String mSessionKey = "";
852c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
86d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue    private int mCurrentDialog;
872c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
882c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    private Button mOkButton;
892c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
902c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    private CheckBox mAlwaysAllowed;
912c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
92d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue    private boolean mTimeout = false;
932c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
94acab258c177d82338b1696360cd0b8c9821b0f03Lixin Yue    private boolean mAlwaysAllowedValue = true;
952c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
96b0fa09caef6a0748a568dc2a89f5d94b85423bb2Lixin Yue    private static final int DISMISS_TIMEOUT_DIALOG = 0;
97b0fa09caef6a0748a568dc2a89f5d94b85423bb2Lixin Yue
98b0fa09caef6a0748a568dc2a89f5d94b85423bb2Lixin Yue    private static final int DISMISS_TIMEOUT_DIALOG_VALUE = 2000;
99b0fa09caef6a0748a568dc2a89f5d94b85423bb2Lixin Yue
1002c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    private BroadcastReceiver mReceiver = new BroadcastReceiver() {
1012c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        @Override
1022c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        public void onReceive(Context context, Intent intent) {
103d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue            if (!BluetoothPbapService.USER_CONFIRM_TIMEOUT_ACTION.equals(intent.getAction())) {
1042c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                return;
1052c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            }
106d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue            onTimeout();
1072c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        }
1082c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    };
1092c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
1102c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    @Override
1112c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    protected void onCreate(Bundle savedInstanceState) {
1122c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        super.onCreate(savedInstanceState);
1132c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        Intent i = getIntent();
1142c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        String action = i.getAction();
1157eab97d6be9228b1c210bbb171c3e5e88e02f3d8Matthew Xie        if (action.equals(BluetoothPbapService.AUTH_CHALL_ACTION)) {
1162c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            showPbapDialog(DIALOG_YES_NO_AUTH);
1172c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            mCurrentDialog = DIALOG_YES_NO_AUTH;
1182c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        } else {
1192c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            Log.e(TAG, "Error: this activity may be started only with intent "
1202c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                    + "PBAP_ACCESS_REQUEST or PBAP_AUTH_CHALL ");
1212c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            finish();
1222c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        }
1234446eaa935994bc91d6d308303e8d27526b4590dLixin Yue        registerReceiver(mReceiver, new IntentFilter(
1244446eaa935994bc91d6d308303e8d27526b4590dLixin Yue                BluetoothPbapService.USER_CONFIRM_TIMEOUT_ACTION));
1252c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    }
1262c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
1272c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    private void showPbapDialog(int id) {
1282c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        final AlertController.AlertParams p = mAlertParams;
1292c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        switch (id) {
1302c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            case DIALOG_YES_NO_AUTH:
1312c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                p.mTitle = getString(R.string.pbap_session_key_dialog_header);
1322c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                p.mView = createView(DIALOG_YES_NO_AUTH);
1332c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                p.mPositiveButtonText = getString(android.R.string.ok);
1342c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                p.mPositiveButtonListener = this;
1352c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                p.mNegativeButtonText = getString(android.R.string.cancel);
1362c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                p.mNegativeButtonListener = this;
1372c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                setupAlert();
1382c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                mOkButton = mAlert.getButton(DialogInterface.BUTTON_POSITIVE);
1392c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                mOkButton.setEnabled(false);
1402c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                break;
1412c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            default:
1422c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                break;
1432c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        }
1442c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    }
1452c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
1462c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    private String createDisplayText(final int id) {
1472c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        String mRemoteName = BluetoothPbapService.getRemoteDeviceName();
1482c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        switch (id) {
1492c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            case DIALOG_YES_NO_AUTH:
1502c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                String mMessage2 = getString(R.string.pbap_session_key_dialog_title, mRemoteName);
1512c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                return mMessage2;
1522c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            default:
1532c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                return null;
1542c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        }
1552c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    }
1562c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
1572c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    private View createView(final int id) {
1582c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        switch (id) {
1592c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            case DIALOG_YES_NO_AUTH:
1602c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                mView = getLayoutInflater().inflate(R.layout.auth, null);
1612c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                messageView = (TextView)mView.findViewById(R.id.message);
1622c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                messageView.setText(createDisplayText(id));
1632c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                mKeyView = (EditText)mView.findViewById(R.id.text);
1642c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                mKeyView.addTextChangedListener(this);
1652c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                mKeyView.setFilters(new InputFilter[] {
1662c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                    new LengthFilter(BLUETOOTH_OBEX_AUTHKEY_MAX_LENGTH)
1672c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                });
1682c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                return mView;
1692c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            default:
1702c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                return null;
1712c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        }
1722c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    }
1732c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
1742c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    private void onPositive() {
175d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue        if (!mTimeout) {
1767eab97d6be9228b1c210bbb171c3e5e88e02f3d8Matthew Xie            if (mCurrentDialog == DIALOG_YES_NO_AUTH) {
177d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue                sendIntentToReceiver(BluetoothPbapService.AUTH_RESPONSE_ACTION,
178d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue                        BluetoothPbapService.EXTRA_SESSION_KEY, mSessionKey);
1792c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                mKeyView.removeTextChangedListener(this);
1802c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            }
1812c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        }
182d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue        mTimeout = false;
1832c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        finish();
1842c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    }
1852c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
1862c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    private void onNegative() {
1877eab97d6be9228b1c210bbb171c3e5e88e02f3d8Matthew Xie        if (mCurrentDialog == DIALOG_YES_NO_AUTH) {
188d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue            sendIntentToReceiver(BluetoothPbapService.AUTH_CANCELLED_ACTION, null, null);
1892c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            mKeyView.removeTextChangedListener(this);
1902c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        }
1912c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        finish();
1922c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    }
1932c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
1942c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    private void sendIntentToReceiver(final String intentName, final String extraName,
1952c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            final String extraValue) {
1962c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        Intent intent = new Intent(intentName);
1972c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        intent.setClassName(BluetoothPbapService.THIS_PACKAGE_NAME, BluetoothPbapReceiver.class
1982c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                .getName());
1992c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        if (extraName != null) {
2002c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            intent.putExtra(extraName, extraValue);
2012c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        }
2022c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        sendBroadcast(intent);
2032c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    }
2042c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
2052c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    private void sendIntentToReceiver(final String intentName, final String extraName,
2062c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            final boolean extraValue) {
2072c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        Intent intent = new Intent(intentName);
2082c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        intent.setClassName(BluetoothPbapService.THIS_PACKAGE_NAME, BluetoothPbapReceiver.class
2092c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                .getName());
2102c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        if (extraName != null) {
2112c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            intent.putExtra(extraName, extraValue);
2122c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        }
2132c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        sendBroadcast(intent);
2142c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    }
2152c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
2162c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    public void onClick(DialogInterface dialog, int which) {
2172c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        switch (which) {
2182c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            case DialogInterface.BUTTON_POSITIVE:
2192c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                if (mCurrentDialog == DIALOG_YES_NO_AUTH) {
2202c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                    mSessionKey = mKeyView.getText().toString();
2212c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                }
2222c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                onPositive();
2232c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                break;
2242c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
2252c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            case DialogInterface.BUTTON_NEGATIVE:
2262c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                onNegative();
2272c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                break;
2284446eaa935994bc91d6d308303e8d27526b4590dLixin Yue            default:
2294446eaa935994bc91d6d308303e8d27526b4590dLixin Yue                break;
2302c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        }
2312c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    }
2322c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
233d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue    private void onTimeout() {
234d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue        mTimeout = true;
2357eab97d6be9228b1c210bbb171c3e5e88e02f3d8Matthew Xie        if (mCurrentDialog == DIALOG_YES_NO_AUTH) {
2362c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            messageView.setText(getString(R.string.pbap_authentication_timeout_message,
2372c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                    BluetoothPbapService.getRemoteDeviceName()));
2382c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            mKeyView.setVisibility(View.GONE);
2392c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            mKeyView.clearFocus();
2402c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            mKeyView.removeTextChangedListener(this);
2412c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            mOkButton.setEnabled(true);
2422c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            mAlert.getButton(DialogInterface.BUTTON_NEGATIVE).setVisibility(View.GONE);
2432c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        }
244b0fa09caef6a0748a568dc2a89f5d94b85423bb2Lixin Yue
245b0fa09caef6a0748a568dc2a89f5d94b85423bb2Lixin Yue        mTimeoutHandler.sendMessageDelayed(mTimeoutHandler.obtainMessage(DISMISS_TIMEOUT_DIALOG),
246b0fa09caef6a0748a568dc2a89f5d94b85423bb2Lixin Yue                DISMISS_TIMEOUT_DIALOG_VALUE);
2472c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    }
2482c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
2492c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    @Override
2502c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    protected void onRestoreInstanceState(Bundle savedInstanceState) {
2512c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        super.onRestoreInstanceState(savedInstanceState);
252d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue        mTimeout = savedInstanceState.getBoolean(KEY_USER_TIMEOUT);
253b0fa09caef6a0748a568dc2a89f5d94b85423bb2Lixin Yue        if (V) Log.v(TAG, "onRestoreInstanceState() mTimeout: " + mTimeout);
254b0fa09caef6a0748a568dc2a89f5d94b85423bb2Lixin Yue        if (mTimeout) {
255b0fa09caef6a0748a568dc2a89f5d94b85423bb2Lixin Yue            onTimeout();
256b0fa09caef6a0748a568dc2a89f5d94b85423bb2Lixin Yue        }
2572c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    }
2582c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
2592c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    @Override
2602c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    protected void onSaveInstanceState(Bundle outState) {
2612c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        super.onSaveInstanceState(outState);
262d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue        outState.putBoolean(KEY_USER_TIMEOUT, mTimeout);
2632c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    }
2642c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
2652c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    @Override
2662c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    protected void onDestroy() {
2672c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        super.onDestroy();
2682c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        unregisterReceiver(mReceiver);
2692c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    }
2702c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
2712c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    public boolean onPreferenceChange(Preference preference, Object newValue) {
2722c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        return true;
2732c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    }
2742c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
2752c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    public void beforeTextChanged(CharSequence s, int start, int before, int after) {
2762c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    }
2772c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
2782c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    public void onTextChanged(CharSequence s, int start, int before, int count) {
2792c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    }
2802c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
2812c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    public void afterTextChanged(android.text.Editable s) {
2822c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        if (s.length() > 0) {
2832c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            mOkButton.setEnabled(true);
2842c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        }
2852c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    }
286b0fa09caef6a0748a568dc2a89f5d94b85423bb2Lixin Yue
287b0fa09caef6a0748a568dc2a89f5d94b85423bb2Lixin Yue    private final Handler mTimeoutHandler = new Handler() {
288b0fa09caef6a0748a568dc2a89f5d94b85423bb2Lixin Yue        @Override
289b0fa09caef6a0748a568dc2a89f5d94b85423bb2Lixin Yue        public void handleMessage(Message msg) {
290b0fa09caef6a0748a568dc2a89f5d94b85423bb2Lixin Yue            switch (msg.what) {
291b0fa09caef6a0748a568dc2a89f5d94b85423bb2Lixin Yue                case DISMISS_TIMEOUT_DIALOG:
292b0fa09caef6a0748a568dc2a89f5d94b85423bb2Lixin Yue                    if (V) Log.v(TAG, "Received DISMISS_TIMEOUT_DIALOG msg.");
293b0fa09caef6a0748a568dc2a89f5d94b85423bb2Lixin Yue                    finish();
294b0fa09caef6a0748a568dc2a89f5d94b85423bb2Lixin Yue                    break;
295b0fa09caef6a0748a568dc2a89f5d94b85423bb2Lixin Yue                default:
296b0fa09caef6a0748a568dc2a89f5d94b85423bb2Lixin Yue                    break;
297b0fa09caef6a0748a568dc2a89f5d94b85423bb2Lixin Yue            }
298b0fa09caef6a0748a568dc2a89f5d94b85423bb2Lixin Yue        }
299b0fa09caef6a0748a568dc2a89f5d94b85423bb2Lixin Yue    };
3002c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan}
301