BluetoothPbapService.java revision 37b69bd05e4b7a7d0e43575a6c22734b2d8c3f69
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.app.Service;
382c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fanimport android.content.Context;
392c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fanimport android.content.Intent;
402c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fanimport android.bluetooth.BluetoothDevice;
412c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fanimport android.bluetooth.BluetoothError;
422c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fanimport android.bluetooth.BluetoothHeadset;
432c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fanimport android.bluetooth.BluetoothIntent;
4437b69bd05e4b7a7d0e43575a6c22734b2d8c3f69Jackson Fanimport android.bluetooth.BluetoothPbap;
452c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fanimport android.bluetooth.BluetoothSocket;
462c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fanimport android.bluetooth.BluetoothServerSocket;
4737b69bd05e4b7a7d0e43575a6c22734b2d8c3f69Jackson Fanimport android.bluetooth.IBluetoothPbap;
482c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fanimport android.os.Handler;
492c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fanimport android.os.IBinder;
502c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fanimport android.os.Message;
512c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fanimport android.os.PowerManager;
522c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fanimport android.telephony.TelephonyManager;
532c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fanimport android.util.Log;
542c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fanimport android.widget.Toast;
552c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
562c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fanimport java.io.IOException;
572c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fanimport java.util.ArrayList;
582c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
592c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fanimport javax.obex.ServerSession;
602c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
612c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fanpublic class BluetoothPbapService extends Service {
622c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
632c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    private static final String TAG = "BluetoothPbapService";
642c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
6587f9a72cc2d9544f65eab18893f7dc0de4f6ee31Jaikumar Ganesh    public static final boolean DBG = false;
662c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
672c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    /**
682c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan     * Intent indicating incoming connection request which is sent to
692c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan     * BluetoothPbapActivity
702c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan     */
712c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    public static final String ACCESS_REQUEST = "com.android.bluetooth.pbap.accessrequest";
722c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
732c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    /**
742c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan     * Intent indicating incoming connection request accepted by user which is
752c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan     * sent from BluetoothPbapActivity
762c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan     */
772c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    public static final String ACCESS_ALLOWED = "com.android.bluetooth.pbap.accessallowed";
782c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
792c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    /**
802c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan     * Intent indicating incoming connection request denied by user which is
812c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan     * sent from BluetoothPbapActivity
822c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan     */
832c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    public static final String ACCESS_DISALLOWED = "com.android.bluetooth.pbap.accessdisallowed";
842c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
852c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    /**
862c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan     * Intent indicating incoming obex authentication request which is from
872c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan     * PCE(Carkit)
882c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan     */
892c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    public static final String AUTH_CHALL = "com.android.bluetooth.pbap.authchall";
902c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
912c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    /**
922c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan     * Intent indicating obex session key input complete by user which is sent
932c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan     * from BluetoothPbapActivity
942c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan     */
952c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    public static final String AUTH_RESPONSE = "com.android.bluetooth.pbap.authresponse";
962c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
972c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    /**
982c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan     * Intent indicating user canceled obex authentication session key input
992c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan     * which is sent from BluetoothPbapActivity
1002c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan     */
1012c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    public static final String AUTH_CANCELLED = "com.android.bluetooth.pbap.authcancelled";
1022c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
1032c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    /**
1042c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan     * Intent indicating user confirmation timeout which is sent to
1052c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan     * BluetoothPbapActivity
1062c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan     */
1072c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    public static final String USER_CONFIRM_TIMEOUT = "com.android.bluetooth.pbap.userconfirmtimeout";
1082c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
1092c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    /**
1102c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan     * Intent Extra name indicating always allowed which is sent from
1112c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan     * BluetoothPbapActivity
1122c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan     */
1132c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    public static final String ALWAYS_ALLOWED = "com.android.bluetooth.pbap.alwaysallowed";
1142c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
1152c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    /**
1162c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan     * Intent Extra name indicating session key which is sent from
1172c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan     * BluetoothPbapActivity
1182c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan     */
1192c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    public static final String SESSION_KEY = "com.android.bluetooth.pbap.sessionkey";
1202c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
1212c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    public static final String THIS_PACKAGE_NAME = "com.android.bluetooth";
1222c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
1232c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    public static final int MSG_SERVERSESSION_CLOSE = 5000;
1242c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
1252c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    public static final int MSG_SESSION_ESTABLISHED = 5001;
1262c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
1272c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    public static final int MSG_SESSION_DISCONNECTED = 5002;
1282c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
1292c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    public static final int MSG_OBEX_AUTH_CHALL = 5003;
1302c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
1312c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    private static final String BLUETOOTH_PERM = android.Manifest.permission.BLUETOOTH;
1322c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
1332c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    private static final String BLUETOOTH_ADMIN_PERM = android.Manifest.permission.BLUETOOTH_ADMIN;
1342c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
1352c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    private static final int START_LISTENER = 1;
1362c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
1372c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    private static final int USER_TIMEOUT = 2;
1382c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
1392c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    private static final int AUTH_TIMEOUT = 3;
1402c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
1412c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    private PowerManager.WakeLock mWakeLock = null;
1422c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
1432c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    private BluetoothDevice mBluetooth;
1442c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
1452c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    private SocketAcceptThread mAcceptThread = null;
1462c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
1472c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    private BluetoothPbapObexServer mPbapServer;
1482c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
1492c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    private ServerSession mServerSession = null;
1502c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
1512c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    private BluetoothServerSocket mServerSocket = null;
1522c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
1532c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    private BluetoothSocket mConnSocket = null;
1542c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
1552c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    private String mDeviceAddr = null;
1562c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
1572c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    private static String sLocalPhoneNum = null;
1582c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
1592c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    private static String sLocalPhoneName = null;
1602c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
1612c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    private static String sRemoteDeviceName = null;
1622c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
1632c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    private String mRemoteAddr = null;
1642c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
1652c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    private boolean mHasStarted = false;
1662c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
1672c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    private int mState;
1682c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
1692c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    private int mStartId = -1;
1702c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
1712c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    private static final int PORT_NUM = 19;
1722c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
1732c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    private static final int USER_CONFIRM_TIMEOUT_VALUE = 30000;
1742c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
1752c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    private static final int SOCKET_ACCEPT_TIMEOUT_VALUE = 5000;
1762c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
1772c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    private static final int TIME_TO_WAIT_VALUE = 6000;
1782c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
1792c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    private static BluetoothPbapVcardManager sVcardManager;
1802c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
1812c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    private CharSequence mTmpTxt;
1822c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
1832c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    private BluetoothPbapAuthenticator mAuth = null;
1842c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
1852c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    public BluetoothPbapService() {
18637b69bd05e4b7a7d0e43575a6c22734b2d8c3f69Jackson Fan        mState = BluetoothPbap.STATE_DISCONNECTED;
1872c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    }
1882c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
1892c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    @Override
1902c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    public void onCreate() {
1912c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        super.onCreate();
1922c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        mBluetooth = (BluetoothDevice)getSystemService(Context.BLUETOOTH_SERVICE);
1932c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        if (mBluetooth != null) {
1942c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            mDeviceAddr = mBluetooth.getAddress();
1952c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        }
1962c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        sVcardManager = new BluetoothPbapVcardManager(BluetoothPbapService.this);
1972c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        if (!mHasStarted && mDeviceAddr != null) {
1982c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            mHasStarted = true;
1992c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            Log.i(TAG, "Starting PBAP service");
2002c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            int state = mBluetooth.getBluetoothState();
2012c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            if (state == BluetoothDevice.BLUETOOTH_STATE_ON) {
2022c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                mSessionStatusHandler.sendMessageDelayed(mSessionStatusHandler
2032c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                        .obtainMessage(START_LISTENER), TIME_TO_WAIT_VALUE);
2042c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            }
2052c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        }
2062c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    }
2072c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
2082c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    @Override
2092c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    public void onStart(Intent intent, int startId) {
2102c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        mStartId = startId;
2112c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        if (mBluetooth == null || mDeviceAddr == null) {
2122c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            Log.w(TAG, "Stopping BluetoothHeadsetService: "
2132c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                    + "device does not have BT or device is not ready");
2142c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            closeService(); // release all resources
2152c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        } else {
2162c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            parseIntent(intent);
2172c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        }
2182c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    }
2192c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
2202c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    // process the intent from receiver
2212c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    private void parseIntent(final Intent intent) {
2222c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        String action = intent.getExtras().getString("action");
2232c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        int state = intent.getIntExtra(BluetoothIntent.BLUETOOTH_STATE, BluetoothError.ERROR);
2242c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        if (action.equals(BluetoothIntent.BLUETOOTH_STATE_CHANGED_ACTION)) {
2252c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            if (state == BluetoothDevice.BLUETOOTH_STATE_OFF) {
2262c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                closeService(); // release all resources
2272c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            }
2282c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        }
2292c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
2302c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        if (action.equals(ACCESS_ALLOWED)) {
2312c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            mSessionStatusHandler.removeMessages(USER_TIMEOUT);
2322c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            if (intent.getBooleanExtra(ALWAYS_ALLOWED, false)) {
2332c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                // TODO: have dependency on device trust feature implementation
2342c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                // mBluetooth.setTrust(mRemoteAddr, true);
2352c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            }
2362c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            try {
2372c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                // In case carkit time out and try to use HFP for phonebook
2382c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                // access ,while UI still there for user to comfirm
2392c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                if (mConnSocket != null) {
2402c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                    startObexServerSession();
2412c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                } else {
2422c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                    obexServerSessionClose();
2432c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                }
2442c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            } catch (IOException ex) {
24587f9a72cc2d9544f65eab18893f7dc0de4f6ee31Jaikumar Ganesh                if (DBG) {
24687f9a72cc2d9544f65eab18893f7dc0de4f6ee31Jaikumar Ganesh                    Log.e(TAG, "Caught the error: " + ex.toString());
24787f9a72cc2d9544f65eab18893f7dc0de4f6ee31Jaikumar Ganesh                }
2482c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            }
2492c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        }
2502c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
2512c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        if (action.equals(ACCESS_DISALLOWED)) {
2522c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            mSessionStatusHandler.removeMessages(USER_TIMEOUT);
2532c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            obexServerSessionClose();
2542c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        }
2552c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
2562c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        if (action.equals(AUTH_RESPONSE)) {
2572c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            mSessionStatusHandler.removeMessages(USER_TIMEOUT);
2582c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            String sessionkey = intent.getStringExtra(SESSION_KEY);
2592c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            notifyAuthKeyInput(sessionkey);
2602c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        }
2612c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
2622c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        if (action.equals(AUTH_CANCELLED)) {
2632c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            mSessionStatusHandler.removeMessages(USER_TIMEOUT);
2642c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            notifyAuthCancelled();
2652c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        }
2662c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    }
2672c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
2682c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    @Override
2692c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    public void onDestroy() {
2702c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        super.onDestroy();
27137b69bd05e4b7a7d0e43575a6c22734b2d8c3f69Jackson Fan        setState(BluetoothPbap.STATE_DISCONNECTED, BluetoothPbap.RESULT_CANCELED);
2722c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    }
2732c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
2742c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    @Override
2752c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    public IBinder onBind(Intent intent) {
27637b69bd05e4b7a7d0e43575a6c22734b2d8c3f69Jackson Fan        return mBinder;
2772c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    }
2782c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
2792c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    public static int getPhonebookSize(final int type) {
2802c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        if (DBG) {
2812c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            Log.d(TAG, "getPhonebookSzie type=" + type);
2822c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        }
2832c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        switch (type) {
2842c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            case BluetoothPbapObexServer.NEED_PHONEBOOK:
2852c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                return sVcardManager.getPhonebookSize();
2862c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            default:
2872c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                return sVcardManager.getCallHistorySize(type);
2882c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        }
2892c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    }
2902c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
2912c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    public static String getPhonebook(final int type, final int pos, final boolean vcardType) {
2922c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        if (DBG) {
2932c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            Log.d(TAG, "getPhonebook type=" + type + " pos=" + pos + " vcardType=" + vcardType);
2942c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        }
2952c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        switch (type) {
2962c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            case BluetoothPbapObexServer.NEED_PHONEBOOK:
2972c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                return sVcardManager.getPhonebook(pos, vcardType);
2982c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            default:
2992c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                return sVcardManager.getCallHistory(pos, type, vcardType);
3002c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        }
3012c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    }
3022c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
3032c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    public static String getLocalPhoneNum() {
3042c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        return sLocalPhoneNum;
3052c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    }
3062c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
3072c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    public static String getLocalPhoneName() {
3082c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        return sLocalPhoneName;
3092c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    }
3102c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
3112c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    public static String getRemoteDeviceName() {
3122c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        return sRemoteDeviceName;
3132c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    }
3142c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
3152c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    // Used for phone book listing by name
3162c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    public static ArrayList<String> getPhonebookNameList() {
3172c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        return sVcardManager.loadNameList();
3182c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    }
3192c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
3202c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    // Used for phone book listing by number
3212c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    public static ArrayList<String> getPhonebookNumberList() {
3222c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        return sVcardManager.loadNumberList();
3232c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    }
3242c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
3252c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    // Used for call history listing
3262c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    public static ArrayList<String> getCallLogList(final int type) {
3272c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        return sVcardManager.loadCallHistoryList(type);
3282c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    }
3292c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
3302c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    private void notifyAuthKeyInput(final String key) {
3312c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        synchronized (mAuth) {
3322c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            mAuth.setSessionKey(key);
3332c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            mAuth.setChallenged(true);
3342c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            mAuth.notify();
3352c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        }
3362c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    }
3372c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
3382c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    private void notifyAuthCancelled() {
3392c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        synchronized (mAuth) {
3402c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            mAuth.setCancelled(true);
3412c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            mAuth.notify();
3422c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        }
3432c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    }
3442c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
3452c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    private final boolean initSocket() {
3462c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        try {
3472c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            // It is mandatory for PSE to support initiation of bonding and
3482c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            // encryption.
3492c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            mServerSocket = BluetoothServerSocket.listenUsingRfcommOn(PORT_NUM);
3502c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        } catch (IOException ex) {
3512c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            Log.e(TAG, "initSocket " + ex.toString());
3522c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            return false;
3532c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        }
3542c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        return true;
3552c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    }
3562c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
3572c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    private final void startObexServerSession() throws IOException {
3582c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        // acquire the wakeLock before start Obex transaction thread
3592c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        if (mWakeLock == null) {
3602c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            PowerManager pm = (PowerManager)getSystemService(Context.POWER_SERVICE);
3612c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
3622c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                    "StartingObexPbapTransaction");
3632c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            mWakeLock.setReferenceCounted(false);
3642c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            mWakeLock.acquire();
3652c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        }
3662c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        TelephonyManager tm = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
3672c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        if (tm != null) {
3682c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            sLocalPhoneNum = tm.getLine1Number();
3692c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            sLocalPhoneName = tm.getLine1AlphaTag();
3702c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        }
3712c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        mPbapServer = new BluetoothPbapObexServer(mSessionStatusHandler);
3722c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        mAuth = new BluetoothPbapAuthenticator(mSessionStatusHandler);
3732c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        synchronized (mAuth) {
3742c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            mAuth.setChallenged(false);
3752c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            mAuth.setCancelled(false);
3762c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        }
3772c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        BluetoothPbapRfcommTransport transport = new BluetoothPbapRfcommTransport(mConnSocket);
3782c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        mServerSession = new ServerSession(transport, mPbapServer, mAuth);
37937b69bd05e4b7a7d0e43575a6c22734b2d8c3f69Jackson Fan        setState(BluetoothPbap.STATE_CONNECTED);
3802c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    }
3812c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
3822c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    private final void closeSocket(boolean server, boolean accept) throws IOException {
3832c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        if (server == true) {
3842c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            if (mServerSocket != null) {
3852c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                mServerSocket.close();
3862c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            }
3872c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            mServerSocket = null;
3882c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        }
3892c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
3902c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        if (accept == true) {
3912c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            if (mConnSocket != null) {
3922c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                mConnSocket.close();
3932c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            }
3942c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            mConnSocket = null;
3952c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        }
3962c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    }
3972c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
3982c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    private final void closeService() {
3992c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        if (mAcceptThread != null) {
4002c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            try {
4012c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                mAcceptThread.shutdown();
4022c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                mAcceptThread.join();
4032c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                mAcceptThread = null;
4042c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            } catch (InterruptedException ex) {
4052c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                Log.w(TAG, "mAcceptThread close error" + ex);
4062c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            }
4072c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        }
4082c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        if (mServerSession != null) {
4092c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            mServerSession.close();
4102c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            mServerSession = null;
4112c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        }
4122c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        try {
4132c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            closeSocket(true, true);
4142c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        } catch (IOException ex) {
41587f9a72cc2d9544f65eab18893f7dc0de4f6ee31Jaikumar Ganesh            if (DBG) {
41687f9a72cc2d9544f65eab18893f7dc0de4f6ee31Jaikumar Ganesh                Log.e(TAG, "Caught the error: " + ex);
41787f9a72cc2d9544f65eab18893f7dc0de4f6ee31Jaikumar Ganesh            }
4182c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        }
4192c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        mHasStarted = false;
4202c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        BluetoothPbapReceiver.finishStartingService(BluetoothPbapService.this, mStartId);
4212c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    }
4222c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
4232c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    private void obexServerSessionClose() {
4242c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        // Release the wake lock if obex transaction is over
4252c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        if (mWakeLock != null) {
4262c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            mWakeLock.release();
4272c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            mWakeLock = null;
4282c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        }
4292c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        mServerSession = null;
4302c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        mAcceptThread = null;
4312c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        try {
4322c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            closeSocket(false, true);
4332c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        } catch (IOException e) {
43487f9a72cc2d9544f65eab18893f7dc0de4f6ee31Jaikumar Ganesh            if (DBG) {
43587f9a72cc2d9544f65eab18893f7dc0de4f6ee31Jaikumar Ganesh                Log.e(TAG, "Caught the error: " + e.toString());
43687f9a72cc2d9544f65eab18893f7dc0de4f6ee31Jaikumar Ganesh            }
4372c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        }
4382c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        // Last obex transaction is finished,we start to listen for incoming
4392c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        // connection again
4402c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        if (mBluetooth.isEnabled()) {
4412c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            startRfcommSocketListener();
4422c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        }
44337b69bd05e4b7a7d0e43575a6c22734b2d8c3f69Jackson Fan        setState(BluetoothPbap.STATE_DISCONNECTED);
4442c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    }
4452c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
4462c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    /**
4472c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan     * A thread that runs in the background waiting for remote rfcomm
4482c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan     * connect.Once a remote socket connected, this thread shall be
4492c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan     * shutdown.When the remote disconnect,this thread shall run again waiting
4502c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan     * for next request.
4512c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan     */
4522c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    private class SocketAcceptThread extends Thread {
4532c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
4542c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        private boolean stopped = false;
4552c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
4562c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        private boolean trust;
4572c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
4582c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        @Override
4592c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        public void run() {
4602c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            while (!stopped) {
4612c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                try {
4622c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                    mConnSocket = mServerSocket.accept(SOCKET_ACCEPT_TIMEOUT_VALUE);
4632c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                } catch (IOException ex) {
4642c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                    if (stopped) {
4652c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                        break;
4662c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                    }
4672c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                    if (DBG) {
4682c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                        Log.v(TAG, "Caught the error in socketAcceptThread: " + ex);
4692c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                    }
4702c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                }
4712c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                if (mConnSocket != null) {
4722c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                    mRemoteAddr = mConnSocket.getAddress();
4732c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                    if (mRemoteAddr != null) {
4742c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                        sRemoteDeviceName = mBluetooth.getRemoteName(mRemoteAddr);
4752c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                        // In case getRemoteName failed and return null
4762c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                        if (sRemoteDeviceName == null) {
4772c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                            sRemoteDeviceName = getString(R.string.defaultname);
4782c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                        }
4792c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                    }
4802c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                    // TODO: have dependency on device trust feature
4812c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                    // implementation
4822c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                    // trust = mBluetooth.getTrustState(mRemoteAddr);
4832c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                    if (trust) {
4842c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                        try {
4852c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                            startObexServerSession();
4862c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                        } catch (IOException ex) {
4872c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                            Log.e(TAG, "catch exception starting obex server session"
4882c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                                    + ex.toString());
4892c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                        }
4902c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                    } else {
4912c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                        BluetoothPbapReceiver.makeNewPbapNotification(getApplicationContext(),
4922c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                                ACCESS_REQUEST);
4932c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                        Log.i(TAG, "incomming connection accepted from" + sRemoteDeviceName);
4942c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                        mSessionStatusHandler.sendMessageDelayed(mSessionStatusHandler
4952c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                                .obtainMessage(USER_TIMEOUT), USER_CONFIRM_TIMEOUT_VALUE);
4962c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                    }
4972c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                    stopped = true; // job done ,close this thread;
4982c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                }
4992c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            }
5002c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        }
5012c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
5022c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        void shutdown() {
5032c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            stopped = true;
5042c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            interrupt();
5052c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        }
5062c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    }
5072c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
5082c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    private void startRfcommSocketListener() {
5092c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        if (mServerSocket == null) {
5102c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            if (!initSocket()) {
5112c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                closeService();
5122c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                return;
5132c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            }
5142c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        }
5152c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        if (mAcceptThread == null) {
5162c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            mAcceptThread = new SocketAcceptThread();
5172c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            mAcceptThread.setName("BluetoothPbapAcceptThread");
5182c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            mAcceptThread.start();
5192c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        }
5202c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    }
5212c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
5222c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    private void setState(int state) {
52337b69bd05e4b7a7d0e43575a6c22734b2d8c3f69Jackson Fan        setState(state, BluetoothHeadset.RESULT_SUCCESS);
5242c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    }
5252c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
52637b69bd05e4b7a7d0e43575a6c22734b2d8c3f69Jackson Fan    private synchronized void setState(int state, int result) {
52737b69bd05e4b7a7d0e43575a6c22734b2d8c3f69Jackson Fan        if (state != mState) {
52837b69bd05e4b7a7d0e43575a6c22734b2d8c3f69Jackson Fan            if (DBG)
52937b69bd05e4b7a7d0e43575a6c22734b2d8c3f69Jackson Fan                Log.d(TAG, "Pbap state " + mState + " -> " + state + ", result = " + result);
53037b69bd05e4b7a7d0e43575a6c22734b2d8c3f69Jackson Fan            Intent intent = new Intent(BluetoothPbap.PBAP_STATE_CHANGED_ACTION);
53137b69bd05e4b7a7d0e43575a6c22734b2d8c3f69Jackson Fan            intent.putExtra(BluetoothPbap.PBAP_PREVIOUS_STATE, mState);
53237b69bd05e4b7a7d0e43575a6c22734b2d8c3f69Jackson Fan            mState = state;
53337b69bd05e4b7a7d0e43575a6c22734b2d8c3f69Jackson Fan            intent.putExtra(BluetoothPbap.PBAP_STATE, mState);
53437b69bd05e4b7a7d0e43575a6c22734b2d8c3f69Jackson Fan            intent.putExtra(BluetoothIntent.ADDRESS, mRemoteAddr);
53537b69bd05e4b7a7d0e43575a6c22734b2d8c3f69Jackson Fan            sendBroadcast(intent, BLUETOOTH_PERM);
53637b69bd05e4b7a7d0e43575a6c22734b2d8c3f69Jackson Fan        }
53737b69bd05e4b7a7d0e43575a6c22734b2d8c3f69Jackson Fan    }
5382c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
5392c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    /**
5402c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan     * Handlers for incoming service calls
5412c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan     */
5422c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    private final IBluetoothPbap.Stub mBinder = new IBluetoothPbap.Stub() {
5432c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        private static final String TAG1 = "IBluetoothPbap.Stub";
5442c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
5452c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        public int getState() {
5462c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            if (DBG) {
5472c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                Log.d(TAG1, "getState " + mState);
5482c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            }
5492c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
5502c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            return mState;
5512c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        }
5522c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
5532c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        public String getPceAddress() {
5542c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            if (DBG) {
5552c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                Log.d(TAG1, "getPceAddress" + mRemoteAddr);
5562c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            }
5572c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
5582c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            if (mState == BluetoothPbap.STATE_DISCONNECTED) {
5592c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                return null;
5602c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            }
5612c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            return mRemoteAddr;
5622c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        }
5632c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
5642c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        public boolean isConnected(String address) {
5652c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
5662c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            return mState == BluetoothPbap.STATE_CONNECTED && mRemoteAddr.equals(address);
5672c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        }
5682c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
5692c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        public boolean connectPce(String address) {
5702c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH_ADMIN permission");
5712c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            return false;
5722c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        }
5732c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
5742c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        public void disconnectPce() {
5752c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            if (DBG) {
5762c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                Log.d(TAG1, "disconnectPce");
5772c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            }
5782c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH_ADMIN permission");
5792c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            synchronized (BluetoothPbapService.this) {
5802c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                switch (mState) {
5812c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                    case BluetoothPbap.STATE_CONNECTED:
5822c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                        if (mServerSession != null) {
5832c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                            mServerSession.close();
5842c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                            mServerSession = null;
5852c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                        }
5862c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                        try {
5872c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                            closeSocket(false, true);
5882c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                        } catch (IOException ex) {
5892c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                            Log.e(TAG1, "Caught the error: " + ex);
5902c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                        }
5912c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                        setState(BluetoothPbap.STATE_DISCONNECTED, BluetoothPbap.RESULT_CANCELED);
5922c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                        break;
5932c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                }
5942c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            }
5952c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        }
5962c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    };
59737b69bd05e4b7a7d0e43575a6c22734b2d8c3f69Jackson Fan
5982c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    private final Handler mSessionStatusHandler = new Handler() {
5992c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        @Override
6002c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        public void handleMessage(Message msg) {
6012c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            switch (msg.what) {
6022c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                case START_LISTENER:
6032c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                    if (mBluetooth.isEnabled()) {
6042c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                        startRfcommSocketListener();
6052c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                    } else {
6062c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                        closeService();// release all resources
6072c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                    }
6082c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                    break;
6092c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                case USER_TIMEOUT:
6102c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                    Intent intent = new Intent(USER_CONFIRM_TIMEOUT);
6112c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                    sendBroadcast(intent);
6122c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                    BluetoothPbapReceiver.removePbapNotification(getApplicationContext(),
6132c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                            BluetoothPbapReceiver.NOTIFICATION_ID_ACCESS);
6142c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                    obexServerSessionClose();
6152c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                    break;
6162c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                case AUTH_TIMEOUT:
6172c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                    Intent i = new Intent(USER_CONFIRM_TIMEOUT);
6182c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                    sendBroadcast(i);
6192c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                    BluetoothPbapReceiver.removePbapNotification(getApplicationContext(),
6202c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                            BluetoothPbapReceiver.NOTIFICATION_ID_AUTH);
6212c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                    notifyAuthCancelled();
6222c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                    break;
6232c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                case MSG_SERVERSESSION_CLOSE:
6242c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                    obexServerSessionClose();
6252c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                    mTmpTxt = getString(R.string.toast_disconnected, sRemoteDeviceName);
6262c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                    Toast.makeText(BluetoothPbapService.this, mTmpTxt, Toast.LENGTH_SHORT).show();
6272c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                    break;
6282c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                case MSG_SESSION_ESTABLISHED:
6292c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                    mTmpTxt = getString(R.string.toast_connected, sRemoteDeviceName);
6302c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                    Toast.makeText(BluetoothPbapService.this, mTmpTxt, Toast.LENGTH_SHORT).show();
6312c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                    break;
6322c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                case MSG_SESSION_DISCONNECTED:
6332c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                    // case MSG_SERVERSESSION_CLOSE will handle ,so just skip
6342c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                    break;
6352c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                case MSG_OBEX_AUTH_CHALL:
6362c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                    BluetoothPbapReceiver.makeNewPbapNotification(getApplicationContext(),
6372c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                            AUTH_CHALL);
6382c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                    mSessionStatusHandler.sendMessageDelayed(mSessionStatusHandler
6392c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                            .obtainMessage(AUTH_TIMEOUT), USER_CONFIRM_TIMEOUT_VALUE);
6402c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                    break;
6412c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            }
6422c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        }
6432c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    };
6442c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
6452c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan}
646