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 354446eaa935994bc91d6d308303e8d27526b4590dLixin Yueimport android.app.Notification; 364446eaa935994bc91d6d308303e8d27526b4590dLixin Yueimport android.app.NotificationManager; 374446eaa935994bc91d6d308303e8d27526b4590dLixin Yueimport android.app.PendingIntent; 382c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fanimport android.app.Service; 3941ef8d494511c040451f2f887cb31c3100746b61Nick Pellyimport android.bluetooth.BluetoothAdapter; 402c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fanimport android.bluetooth.BluetoothDevice; 4137b69bd05e4b7a7d0e43575a6c22734b2d8c3f69Jackson Fanimport android.bluetooth.BluetoothPbap; 4272d2952fcde46d8c2adc68718957c2fe9f5fa3b0Jaikumar Ganeshimport android.bluetooth.BluetoothProfile; 432c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fanimport android.bluetooth.BluetoothServerSocket; 4484ec2fa756c3e918b6083726271128096de57ffbJaikumar Ganeshimport android.bluetooth.BluetoothSocket; 4584ec2fa756c3e918b6083726271128096de57ffbJaikumar Ganeshimport android.bluetooth.IBluetooth; 4637b69bd05e4b7a7d0e43575a6c22734b2d8c3f69Jackson Fanimport android.bluetooth.IBluetoothPbap; 479f0d856f41d443ec23d5aa2eecfc561d7a3c01d1fredcimport android.bluetooth.BluetoothUuid; 4884ec2fa756c3e918b6083726271128096de57ffbJaikumar Ganeshimport android.content.Context; 4984ec2fa756c3e918b6083726271128096de57ffbJaikumar Ganeshimport android.content.Intent; 502c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fanimport android.os.Handler; 512c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fanimport android.os.IBinder; 522c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fanimport android.os.Message; 532c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fanimport android.os.PowerManager; 5484ec2fa756c3e918b6083726271128096de57ffbJaikumar Ganeshimport android.os.RemoteException; 5584ec2fa756c3e918b6083726271128096de57ffbJaikumar Ganeshimport android.os.ServiceManager; 562c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fanimport android.telephony.TelephonyManager; 572f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yueimport android.text.TextUtils; 582c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fanimport android.util.Log; 59bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde 60bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bondeimport com.android.bluetooth.BluetoothObexTransport; 6137510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xuimport com.android.bluetooth.Utils; 629f0d856f41d443ec23d5aa2eecfc561d7a3c01d1fredc 639f0d856f41d443ec23d5aa2eecfc561d7a3c01d1fredc 6484ec2fa756c3e918b6083726271128096de57ffbJaikumar Ganeshimport com.android.bluetooth.R; 65b5cc776c9353a203cdde97e62b25f05d9633d14cfredcimport com.android.bluetooth.btservice.AdapterService; 6684ec2fa756c3e918b6083726271128096de57ffbJaikumar Ganesh 672c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fanimport java.io.IOException; 682c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 692c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fanimport javax.obex.ServerSession; 702c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 712c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fanpublic class BluetoothPbapService extends Service { 722c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan private static final String TAG = "BluetoothPbapService"; 732c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 744446eaa935994bc91d6d308303e8d27526b4590dLixin Yue /** 752f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue * To enable PBAP DEBUG/VERBOSE logging - run below cmd in adb shell, and 762f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue * restart com.android.bluetooth process. only enable DEBUG log: 772f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue * "setprop log.tag.BluetoothPbapService DEBUG"; enable both VERBOSE and 782f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue * DEBUG log: "setprop log.tag.BluetoothPbapService VERBOSE" 794446eaa935994bc91d6d308303e8d27526b4590dLixin Yue */ 804446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 816654f5c903de510a70f9e72cd5ad7837b615d93ffredc public static final boolean DEBUG = true; 824446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 83fd1da115cbf09b7dd9bca3c7d3a4fb816a835dc5Matthew Xie public static final boolean VERBOSE = false; 842c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 852c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan /** 862c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan * Intent indicating incoming obex authentication request which is from 872c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan * PCE(Carkit) 882c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan */ 89d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue public static final String AUTH_CHALL_ACTION = "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 */ 95d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue public static final String AUTH_RESPONSE_ACTION = "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 */ 101d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue public static final String AUTH_CANCELLED_ACTION = "com.android.bluetooth.pbap.authcancelled"; 1022c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 1032c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan /** 104d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue * Intent indicating timeout for user confirmation, which is sent to 1052c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan * BluetoothPbapActivity 1062c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan */ 107d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue public static final String USER_CONFIRM_TIMEOUT_ACTION = 1084446eaa935994bc91d6d308303e8d27526b4590dLixin Yue "com.android.bluetooth.pbap.userconfirmtimeout"; 1092c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 1102c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan /** 1112c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan * Intent Extra name indicating session key which is sent from 1122c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan * BluetoothPbapActivity 1132c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan */ 114d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue public static final String EXTRA_SESSION_KEY = "com.android.bluetooth.pbap.sessionkey"; 1152c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 1162c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan public static final String THIS_PACKAGE_NAME = "com.android.bluetooth"; 1172c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 1182c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan public static final int MSG_SERVERSESSION_CLOSE = 5000; 1192c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 1202c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan public static final int MSG_SESSION_ESTABLISHED = 5001; 1212c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 1222c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan public static final int MSG_SESSION_DISCONNECTED = 5002; 1232c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 1242c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan public static final int MSG_OBEX_AUTH_CHALL = 5003; 1252c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 1268fa8d120e86c7488616cc7f7310843f15278b5d9Zhihai Xu public static final int MSG_ACQUIRE_WAKE_LOCK = 5004; 1278fa8d120e86c7488616cc7f7310843f15278b5d9Zhihai Xu 1288fa8d120e86c7488616cc7f7310843f15278b5d9Zhihai Xu public static final int MSG_RELEASE_WAKE_LOCK = 5005; 1298fa8d120e86c7488616cc7f7310843f15278b5d9Zhihai Xu 1302c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan private static final String BLUETOOTH_PERM = android.Manifest.permission.BLUETOOTH; 1312c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 1322c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan private static final String BLUETOOTH_ADMIN_PERM = android.Manifest.permission.BLUETOOTH_ADMIN; 1332c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 1342c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan private static final int START_LISTENER = 1; 1352c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 1362c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan private static final int USER_TIMEOUT = 2; 1372c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 1382c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan private static final int AUTH_TIMEOUT = 3; 1392c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 1404446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 1414446eaa935994bc91d6d308303e8d27526b4590dLixin Yue private static final int USER_CONFIRM_TIMEOUT_VALUE = 30000; 1424446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 1438fa8d120e86c7488616cc7f7310843f15278b5d9Zhihai Xu private static final int RELEASE_WAKE_LOCK_DELAY = 10000; 1444446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 1454446eaa935994bc91d6d308303e8d27526b4590dLixin Yue // Ensure not conflict with Opp notification ID 1464446eaa935994bc91d6d308303e8d27526b4590dLixin Yue private static final int NOTIFICATION_ID_ACCESS = -1000001; 1474446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 1484446eaa935994bc91d6d308303e8d27526b4590dLixin Yue private static final int NOTIFICATION_ID_AUTH = -1000002; 1494446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 1502c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan private PowerManager.WakeLock mWakeLock = null; 1512c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 15241ef8d494511c040451f2f887cb31c3100746b61Nick Pelly private BluetoothAdapter mAdapter; 1532c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 1542c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan private SocketAcceptThread mAcceptThread = null; 1552c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 1564446eaa935994bc91d6d308303e8d27526b4590dLixin Yue private BluetoothPbapAuthenticator mAuth = null; 1574446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 1582c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan private BluetoothPbapObexServer mPbapServer; 1592c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 1602c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan private ServerSession mServerSession = null; 1612c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 1622c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan private BluetoothServerSocket mServerSocket = null; 1632c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 1642c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan private BluetoothSocket mConnSocket = null; 1652c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 1664446eaa935994bc91d6d308303e8d27526b4590dLixin Yue private BluetoothDevice mRemoteDevice = null; 1672c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 1682c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan private static String sLocalPhoneNum = null; 1692c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 1702c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan private static String sLocalPhoneName = null; 1712c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 1722c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan private static String sRemoteDeviceName = null; 1732c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 1742c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan private boolean mHasStarted = false; 1752c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 1764446eaa935994bc91d6d308303e8d27526b4590dLixin Yue private volatile boolean mInterrupted; 1774446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 1782c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan private int mState; 1792c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 1802c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan private int mStartId = -1; 1812c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 182b5cc776c9353a203cdde97e62b25f05d9633d14cfredc //private IBluetooth mBluetoothService; 18384ec2fa756c3e918b6083726271128096de57ffbJaikumar Ganesh 184fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee private boolean mIsWaitingAuthorization = false; 1857eab97d6be9228b1c210bbb171c3e5e88e02f3d8Matthew Xie 1867eab97d6be9228b1c210bbb171c3e5e88e02f3d8Matthew Xie // package and class name to which we send intent to check phone book access permission 1877eab97d6be9228b1c210bbb171c3e5e88e02f3d8Matthew Xie private static final String ACCESS_AUTHORITY_PACKAGE = "com.android.settings"; 1887eab97d6be9228b1c210bbb171c3e5e88e02f3d8Matthew Xie private static final String ACCESS_AUTHORITY_CLASS = 1897eab97d6be9228b1c210bbb171c3e5e88e02f3d8Matthew Xie "com.android.settings.bluetooth.BluetoothPermissionRequest"; 1907eab97d6be9228b1c210bbb171c3e5e88e02f3d8Matthew Xie 1912c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan public BluetoothPbapService() { 19237b69bd05e4b7a7d0e43575a6c22734b2d8c3f69Jackson Fan mState = BluetoothPbap.STATE_DISCONNECTED; 1932c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 1942c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 1952c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan @Override 1962c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan public void onCreate() { 1972c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan super.onCreate(); 1984446eaa935994bc91d6d308303e8d27526b4590dLixin Yue if (VERBOSE) Log.v(TAG, "Pbap Service onCreate"); 1994446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 2004446eaa935994bc91d6d308303e8d27526b4590dLixin Yue mInterrupted = false; 2013a88b20fcd71e42451e402d27374b19eeb2ff0daNick Pelly mAdapter = BluetoothAdapter.getDefaultAdapter(); 2022f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue 2034446eaa935994bc91d6d308303e8d27526b4590dLixin Yue if (!mHasStarted) { 2042c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan mHasStarted = true; 2054446eaa935994bc91d6d308303e8d27526b4590dLixin Yue if (VERBOSE) Log.v(TAG, "Starting PBAP service"); 206c7a57f31515107366589bd6875c3cc4af1fc806efredc BluetoothPbapConfig.init(this); 207f4a286ee2aba5a75abe41881334bbdb5d0080105Nick Pelly int state = mAdapter.getState(); 208f4a286ee2aba5a75abe41881334bbdb5d0080105Nick Pelly if (state == BluetoothAdapter.STATE_ON) { 20977e6229d558b52c316fdba8dd29a6b26fb13fd28jhtop.kim mSessionStatusHandler.sendMessage(mSessionStatusHandler 21077e6229d558b52c316fdba8dd29a6b26fb13fd28jhtop.kim .obtainMessage(START_LISTENER)); 2112c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 2122c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 2132c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 2142c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 2152c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan @Override 2168222c7902a2281929fd31e840f6012038e6fa44aLixin Yue public int onStartCommand(Intent intent, int flags, int startId) { 21731ba132491053bc86d419a7d51fc04af3299c076fredc //int retCode = super.onStartCommand(intent, flags, startId); 21831ba132491053bc86d419a7d51fc04af3299c076fredc //if (retCode == START_STICKY) { 2198222c7902a2281929fd31e840f6012038e6fa44aLixin Yue mStartId = startId; 2208222c7902a2281929fd31e840f6012038e6fa44aLixin Yue if (mAdapter == null) { 2218222c7902a2281929fd31e840f6012038e6fa44aLixin Yue Log.w(TAG, "Stopping BluetoothPbapService: " 2228222c7902a2281929fd31e840f6012038e6fa44aLixin Yue + "device does not have BT or device is not ready"); 2238222c7902a2281929fd31e840f6012038e6fa44aLixin Yue // Release all resources 2248222c7902a2281929fd31e840f6012038e6fa44aLixin Yue closeService(); 2258222c7902a2281929fd31e840f6012038e6fa44aLixin Yue } else { 2268222c7902a2281929fd31e840f6012038e6fa44aLixin Yue // No need to handle the null intent case, because we have 2278222c7902a2281929fd31e840f6012038e6fa44aLixin Yue // all restart work done in onCreate() 2288222c7902a2281929fd31e840f6012038e6fa44aLixin Yue if (intent != null) { 2298222c7902a2281929fd31e840f6012038e6fa44aLixin Yue parseIntent(intent); 2308222c7902a2281929fd31e840f6012038e6fa44aLixin Yue } 2318222c7902a2281929fd31e840f6012038e6fa44aLixin Yue } 23231ba132491053bc86d419a7d51fc04af3299c076fredc //} 23331ba132491053bc86d419a7d51fc04af3299c076fredc return START_NOT_STICKY; 2342c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 2352c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 2362c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan // process the intent from receiver 2372c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan private void parseIntent(final Intent intent) { 2382f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue String action = intent.getStringExtra("action"); 239534bbd9a2347141644a684ce179b2cedf20541b4Pavlin Radoslavov if (action == null) return; // Nothing to do 2402f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue if (VERBOSE) Log.v(TAG, "action: " + action); 2412f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue 242613bae227d65f61903e196944a9c718b4394f25aNick Pelly int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR); 2436654f5c903de510a70f9e72cd5ad7837b615d93ffredc if (VERBOSE) Log.v(TAG, "state: " + state); 2446654f5c903de510a70f9e72cd5ad7837b615d93ffredc 2454446eaa935994bc91d6d308303e8d27526b4590dLixin Yue boolean removeTimeoutMsg = true; 246f4a286ee2aba5a75abe41881334bbdb5d0080105Nick Pelly if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) { 24715d36984a79d6e35c659edb0efdf929f0b526bd5Fred if (state == BluetoothAdapter.STATE_TURNING_OFF) { 2487d6a3299b58c5b53de4016a2e199974b94ae90dfMathias Jeppsson // Send any pending timeout now, as this service will be destroyed. 2497d6a3299b58c5b53de4016a2e199974b94ae90dfMathias Jeppsson if (mSessionStatusHandler.hasMessages(USER_TIMEOUT)) { 2507eab97d6be9228b1c210bbb171c3e5e88e02f3d8Matthew Xie Intent timeoutIntent = 2517eab97d6be9228b1c210bbb171c3e5e88e02f3d8Matthew Xie new Intent(BluetoothDevice.ACTION_CONNECTION_ACCESS_CANCEL); 2527eab97d6be9228b1c210bbb171c3e5e88e02f3d8Matthew Xie timeoutIntent.setClassName(ACCESS_AUTHORITY_PACKAGE, ACCESS_AUTHORITY_CLASS); 25370be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz timeoutIntent.putExtra(BluetoothDevice.EXTRA_ACCESS_REQUEST_TYPE, 25470be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz BluetoothDevice.REQUEST_TYPE_PHONEBOOK_ACCESS); 255dca6152362544ce9d430ca8f2ece7d5dc0f278d1Jaikumar Ganesh sendBroadcast(timeoutIntent, BLUETOOTH_ADMIN_PERM); 2567d6a3299b58c5b53de4016a2e199974b94ae90dfMathias Jeppsson } 2574446eaa935994bc91d6d308303e8d27526b4590dLixin Yue // Release all resources 2584446eaa935994bc91d6d308303e8d27526b4590dLixin Yue closeService(); 2597d6a3299b58c5b53de4016a2e199974b94ae90dfMathias Jeppsson } else { 2607d6a3299b58c5b53de4016a2e199974b94ae90dfMathias Jeppsson removeTimeoutMsg = false; 2612c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 262fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee } else if (action.equals(BluetoothDevice.ACTION_ACL_DISCONNECTED) 263fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee && mIsWaitingAuthorization) { 2644216387d9887926cebd652f8d3807d780642fc87Hemant Gupta BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); 2654216387d9887926cebd652f8d3807d780642fc87Hemant Gupta 2664216387d9887926cebd652f8d3807d780642fc87Hemant Gupta if (mRemoteDevice == null || device == null) { 2674216387d9887926cebd652f8d3807d780642fc87Hemant Gupta Log.e(TAG, "Unexpected error!"); 2684216387d9887926cebd652f8d3807d780642fc87Hemant Gupta return; 2694216387d9887926cebd652f8d3807d780642fc87Hemant Gupta } 2704216387d9887926cebd652f8d3807d780642fc87Hemant Gupta 2714216387d9887926cebd652f8d3807d780642fc87Hemant Gupta if (DEBUG) Log.d(TAG,"ACL disconnected for "+ device); 2724216387d9887926cebd652f8d3807d780642fc87Hemant Gupta 2734216387d9887926cebd652f8d3807d780642fc87Hemant Gupta if (mRemoteDevice.equals(device)) { 2744216387d9887926cebd652f8d3807d780642fc87Hemant Gupta Intent cancelIntent = new Intent(BluetoothDevice.ACTION_CONNECTION_ACCESS_CANCEL); 2754216387d9887926cebd652f8d3807d780642fc87Hemant Gupta cancelIntent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); 2764216387d9887926cebd652f8d3807d780642fc87Hemant Gupta cancelIntent.putExtra(BluetoothDevice.EXTRA_ACCESS_REQUEST_TYPE, 2774216387d9887926cebd652f8d3807d780642fc87Hemant Gupta BluetoothDevice.REQUEST_TYPE_PHONEBOOK_ACCESS); 2784216387d9887926cebd652f8d3807d780642fc87Hemant Gupta sendBroadcast(cancelIntent); 279fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee mIsWaitingAuthorization = false; 2804216387d9887926cebd652f8d3807d780642fc87Hemant Gupta stopObexServerSession(); 2814216387d9887926cebd652f8d3807d780642fc87Hemant Gupta } 2827eab97d6be9228b1c210bbb171c3e5e88e02f3d8Matthew Xie } else if (action.equals(BluetoothDevice.ACTION_CONNECTION_ACCESS_REPLY)) { 28370be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz int requestType = intent.getIntExtra(BluetoothDevice.EXTRA_ACCESS_REQUEST_TYPE, 28470be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz BluetoothDevice.REQUEST_TYPE_PHONEBOOK_ACCESS); 28570be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz 286fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee if ((!mIsWaitingAuthorization) 287fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee || (requestType != BluetoothDevice.REQUEST_TYPE_PHONEBOOK_ACCESS)) { 2887eab97d6be9228b1c210bbb171c3e5e88e02f3d8Matthew Xie // this reply is not for us 2897eab97d6be9228b1c210bbb171c3e5e88e02f3d8Matthew Xie return; 2902c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 2917eab97d6be9228b1c210bbb171c3e5e88e02f3d8Matthew Xie 292fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee mIsWaitingAuthorization = false; 2937eab97d6be9228b1c210bbb171c3e5e88e02f3d8Matthew Xie 2947eab97d6be9228b1c210bbb171c3e5e88e02f3d8Matthew Xie if (intent.getIntExtra(BluetoothDevice.EXTRA_CONNECTION_ACCESS_RESULT, 295fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee BluetoothDevice.CONNECTION_ACCESS_NO) 296fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee == BluetoothDevice.CONNECTION_ACCESS_YES) { 2977eab97d6be9228b1c210bbb171c3e5e88e02f3d8Matthew Xie if (intent.getBooleanExtra(BluetoothDevice.EXTRA_ALWAYS_ALLOWED, false)) { 298fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee boolean result = mRemoteDevice.setPhonebookAccessPermission( 299fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee BluetoothDevice.ACCESS_ALLOWED); 300fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee if (VERBOSE) { 301fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee Log.v(TAG, "setPhonebookAccessPermission(ACCESS_ALLOWED) result=" + result); 302fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee } 3032c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 3047eab97d6be9228b1c210bbb171c3e5e88e02f3d8Matthew Xie try { 3057eab97d6be9228b1c210bbb171c3e5e88e02f3d8Matthew Xie if (mConnSocket != null) { 3067eab97d6be9228b1c210bbb171c3e5e88e02f3d8Matthew Xie startObexServerSession(); 3077eab97d6be9228b1c210bbb171c3e5e88e02f3d8Matthew Xie } else { 3087eab97d6be9228b1c210bbb171c3e5e88e02f3d8Matthew Xie stopObexServerSession(); 3097eab97d6be9228b1c210bbb171c3e5e88e02f3d8Matthew Xie } 3107eab97d6be9228b1c210bbb171c3e5e88e02f3d8Matthew Xie } catch (IOException ex) { 3117eab97d6be9228b1c210bbb171c3e5e88e02f3d8Matthew Xie Log.e(TAG, "Caught the error: " + ex.toString()); 3127eab97d6be9228b1c210bbb171c3e5e88e02f3d8Matthew Xie } 3137eab97d6be9228b1c210bbb171c3e5e88e02f3d8Matthew Xie } else { 314fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee if (intent.getBooleanExtra(BluetoothDevice.EXTRA_ALWAYS_ALLOWED, false)) { 315fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee boolean result = mRemoteDevice.setPhonebookAccessPermission( 316fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee BluetoothDevice.ACCESS_REJECTED); 317fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee if (VERBOSE) { 318fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee Log.v(TAG, "setPhonebookAccessPermission(ACCESS_REJECTED) result=" 319fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee + result); 320fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee } 321fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee } 3227eab97d6be9228b1c210bbb171c3e5e88e02f3d8Matthew Xie stopObexServerSession(); 3232c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 324d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue } else if (action.equals(AUTH_RESPONSE_ACTION)) { 325d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue String sessionkey = intent.getStringExtra(EXTRA_SESSION_KEY); 3262c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan notifyAuthKeyInput(sessionkey); 327d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue } else if (action.equals(AUTH_CANCELLED_ACTION)) { 3282c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan notifyAuthCancelled(); 3294446eaa935994bc91d6d308303e8d27526b4590dLixin Yue } else { 3304446eaa935994bc91d6d308303e8d27526b4590dLixin Yue removeTimeoutMsg = false; 3314446eaa935994bc91d6d308303e8d27526b4590dLixin Yue } 3324446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 3334446eaa935994bc91d6d308303e8d27526b4590dLixin Yue if (removeTimeoutMsg) { 3344446eaa935994bc91d6d308303e8d27526b4590dLixin Yue mSessionStatusHandler.removeMessages(USER_TIMEOUT); 3352c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 3362c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 3372c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 3382c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan @Override 3392c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan public void onDestroy() { 3404446eaa935994bc91d6d308303e8d27526b4590dLixin Yue if (VERBOSE) Log.v(TAG, "Pbap Service onDestroy"); 3414446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 3422c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan super.onDestroy(); 34337b69bd05e4b7a7d0e43575a6c22734b2d8c3f69Jackson Fan setState(BluetoothPbap.STATE_DISCONNECTED, BluetoothPbap.RESULT_CANCELED); 3448222c7902a2281929fd31e840f6012038e6fa44aLixin Yue closeService(); 3453fafe61ef25c1899fdc817c52163aec16c31055cRavi Nagarajan if(mSessionStatusHandler != null) { 3463fafe61ef25c1899fdc817c52163aec16c31055cRavi Nagarajan mSessionStatusHandler.removeCallbacksAndMessages(null); 3473fafe61ef25c1899fdc817c52163aec16c31055cRavi Nagarajan } 3482c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 3492c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 3502c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan @Override 3512c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan public IBinder onBind(Intent intent) { 3524446eaa935994bc91d6d308303e8d27526b4590dLixin Yue if (VERBOSE) Log.v(TAG, "Pbap Service onBind"); 35337b69bd05e4b7a7d0e43575a6c22734b2d8c3f69Jackson Fan return mBinder; 3542c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 3552c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 3564446eaa935994bc91d6d308303e8d27526b4590dLixin Yue private void startRfcommSocketListener() { 3574446eaa935994bc91d6d308303e8d27526b4590dLixin Yue if (VERBOSE) Log.v(TAG, "Pbap Service startRfcommSocketListener"); 3582c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 3594446eaa935994bc91d6d308303e8d27526b4590dLixin Yue if (mAcceptThread == null) { 3604446eaa935994bc91d6d308303e8d27526b4590dLixin Yue mAcceptThread = new SocketAcceptThread(); 3614446eaa935994bc91d6d308303e8d27526b4590dLixin Yue mAcceptThread.setName("BluetoothPbapAcceptThread"); 3624446eaa935994bc91d6d308303e8d27526b4590dLixin Yue mAcceptThread.start(); 3632c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 3642c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 3652c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 3664446eaa935994bc91d6d308303e8d27526b4590dLixin Yue private final boolean initSocket() { 3674446eaa935994bc91d6d308303e8d27526b4590dLixin Yue if (VERBOSE) Log.v(TAG, "Pbap Service initSocket"); 3682c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 3697b91a410d595b879548e540889f8b30a0d6476c4Zhihai Xu boolean initSocketOK = false; 3704446eaa935994bc91d6d308303e8d27526b4590dLixin Yue final int CREATE_RETRY_TIME = 10; 3712c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 3724446eaa935994bc91d6d308303e8d27526b4590dLixin Yue // It's possible that create will fail in some cases. retry for 10 times 3734446eaa935994bc91d6d308303e8d27526b4590dLixin Yue for (int i = 0; i < CREATE_RETRY_TIME && !mInterrupted; i++) { 3747b91a410d595b879548e540889f8b30a0d6476c4Zhihai Xu initSocketOK = true; 3754446eaa935994bc91d6d308303e8d27526b4590dLixin Yue try { 3764446eaa935994bc91d6d308303e8d27526b4590dLixin Yue // It is mandatory for PSE to support initiation of bonding and 3774446eaa935994bc91d6d308303e8d27526b4590dLixin Yue // encryption. 3786458cffaca286611e898c75ad86e2d98c89008b6Matthew Xie mServerSocket = mAdapter.listenUsingEncryptedRfcommWithServiceRecord 3796458cffaca286611e898c75ad86e2d98c89008b6Matthew Xie ("OBEX Phonebook Access Server", BluetoothUuid.PBAP_PSE.getUuid()); 380e479e18951a375a548e617e86e3b1b7d121351a1Fred 3814446eaa935994bc91d6d308303e8d27526b4590dLixin Yue } catch (IOException e) { 3824446eaa935994bc91d6d308303e8d27526b4590dLixin Yue Log.e(TAG, "Error create RfcommServerSocket " + e.toString()); 3834446eaa935994bc91d6d308303e8d27526b4590dLixin Yue initSocketOK = false; 3844446eaa935994bc91d6d308303e8d27526b4590dLixin Yue } 3854446eaa935994bc91d6d308303e8d27526b4590dLixin Yue if (!initSocketOK) { 38637e1e995fdfd6aecd53f1fd1f8f0928021472db1Kausik Sinnaswamy // Need to break out of this loop if BT is being turned off. 38737e1e995fdfd6aecd53f1fd1f8f0928021472db1Kausik Sinnaswamy if (mAdapter == null) break; 38837e1e995fdfd6aecd53f1fd1f8f0928021472db1Kausik Sinnaswamy int state = mAdapter.getState(); 38937e1e995fdfd6aecd53f1fd1f8f0928021472db1Kausik Sinnaswamy if ((state != BluetoothAdapter.STATE_TURNING_ON) && 39037e1e995fdfd6aecd53f1fd1f8f0928021472db1Kausik Sinnaswamy (state != BluetoothAdapter.STATE_ON)) { 39137e1e995fdfd6aecd53f1fd1f8f0928021472db1Kausik Sinnaswamy Log.w(TAG, "initServerSocket failed as BT is (being) turned off"); 39237e1e995fdfd6aecd53f1fd1f8f0928021472db1Kausik Sinnaswamy break; 39337e1e995fdfd6aecd53f1fd1f8f0928021472db1Kausik Sinnaswamy } 3947b91a410d595b879548e540889f8b30a0d6476c4Zhihai Xu try { 3957b91a410d595b879548e540889f8b30a0d6476c4Zhihai Xu if (VERBOSE) Log.v(TAG, "wait 300 ms"); 3967b91a410d595b879548e540889f8b30a0d6476c4Zhihai Xu Thread.sleep(300); 3977b91a410d595b879548e540889f8b30a0d6476c4Zhihai Xu } catch (InterruptedException e) { 3987b91a410d595b879548e540889f8b30a0d6476c4Zhihai Xu Log.e(TAG, "socketAcceptThread thread was interrupted (3)"); 3997b91a410d595b879548e540889f8b30a0d6476c4Zhihai Xu break; 4004446eaa935994bc91d6d308303e8d27526b4590dLixin Yue } 4014446eaa935994bc91d6d308303e8d27526b4590dLixin Yue } else { 4024446eaa935994bc91d6d308303e8d27526b4590dLixin Yue break; 4034446eaa935994bc91d6d308303e8d27526b4590dLixin Yue } 4044446eaa935994bc91d6d308303e8d27526b4590dLixin Yue } 4052c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 4067b91a410d595b879548e540889f8b30a0d6476c4Zhihai Xu if (mInterrupted) { 4077b91a410d595b879548e540889f8b30a0d6476c4Zhihai Xu initSocketOK = false; 4087b91a410d595b879548e540889f8b30a0d6476c4Zhihai Xu // close server socket to avoid resource leakage 4097b91a410d595b879548e540889f8b30a0d6476c4Zhihai Xu closeServerSocket(); 4107b91a410d595b879548e540889f8b30a0d6476c4Zhihai Xu } 4117b91a410d595b879548e540889f8b30a0d6476c4Zhihai Xu 4124446eaa935994bc91d6d308303e8d27526b4590dLixin Yue if (initSocketOK) { 4139f0d856f41d443ec23d5aa2eecfc561d7a3c01d1fredc if (VERBOSE) Log.v(TAG, "Succeed to create listening socket "); 4142c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 4154446eaa935994bc91d6d308303e8d27526b4590dLixin Yue } else { 4164446eaa935994bc91d6d308303e8d27526b4590dLixin Yue Log.e(TAG, "Error to create listening socket after " + CREATE_RETRY_TIME + " try"); 4174446eaa935994bc91d6d308303e8d27526b4590dLixin Yue } 4184446eaa935994bc91d6d308303e8d27526b4590dLixin Yue return initSocketOK; 4192c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 4202c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 4217b91a410d595b879548e540889f8b30a0d6476c4Zhihai Xu private final synchronized void closeServerSocket() { 4227b91a410d595b879548e540889f8b30a0d6476c4Zhihai Xu // exit SocketAcceptThread early 4237b91a410d595b879548e540889f8b30a0d6476c4Zhihai Xu if (mServerSocket != null) { 4247b91a410d595b879548e540889f8b30a0d6476c4Zhihai Xu try { 4257b91a410d595b879548e540889f8b30a0d6476c4Zhihai Xu // this will cause mServerSocket.accept() return early with IOException 4264446eaa935994bc91d6d308303e8d27526b4590dLixin Yue mServerSocket.close(); 427ebdb4d92c0ea0b5e40afe0feec71105695d27a4czzy mServerSocket = null; 4287b91a410d595b879548e540889f8b30a0d6476c4Zhihai Xu } catch (IOException ex) { 4297b91a410d595b879548e540889f8b30a0d6476c4Zhihai Xu Log.e(TAG, "Close Server Socket error: " + ex); 4304446eaa935994bc91d6d308303e8d27526b4590dLixin Yue } 4312c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 4327b91a410d595b879548e540889f8b30a0d6476c4Zhihai Xu } 4332c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 4347b91a410d595b879548e540889f8b30a0d6476c4Zhihai Xu private final synchronized void closeConnectionSocket() { 4357b91a410d595b879548e540889f8b30a0d6476c4Zhihai Xu if (mConnSocket != null) { 4367b91a410d595b879548e540889f8b30a0d6476c4Zhihai Xu try { 4374446eaa935994bc91d6d308303e8d27526b4590dLixin Yue mConnSocket.close(); 438ebdb4d92c0ea0b5e40afe0feec71105695d27a4czzy mConnSocket = null; 4397b91a410d595b879548e540889f8b30a0d6476c4Zhihai Xu } catch (IOException e) { 4407b91a410d595b879548e540889f8b30a0d6476c4Zhihai Xu Log.e(TAG, "Close Connection Socket error: " + e.toString()); 4414446eaa935994bc91d6d308303e8d27526b4590dLixin Yue } 4422c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 4432c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 4442c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 4454446eaa935994bc91d6d308303e8d27526b4590dLixin Yue private final void closeService() { 446ebdb4d92c0ea0b5e40afe0feec71105695d27a4czzy if (VERBOSE) Log.v(TAG, "Pbap Service closeService in"); 4474446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 4487b91a410d595b879548e540889f8b30a0d6476c4Zhihai Xu // exit initSocket early 4497b91a410d595b879548e540889f8b30a0d6476c4Zhihai Xu mInterrupted = true; 4507b91a410d595b879548e540889f8b30a0d6476c4Zhihai Xu closeServerSocket(); 4510eb2230d3b7c184a00599e8ab70331c599e9ef1cJaikumar Ganesh 4524446eaa935994bc91d6d308303e8d27526b4590dLixin Yue if (mAcceptThread != null) { 4534446eaa935994bc91d6d308303e8d27526b4590dLixin Yue try { 4544446eaa935994bc91d6d308303e8d27526b4590dLixin Yue mAcceptThread.shutdown(); 4554446eaa935994bc91d6d308303e8d27526b4590dLixin Yue mAcceptThread.join(); 4564446eaa935994bc91d6d308303e8d27526b4590dLixin Yue mAcceptThread = null; 4574446eaa935994bc91d6d308303e8d27526b4590dLixin Yue } catch (InterruptedException ex) { 4584446eaa935994bc91d6d308303e8d27526b4590dLixin Yue Log.w(TAG, "mAcceptThread close error" + ex); 4594446eaa935994bc91d6d308303e8d27526b4590dLixin Yue } 4604446eaa935994bc91d6d308303e8d27526b4590dLixin Yue } 4617b91a410d595b879548e540889f8b30a0d6476c4Zhihai Xu 4627b91a410d595b879548e540889f8b30a0d6476c4Zhihai Xu if (mWakeLock != null) { 4637b91a410d595b879548e540889f8b30a0d6476c4Zhihai Xu mWakeLock.release(); 4647b91a410d595b879548e540889f8b30a0d6476c4Zhihai Xu mWakeLock = null; 4657b91a410d595b879548e540889f8b30a0d6476c4Zhihai Xu } 4667b91a410d595b879548e540889f8b30a0d6476c4Zhihai Xu 4674446eaa935994bc91d6d308303e8d27526b4590dLixin Yue if (mServerSession != null) { 4684446eaa935994bc91d6d308303e8d27526b4590dLixin Yue mServerSession.close(); 4694446eaa935994bc91d6d308303e8d27526b4590dLixin Yue mServerSession = null; 4704446eaa935994bc91d6d308303e8d27526b4590dLixin Yue } 4714446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 4727b91a410d595b879548e540889f8b30a0d6476c4Zhihai Xu closeConnectionSocket(); 4737b91a410d595b879548e540889f8b30a0d6476c4Zhihai Xu 4744446eaa935994bc91d6d308303e8d27526b4590dLixin Yue mHasStarted = false; 475ebdb4d92c0ea0b5e40afe0feec71105695d27a4czzy if (mStartId != -1 && stopSelfResult(mStartId)) { 4764446eaa935994bc91d6d308303e8d27526b4590dLixin Yue if (VERBOSE) Log.v(TAG, "successfully stopped pbap service"); 477ebdb4d92c0ea0b5e40afe0feec71105695d27a4czzy mStartId = -1; 4782c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 479ebdb4d92c0ea0b5e40afe0feec71105695d27a4czzy if (VERBOSE) Log.v(TAG, "Pbap Service closeService out"); 4802c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 4812c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 4822c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan private final void startObexServerSession() throws IOException { 4834446eaa935994bc91d6d308303e8d27526b4590dLixin Yue if (VERBOSE) Log.v(TAG, "Pbap Service startObexServerSession"); 4844446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 4852c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan // acquire the wakeLock before start Obex transaction thread 4862c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan if (mWakeLock == null) { 4872c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan PowerManager pm = (PowerManager)getSystemService(Context.POWER_SERVICE); 4882c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, 4892c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan "StartingObexPbapTransaction"); 4902c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan mWakeLock.setReferenceCounted(false); 4912c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan mWakeLock.acquire(); 4922c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 4932c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan TelephonyManager tm = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE); 4942c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan if (tm != null) { 4952c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan sLocalPhoneNum = tm.getLine1Number(); 4962c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan sLocalPhoneName = tm.getLine1AlphaTag(); 4972f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue if (TextUtils.isEmpty(sLocalPhoneName)) { 498cd5ed0c7d04119e508fbddfd9656ef8559e3e524Lixin Yue sLocalPhoneName = this.getString(R.string.localPhoneName); 4992f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } 5002c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 5012f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue 5022f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue mPbapServer = new BluetoothPbapObexServer(mSessionStatusHandler, this); 5034446eaa935994bc91d6d308303e8d27526b4590dLixin Yue synchronized (this) { 5044446eaa935994bc91d6d308303e8d27526b4590dLixin Yue mAuth = new BluetoothPbapAuthenticator(mSessionStatusHandler); 5052c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan mAuth.setChallenged(false); 5062c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan mAuth.setCancelled(false); 5072c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 508bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde BluetoothObexTransport transport = new BluetoothObexTransport(mConnSocket); 5092c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan mServerSession = new ServerSession(transport, mPbapServer, mAuth); 51037b69bd05e4b7a7d0e43575a6c22734b2d8c3f69Jackson Fan setState(BluetoothPbap.STATE_CONNECTED); 5118fa8d120e86c7488616cc7f7310843f15278b5d9Zhihai Xu 5128fa8d120e86c7488616cc7f7310843f15278b5d9Zhihai Xu mSessionStatusHandler.removeMessages(MSG_RELEASE_WAKE_LOCK); 5138fa8d120e86c7488616cc7f7310843f15278b5d9Zhihai Xu mSessionStatusHandler.sendMessageDelayed(mSessionStatusHandler 5148fa8d120e86c7488616cc7f7310843f15278b5d9Zhihai Xu .obtainMessage(MSG_RELEASE_WAKE_LOCK), RELEASE_WAKE_LOCK_DELAY); 5158fa8d120e86c7488616cc7f7310843f15278b5d9Zhihai Xu 5164446eaa935994bc91d6d308303e8d27526b4590dLixin Yue if (VERBOSE) { 517acab258c177d82338b1696360cd0b8c9821b0f03Lixin Yue Log.v(TAG, "startObexServerSession() success!"); 518acab258c177d82338b1696360cd0b8c9821b0f03Lixin Yue } 5192c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 5202c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 5214446eaa935994bc91d6d308303e8d27526b4590dLixin Yue private void stopObexServerSession() { 5224446eaa935994bc91d6d308303e8d27526b4590dLixin Yue if (VERBOSE) Log.v(TAG, "Pbap Service stopObexServerSession"); 5232c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 5248fa8d120e86c7488616cc7f7310843f15278b5d9Zhihai Xu mSessionStatusHandler.removeMessages(MSG_ACQUIRE_WAKE_LOCK); 5258fa8d120e86c7488616cc7f7310843f15278b5d9Zhihai Xu mSessionStatusHandler.removeMessages(MSG_RELEASE_WAKE_LOCK); 5264446eaa935994bc91d6d308303e8d27526b4590dLixin Yue // Release the wake lock if obex transaction is over 5274446eaa935994bc91d6d308303e8d27526b4590dLixin Yue if (mWakeLock != null) { 5284446eaa935994bc91d6d308303e8d27526b4590dLixin Yue mWakeLock.release(); 5294446eaa935994bc91d6d308303e8d27526b4590dLixin Yue mWakeLock = null; 5302c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 5312c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 5322c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan if (mServerSession != null) { 5332c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan mServerSession.close(); 5342c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan mServerSession = null; 5352c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 5362c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 5372c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan mAcceptThread = null; 5384446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 5397b91a410d595b879548e540889f8b30a0d6476c4Zhihai Xu closeConnectionSocket(); 5407b91a410d595b879548e540889f8b30a0d6476c4Zhihai Xu 5414446eaa935994bc91d6d308303e8d27526b4590dLixin Yue // Last obex transaction is finished, we start to listen for incoming 5422c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan // connection again 54341ef8d494511c040451f2f887cb31c3100746b61Nick Pelly if (mAdapter.isEnabled()) { 5449f0d856f41d443ec23d5aa2eecfc561d7a3c01d1fredc startRfcommSocketListener(); 5452c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 54637b69bd05e4b7a7d0e43575a6c22734b2d8c3f69Jackson Fan setState(BluetoothPbap.STATE_DISCONNECTED); 5472c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 5482c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 5494446eaa935994bc91d6d308303e8d27526b4590dLixin Yue private void notifyAuthKeyInput(final String key) { 5502f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue synchronized (mAuth) { 5512f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue if (key != null) { 5522f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue mAuth.setSessionKey(key); 5532f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } 5544446eaa935994bc91d6d308303e8d27526b4590dLixin Yue mAuth.setChallenged(true); 5554446eaa935994bc91d6d308303e8d27526b4590dLixin Yue mAuth.notify(); 5564446eaa935994bc91d6d308303e8d27526b4590dLixin Yue } 5574446eaa935994bc91d6d308303e8d27526b4590dLixin Yue } 5584446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 5594446eaa935994bc91d6d308303e8d27526b4590dLixin Yue private void notifyAuthCancelled() { 5602f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue synchronized (mAuth) { 5614446eaa935994bc91d6d308303e8d27526b4590dLixin Yue mAuth.setCancelled(true); 5624446eaa935994bc91d6d308303e8d27526b4590dLixin Yue mAuth.notify(); 5634446eaa935994bc91d6d308303e8d27526b4590dLixin Yue } 5644446eaa935994bc91d6d308303e8d27526b4590dLixin Yue } 5654446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 5662c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan /** 5672c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan * A thread that runs in the background waiting for remote rfcomm 5682c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan * connect.Once a remote socket connected, this thread shall be 5692c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan * shutdown.When the remote disconnect,this thread shall run again waiting 5702c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan * for next request. 5712c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan */ 5722c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan private class SocketAcceptThread extends Thread { 5732c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 5742c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan private boolean stopped = false; 5752c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 5762c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan @Override 5772c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan public void run() { 5787b91a410d595b879548e540889f8b30a0d6476c4Zhihai Xu BluetoothServerSocket serverSocket; 5796458cffaca286611e898c75ad86e2d98c89008b6Matthew Xie if (mServerSocket == null) { 5806458cffaca286611e898c75ad86e2d98c89008b6Matthew Xie if (!initSocket()) { 5816458cffaca286611e898c75ad86e2d98c89008b6Matthew Xie return; 5826458cffaca286611e898c75ad86e2d98c89008b6Matthew Xie } 5836458cffaca286611e898c75ad86e2d98c89008b6Matthew Xie } 5846458cffaca286611e898c75ad86e2d98c89008b6Matthew Xie 5852c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan while (!stopped) { 5862c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan try { 5879f0d856f41d443ec23d5aa2eecfc561d7a3c01d1fredc if (VERBOSE) Log.v(TAG, "Accepting socket connection..."); 5887b91a410d595b879548e540889f8b30a0d6476c4Zhihai Xu serverSocket = mServerSocket; 5897b91a410d595b879548e540889f8b30a0d6476c4Zhihai Xu if (serverSocket == null) { 5907b91a410d595b879548e540889f8b30a0d6476c4Zhihai Xu Log.w(TAG, "mServerSocket is null"); 5917b91a410d595b879548e540889f8b30a0d6476c4Zhihai Xu break; 5927b91a410d595b879548e540889f8b30a0d6476c4Zhihai Xu } 5937b91a410d595b879548e540889f8b30a0d6476c4Zhihai Xu mConnSocket = serverSocket.accept(); 5949f0d856f41d443ec23d5aa2eecfc561d7a3c01d1fredc if (VERBOSE) Log.v(TAG, "Accepted socket connection..."); 5954446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 5967b91a410d595b879548e540889f8b30a0d6476c4Zhihai Xu synchronized (BluetoothPbapService.this) { 5977b91a410d595b879548e540889f8b30a0d6476c4Zhihai Xu if (mConnSocket == null) { 5987b91a410d595b879548e540889f8b30a0d6476c4Zhihai Xu Log.w(TAG, "mConnSocket is null"); 5997b91a410d595b879548e540889f8b30a0d6476c4Zhihai Xu break; 6007b91a410d595b879548e540889f8b30a0d6476c4Zhihai Xu } 6017b91a410d595b879548e540889f8b30a0d6476c4Zhihai Xu mRemoteDevice = mConnSocket.getRemoteDevice(); 6027b91a410d595b879548e540889f8b30a0d6476c4Zhihai Xu } 6038222c7902a2281929fd31e840f6012038e6fa44aLixin Yue if (mRemoteDevice == null) { 6048222c7902a2281929fd31e840f6012038e6fa44aLixin Yue Log.i(TAG, "getRemoteDevice() = null"); 6058222c7902a2281929fd31e840f6012038e6fa44aLixin Yue break; 6068222c7902a2281929fd31e840f6012038e6fa44aLixin Yue } 6078222c7902a2281929fd31e840f6012038e6fa44aLixin Yue sRemoteDeviceName = mRemoteDevice.getName(); 6088222c7902a2281929fd31e840f6012038e6fa44aLixin Yue // In case getRemoteName failed and return null 6098222c7902a2281929fd31e840f6012038e6fa44aLixin Yue if (TextUtils.isEmpty(sRemoteDeviceName)) { 6108222c7902a2281929fd31e840f6012038e6fa44aLixin Yue sRemoteDeviceName = getString(R.string.defaultname); 6112c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 612fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee int permission = mRemoteDevice.getPhonebookAccessPermission(); 613fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee if (VERBOSE) Log.v(TAG, "getPhonebookAccessPermission() = " + permission); 614c5495c585c0d19cdd20963e5a2144e5f984a306eLixin Yue 615fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee if (permission == BluetoothDevice.ACCESS_ALLOWED) { 6162c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan try { 617fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee if (VERBOSE) { 618fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee Log.v(TAG, "incoming connection accepted from: " + sRemoteDeviceName 619fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee + " automatically as already allowed device"); 620fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee } 6212c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan startObexServerSession(); 6222c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } catch (IOException ex) { 623fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee Log.e(TAG, "Caught exception starting obex server session" 6242c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan + ex.toString()); 6252c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 626fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee } else if (permission == BluetoothDevice.ACCESS_REJECTED) { 627fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee if (VERBOSE) { 628fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee Log.v(TAG, "incoming connection rejected from: " + sRemoteDeviceName 629fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee + " automatically as already rejected device"); 630fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee } 631fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee stopObexServerSession(); 632fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee } else { // permission == BluetoothDevice.ACCESS_UNKNOWN 633fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee // Send an Intent to Settings app to ask user preference. 634fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee Intent intent = 635fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee new Intent(BluetoothDevice.ACTION_CONNECTION_ACCESS_REQUEST); 6367eab97d6be9228b1c210bbb171c3e5e88e02f3d8Matthew Xie intent.setClassName(ACCESS_AUTHORITY_PACKAGE, ACCESS_AUTHORITY_CLASS); 6377eab97d6be9228b1c210bbb171c3e5e88e02f3d8Matthew Xie intent.putExtra(BluetoothDevice.EXTRA_ACCESS_REQUEST_TYPE, 6387eab97d6be9228b1c210bbb171c3e5e88e02f3d8Matthew Xie BluetoothDevice.REQUEST_TYPE_PHONEBOOK_ACCESS); 6397eab97d6be9228b1c210bbb171c3e5e88e02f3d8Matthew Xie intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mRemoteDevice); 6407eab97d6be9228b1c210bbb171c3e5e88e02f3d8Matthew Xie intent.putExtra(BluetoothDevice.EXTRA_PACKAGE_NAME, getPackageName()); 6417eab97d6be9228b1c210bbb171c3e5e88e02f3d8Matthew Xie intent.putExtra(BluetoothDevice.EXTRA_CLASS_NAME, 6427eab97d6be9228b1c210bbb171c3e5e88e02f3d8Matthew Xie BluetoothPbapReceiver.class.getName()); 64398df3e8ff33a6137d4ea13845b583aaee2670613Casper Bonde 644fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee mIsWaitingAuthorization = true; 645beb0497605ef61062d0565d85897f4c842845a8fAng Li sendOrderedBroadcast(intent, BLUETOOTH_ADMIN_PERM); 6467eab97d6be9228b1c210bbb171c3e5e88e02f3d8Matthew Xie 6477eab97d6be9228b1c210bbb171c3e5e88e02f3d8Matthew Xie if (VERBOSE) Log.v(TAG, "waiting for authorization for connection from: " 6484446eaa935994bc91d6d308303e8d27526b4590dLixin Yue + sRemoteDeviceName); 6494446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 6504446eaa935994bc91d6d308303e8d27526b4590dLixin Yue // In case car kit time out and try to use HFP for 6514446eaa935994bc91d6d308303e8d27526b4590dLixin Yue // phonebook 6524446eaa935994bc91d6d308303e8d27526b4590dLixin Yue // access, while UI still there waiting for user to 6534446eaa935994bc91d6d308303e8d27526b4590dLixin Yue // confirm 6542c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan mSessionStatusHandler.sendMessageDelayed(mSessionStatusHandler 6552c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan .obtainMessage(USER_TIMEOUT), USER_CONFIRM_TIMEOUT_VALUE); 656fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee // We will continue the process when we receive 657fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee // BluetoothDevice.ACTION_CONNECTION_ACCESS_REPLY from Settings app. 6582c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 6592c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan stopped = true; // job done ,close this thread; 6604446eaa935994bc91d6d308303e8d27526b4590dLixin Yue } catch (IOException ex) { 6616654f5c903de510a70f9e72cd5ad7837b615d93ffredc stopped=true; 6626654f5c903de510a70f9e72cd5ad7837b615d93ffredc /* 6634446eaa935994bc91d6d308303e8d27526b4590dLixin Yue if (stopped) { 6644446eaa935994bc91d6d308303e8d27526b4590dLixin Yue break; 6654446eaa935994bc91d6d308303e8d27526b4590dLixin Yue } 6666654f5c903de510a70f9e72cd5ad7837b615d93ffredc */ 6674446eaa935994bc91d6d308303e8d27526b4590dLixin Yue if (VERBOSE) Log.v(TAG, "Accept exception: " + ex.toString()); 6682c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 6692c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 6702c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 6712c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 6722c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan void shutdown() { 6732c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan stopped = true; 6742c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan interrupt(); 6752c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 6762c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 6772c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 6784446eaa935994bc91d6d308303e8d27526b4590dLixin Yue private final Handler mSessionStatusHandler = new Handler() { 6794446eaa935994bc91d6d308303e8d27526b4590dLixin Yue @Override 6804446eaa935994bc91d6d308303e8d27526b4590dLixin Yue public void handleMessage(Message msg) { 6814446eaa935994bc91d6d308303e8d27526b4590dLixin Yue if (VERBOSE) Log.v(TAG, "Handler(): got msg=" + msg.what); 6824446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 6834446eaa935994bc91d6d308303e8d27526b4590dLixin Yue switch (msg.what) { 6844446eaa935994bc91d6d308303e8d27526b4590dLixin Yue case START_LISTENER: 6854446eaa935994bc91d6d308303e8d27526b4590dLixin Yue if (mAdapter.isEnabled()) { 6869f0d856f41d443ec23d5aa2eecfc561d7a3c01d1fredc startRfcommSocketListener(); 6874446eaa935994bc91d6d308303e8d27526b4590dLixin Yue } else { 6884446eaa935994bc91d6d308303e8d27526b4590dLixin Yue closeService();// release all resources 6894446eaa935994bc91d6d308303e8d27526b4590dLixin Yue } 6904446eaa935994bc91d6d308303e8d27526b4590dLixin Yue break; 6914446eaa935994bc91d6d308303e8d27526b4590dLixin Yue case USER_TIMEOUT: 6927eab97d6be9228b1c210bbb171c3e5e88e02f3d8Matthew Xie Intent intent = new Intent(BluetoothDevice.ACTION_CONNECTION_ACCESS_CANCEL); 6934216387d9887926cebd652f8d3807d780642fc87Hemant Gupta intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mRemoteDevice); 69470be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz intent.putExtra(BluetoothDevice.EXTRA_ACCESS_REQUEST_TYPE, 69570be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz BluetoothDevice.REQUEST_TYPE_PHONEBOOK_ACCESS); 6964446eaa935994bc91d6d308303e8d27526b4590dLixin Yue sendBroadcast(intent); 697fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee mIsWaitingAuthorization = false; 6984446eaa935994bc91d6d308303e8d27526b4590dLixin Yue stopObexServerSession(); 6994446eaa935994bc91d6d308303e8d27526b4590dLixin Yue break; 7004446eaa935994bc91d6d308303e8d27526b4590dLixin Yue case AUTH_TIMEOUT: 7014446eaa935994bc91d6d308303e8d27526b4590dLixin Yue Intent i = new Intent(USER_CONFIRM_TIMEOUT_ACTION); 7024446eaa935994bc91d6d308303e8d27526b4590dLixin Yue sendBroadcast(i); 7034446eaa935994bc91d6d308303e8d27526b4590dLixin Yue removePbapNotification(NOTIFICATION_ID_AUTH); 7044446eaa935994bc91d6d308303e8d27526b4590dLixin Yue notifyAuthCancelled(); 7054446eaa935994bc91d6d308303e8d27526b4590dLixin Yue break; 7064446eaa935994bc91d6d308303e8d27526b4590dLixin Yue case MSG_SERVERSESSION_CLOSE: 7074446eaa935994bc91d6d308303e8d27526b4590dLixin Yue stopObexServerSession(); 7084446eaa935994bc91d6d308303e8d27526b4590dLixin Yue break; 7094446eaa935994bc91d6d308303e8d27526b4590dLixin Yue case MSG_SESSION_ESTABLISHED: 7104446eaa935994bc91d6d308303e8d27526b4590dLixin Yue break; 7114446eaa935994bc91d6d308303e8d27526b4590dLixin Yue case MSG_SESSION_DISCONNECTED: 7124446eaa935994bc91d6d308303e8d27526b4590dLixin Yue // case MSG_SERVERSESSION_CLOSE will handle ,so just skip 7134446eaa935994bc91d6d308303e8d27526b4590dLixin Yue break; 7144446eaa935994bc91d6d308303e8d27526b4590dLixin Yue case MSG_OBEX_AUTH_CHALL: 7154446eaa935994bc91d6d308303e8d27526b4590dLixin Yue createPbapNotification(AUTH_CHALL_ACTION); 7164446eaa935994bc91d6d308303e8d27526b4590dLixin Yue mSessionStatusHandler.sendMessageDelayed(mSessionStatusHandler 7174446eaa935994bc91d6d308303e8d27526b4590dLixin Yue .obtainMessage(AUTH_TIMEOUT), USER_CONFIRM_TIMEOUT_VALUE); 7184446eaa935994bc91d6d308303e8d27526b4590dLixin Yue break; 7198fa8d120e86c7488616cc7f7310843f15278b5d9Zhihai Xu case MSG_ACQUIRE_WAKE_LOCK: 7208fa8d120e86c7488616cc7f7310843f15278b5d9Zhihai Xu if (mWakeLock == null) { 7218fa8d120e86c7488616cc7f7310843f15278b5d9Zhihai Xu PowerManager pm = (PowerManager)getSystemService( 7228fa8d120e86c7488616cc7f7310843f15278b5d9Zhihai Xu Context.POWER_SERVICE); 7238fa8d120e86c7488616cc7f7310843f15278b5d9Zhihai Xu mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, 7248fa8d120e86c7488616cc7f7310843f15278b5d9Zhihai Xu "StartingObexPbapTransaction"); 7258fa8d120e86c7488616cc7f7310843f15278b5d9Zhihai Xu mWakeLock.setReferenceCounted(false); 7268fa8d120e86c7488616cc7f7310843f15278b5d9Zhihai Xu mWakeLock.acquire(); 7278fa8d120e86c7488616cc7f7310843f15278b5d9Zhihai Xu Log.w(TAG, "Acquire Wake Lock"); 7288fa8d120e86c7488616cc7f7310843f15278b5d9Zhihai Xu } 7298fa8d120e86c7488616cc7f7310843f15278b5d9Zhihai Xu mSessionStatusHandler.removeMessages(MSG_RELEASE_WAKE_LOCK); 7308fa8d120e86c7488616cc7f7310843f15278b5d9Zhihai Xu mSessionStatusHandler.sendMessageDelayed(mSessionStatusHandler 7318fa8d120e86c7488616cc7f7310843f15278b5d9Zhihai Xu .obtainMessage(MSG_RELEASE_WAKE_LOCK), RELEASE_WAKE_LOCK_DELAY); 7328fa8d120e86c7488616cc7f7310843f15278b5d9Zhihai Xu break; 7338fa8d120e86c7488616cc7f7310843f15278b5d9Zhihai Xu case MSG_RELEASE_WAKE_LOCK: 7348fa8d120e86c7488616cc7f7310843f15278b5d9Zhihai Xu if (mWakeLock != null) { 7358fa8d120e86c7488616cc7f7310843f15278b5d9Zhihai Xu mWakeLock.release(); 7368fa8d120e86c7488616cc7f7310843f15278b5d9Zhihai Xu mWakeLock = null; 7378fa8d120e86c7488616cc7f7310843f15278b5d9Zhihai Xu Log.w(TAG, "Release Wake Lock"); 7388fa8d120e86c7488616cc7f7310843f15278b5d9Zhihai Xu } 7398fa8d120e86c7488616cc7f7310843f15278b5d9Zhihai Xu break; 7404446eaa935994bc91d6d308303e8d27526b4590dLixin Yue default: 7414446eaa935994bc91d6d308303e8d27526b4590dLixin Yue break; 7422c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 7432c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 7444446eaa935994bc91d6d308303e8d27526b4590dLixin Yue }; 7452c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 7462c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan private void setState(int state) { 747d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue setState(state, BluetoothPbap.RESULT_SUCCESS); 7482c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 7492c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 75037b69bd05e4b7a7d0e43575a6c22734b2d8c3f69Jackson Fan private synchronized void setState(int state, int result) { 75137b69bd05e4b7a7d0e43575a6c22734b2d8c3f69Jackson Fan if (state != mState) { 7524446eaa935994bc91d6d308303e8d27526b4590dLixin Yue if (DEBUG) Log.d(TAG, "Pbap state " + mState + " -> " + state + ", result = " 7534446eaa935994bc91d6d308303e8d27526b4590dLixin Yue + result); 754cab07635ea60924a4e9dc13f87a4408988ad4c57Jaikumar Ganesh int prevState = mState; 75537b69bd05e4b7a7d0e43575a6c22734b2d8c3f69Jackson Fan mState = state; 756cab07635ea60924a4e9dc13f87a4408988ad4c57Jaikumar Ganesh Intent intent = new Intent(BluetoothPbap.PBAP_STATE_CHANGED_ACTION); 757cab07635ea60924a4e9dc13f87a4408988ad4c57Jaikumar Ganesh intent.putExtra(BluetoothPbap.PBAP_PREVIOUS_STATE, prevState); 75837b69bd05e4b7a7d0e43575a6c22734b2d8c3f69Jackson Fan intent.putExtra(BluetoothPbap.PBAP_STATE, mState); 759f2c447b81c6c03cb1c8a3e64a10381e23934834aNick Pelly intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mRemoteDevice); 76037b69bd05e4b7a7d0e43575a6c22734b2d8c3f69Jackson Fan sendBroadcast(intent, BLUETOOTH_PERM); 761b5cc776c9353a203cdde97e62b25f05d9633d14cfredc AdapterService s = AdapterService.getAdapterService(); 762b5cc776c9353a203cdde97e62b25f05d9633d14cfredc if (s != null) { 763b5cc776c9353a203cdde97e62b25f05d9633d14cfredc s.onProfileConnectionStateChanged(mRemoteDevice, BluetoothProfile.PBAP, 764b5cc776c9353a203cdde97e62b25f05d9633d14cfredc mState, prevState); 765b5cc776c9353a203cdde97e62b25f05d9633d14cfredc } 76637b69bd05e4b7a7d0e43575a6c22734b2d8c3f69Jackson Fan } 76737b69bd05e4b7a7d0e43575a6c22734b2d8c3f69Jackson Fan } 7682c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 7694446eaa935994bc91d6d308303e8d27526b4590dLixin Yue private void createPbapNotification(String action) { 7704446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 7710bd5f7b5c36a60687ffe895368fd8df6df38acabJaikumar Ganesh NotificationManager nm = (NotificationManager) 7720bd5f7b5c36a60687ffe895368fd8df6df38acabJaikumar Ganesh getSystemService(Context.NOTIFICATION_SERVICE); 7734446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 7744446eaa935994bc91d6d308303e8d27526b4590dLixin Yue // Create an intent triggered by clicking on the status icon. 7754446eaa935994bc91d6d308303e8d27526b4590dLixin Yue Intent clickIntent = new Intent(); 7760bd5f7b5c36a60687ffe895368fd8df6df38acabJaikumar Ganesh clickIntent.setClass(this, BluetoothPbapActivity.class); 7774446eaa935994bc91d6d308303e8d27526b4590dLixin Yue clickIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 7784446eaa935994bc91d6d308303e8d27526b4590dLixin Yue clickIntent.setAction(action); 7794446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 7804446eaa935994bc91d6d308303e8d27526b4590dLixin Yue // Create an intent triggered by clicking on the 7814446eaa935994bc91d6d308303e8d27526b4590dLixin Yue // "Clear All Notifications" button 7824446eaa935994bc91d6d308303e8d27526b4590dLixin Yue Intent deleteIntent = new Intent(); 7830bd5f7b5c36a60687ffe895368fd8df6df38acabJaikumar Ganesh deleteIntent.setClass(this, BluetoothPbapReceiver.class); 7844446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 7854446eaa935994bc91d6d308303e8d27526b4590dLixin Yue Notification notification = null; 7864446eaa935994bc91d6d308303e8d27526b4590dLixin Yue String name = getRemoteDeviceName(); 7870bd5f7b5c36a60687ffe895368fd8df6df38acabJaikumar Ganesh 7887eab97d6be9228b1c210bbb171c3e5e88e02f3d8Matthew Xie if (action.equals(AUTH_CHALL_ACTION)) { 7894446eaa935994bc91d6d308303e8d27526b4590dLixin Yue deleteIntent.setAction(AUTH_CANCELLED_ACTION); 7900bd5f7b5c36a60687ffe895368fd8df6df38acabJaikumar Ganesh notification = new Notification(android.R.drawable.stat_sys_data_bluetooth, 7910bd5f7b5c36a60687ffe895368fd8df6df38acabJaikumar Ganesh getString(R.string.auth_notif_ticker), System.currentTimeMillis()); 7920ce48bf302e010af811c903f8a986df567562ecfSelim Cinek notification.color = getResources().getColor( 7930ce48bf302e010af811c903f8a986df567562ecfSelim Cinek com.android.internal.R.color.system_notification_accent_color); 7940bd5f7b5c36a60687ffe895368fd8df6df38acabJaikumar Ganesh notification.setLatestEventInfo(this, getString(R.string.auth_notif_title), 7950bd5f7b5c36a60687ffe895368fd8df6df38acabJaikumar Ganesh getString(R.string.auth_notif_message, name), PendingIntent 7960bd5f7b5c36a60687ffe895368fd8df6df38acabJaikumar Ganesh .getActivity(this, 0, clickIntent, 0)); 7974446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 7984446eaa935994bc91d6d308303e8d27526b4590dLixin Yue notification.flags |= Notification.FLAG_AUTO_CANCEL; 799c5495c585c0d19cdd20963e5a2144e5f984a306eLixin Yue notification.flags |= Notification.FLAG_ONLY_ALERT_ONCE; 800c5495c585c0d19cdd20963e5a2144e5f984a306eLixin Yue notification.defaults = Notification.DEFAULT_SOUND; 8010bd5f7b5c36a60687ffe895368fd8df6df38acabJaikumar Ganesh notification.deleteIntent = PendingIntent.getBroadcast(this, 0, deleteIntent, 0); 8024446eaa935994bc91d6d308303e8d27526b4590dLixin Yue nm.notify(NOTIFICATION_ID_AUTH, notification); 8034446eaa935994bc91d6d308303e8d27526b4590dLixin Yue } 8044446eaa935994bc91d6d308303e8d27526b4590dLixin Yue } 8054446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 8064446eaa935994bc91d6d308303e8d27526b4590dLixin Yue private void removePbapNotification(int id) { 8070bd5f7b5c36a60687ffe895368fd8df6df38acabJaikumar Ganesh NotificationManager nm = (NotificationManager) 8080bd5f7b5c36a60687ffe895368fd8df6df38acabJaikumar Ganesh getSystemService(Context.NOTIFICATION_SERVICE); 8094446eaa935994bc91d6d308303e8d27526b4590dLixin Yue nm.cancel(id); 8104446eaa935994bc91d6d308303e8d27526b4590dLixin Yue } 8114446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 8124446eaa935994bc91d6d308303e8d27526b4590dLixin Yue public static String getLocalPhoneNum() { 8134446eaa935994bc91d6d308303e8d27526b4590dLixin Yue return sLocalPhoneNum; 8144446eaa935994bc91d6d308303e8d27526b4590dLixin Yue } 8154446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 8164446eaa935994bc91d6d308303e8d27526b4590dLixin Yue public static String getLocalPhoneName() { 8174446eaa935994bc91d6d308303e8d27526b4590dLixin Yue return sLocalPhoneName; 8184446eaa935994bc91d6d308303e8d27526b4590dLixin Yue } 8194446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 8204446eaa935994bc91d6d308303e8d27526b4590dLixin Yue public static String getRemoteDeviceName() { 8214446eaa935994bc91d6d308303e8d27526b4590dLixin Yue return sRemoteDeviceName; 8224446eaa935994bc91d6d308303e8d27526b4590dLixin Yue } 8234446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 8242c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan /** 8252c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan * Handlers for incoming service calls 8262c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan */ 8272c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan private final IBluetoothPbap.Stub mBinder = new IBluetoothPbap.Stub() { 8282c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan public int getState() { 8294446eaa935994bc91d6d308303e8d27526b4590dLixin Yue if (DEBUG) Log.d(TAG, "getState " + mState); 8304446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 83137510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu if (!Utils.checkCaller()) { 83237510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu Log.w(TAG,"getState(): not allowed for non-active user"); 83337510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu return BluetoothPbap.STATE_DISCONNECTED; 83437510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu } 83537510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu 8362c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 8372c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan return mState; 8382c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 8392c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 84041ef8d494511c040451f2f887cb31c3100746b61Nick Pelly public BluetoothDevice getClient() { 8414446eaa935994bc91d6d308303e8d27526b4590dLixin Yue if (DEBUG) Log.d(TAG, "getClient" + mRemoteDevice); 8424446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 84337510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu if (!Utils.checkCaller()) { 84437510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu Log.w(TAG,"getClient(): not allowed for non-active user"); 84537510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu return null; 84637510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu } 84737510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu 8482c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 8492c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan if (mState == BluetoothPbap.STATE_DISCONNECTED) { 8502c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan return null; 8512c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 85241ef8d494511c040451f2f887cb31c3100746b61Nick Pelly return mRemoteDevice; 8532c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 8542c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 85541ef8d494511c040451f2f887cb31c3100746b61Nick Pelly public boolean isConnected(BluetoothDevice device) { 85637510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu if (!Utils.checkCaller()) { 85737510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu Log.w(TAG,"isConnected(): not allowed for non-active user"); 85837510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu return false; 85937510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu } 86037510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu 8612c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 86241ef8d494511c040451f2f887cb31c3100746b61Nick Pelly return mState == BluetoothPbap.STATE_CONNECTED && mRemoteDevice.equals(device); 8632c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 8642c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 86541ef8d494511c040451f2f887cb31c3100746b61Nick Pelly public boolean connect(BluetoothDevice device) { 86637510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu if (!Utils.checkCaller()) { 86737510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu Log.w(TAG,"connect(): not allowed for non-active user"); 86837510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu return false; 86937510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu } 87037510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu 871d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, 872d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue "Need BLUETOOTH_ADMIN permission"); 8732c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan return false; 8742c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 8752c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 87641ef8d494511c040451f2f887cb31c3100746b61Nick Pelly public void disconnect() { 8774446eaa935994bc91d6d308303e8d27526b4590dLixin Yue if (DEBUG) Log.d(TAG, "disconnect"); 8784446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 87937510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu if (!Utils.checkCaller()) { 88037510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu Log.w(TAG,"disconnect(): not allowed for non-active user"); 88137510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu return; 88237510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu } 88337510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu 884d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, 885d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue "Need BLUETOOTH_ADMIN permission"); 8862c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan synchronized (BluetoothPbapService.this) { 8872c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan switch (mState) { 8882c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan case BluetoothPbap.STATE_CONNECTED: 8892c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan if (mServerSession != null) { 8902c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan mServerSession.close(); 8912c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan mServerSession = null; 8922c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 8937b91a410d595b879548e540889f8b30a0d6476c4Zhihai Xu 8947b91a410d595b879548e540889f8b30a0d6476c4Zhihai Xu closeConnectionSocket(); 8957b91a410d595b879548e540889f8b30a0d6476c4Zhihai Xu 8962c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan setState(BluetoothPbap.STATE_DISCONNECTED, BluetoothPbap.RESULT_CANCELED); 8972c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan break; 8984446eaa935994bc91d6d308303e8d27526b4590dLixin Yue default: 8994446eaa935994bc91d6d308303e8d27526b4590dLixin Yue break; 9002c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 9012c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 9022c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 9032c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan }; 9042c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan} 905