Loading android/app/src/com/android/bluetooth/pbapclient/PbapClientConnectionHandler.java +79 −3 Original line number Diff line number Diff line Loading @@ -15,17 +15,23 @@ */ package com.android.bluetooth.pbapclient; import android.accounts.Account; import android.accounts.AccountManager; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothSocket; import android.bluetooth.BluetoothUuid; import android.content.Context; import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; import android.os.Message; import android.os.Process; import android.provider.CallLog; import android.util.Log; import com.android.bluetooth.R; import java.io.IOException; import javax.obex.ClientSession; Loading @@ -44,6 +50,8 @@ class PbapClientConnectionHandler extends Handler { static final int MSG_DISCONNECT = 2; static final int MSG_DOWNLOAD = 3; // The following constants are pulled from the Bluetooth Phone Book Access Profile specification // 1.1 private static final byte[] PBAP_TARGET = new byte[] { 0x79, 0x61, 0x35, (byte) 0xf0, (byte) 0xf0, (byte) 0xc5, 0x11, (byte) 0xd8, 0x09, 0x66, 0x08, 0x00, 0x20, 0x0c, (byte) 0x9a, 0x66 Loading @@ -51,14 +59,19 @@ class PbapClientConnectionHandler extends Handler { public static final String PB_PATH = "telecom/pb.vcf"; public static final String MCH_PATH = "telecom/mch.vcf"; public static final String ICH_PATH = "telecom/ich.vcf"; public static final String OCH_PATH = "telecom/och.vcf"; public static final byte VCARD_TYPE_21 = 0; private Account mAccount; private AccountManager mAccountManager; private BluetoothSocket mSocket; private final BluetoothAdapter mAdapter; private final BluetoothDevice mDevice; private ClientSession mObexSession; private BluetoothPbapObexAuthenticator mAuth = null; private final PbapClientStateMachine mPbapClientStateMachine; private boolean mAccountCreated; PbapClientConnectionHandler(Looper looper, PbapClientStateMachine stateMachine, BluetoothDevice device) { Loading @@ -67,6 +80,7 @@ class PbapClientConnectionHandler extends Handler { mDevice = device; mPbapClientStateMachine = stateMachine; mAuth = new BluetoothPbapObexAuthenticator(this); mAccountManager = AccountManager.get(mPbapClientStateMachine.getContext()); } @Override Loading @@ -80,6 +94,10 @@ class PbapClientConnectionHandler extends Handler { /* To establish a connection first open a socket, establish a OBEX Transport * abstraction, establish a Bluetooth Authenticator, and finally attempt to * connect via an OBEX session */ mAccount = new Account(mDevice.getAddress(), mPbapClientStateMachine.getContext() .getString(R.string.pbap_account_type)); mSocket = mDevice.createRfcommSocketToServiceRecord( BluetoothUuid.PBAP_PSE.getUuid()); mSocket.connect(); Loading Loading @@ -116,24 +134,45 @@ class PbapClientConnectionHandler extends Handler { if (mObexSession != null) { mObexSession.disconnect(null); } closeSocket(); } catch (IOException e) { Log.w(TAG,"DISCONNECT Failure " + e.toString()); } removeAccount(mAccount); mPbapClientStateMachine.getContext().getContentResolver() .delete(CallLog.Calls.CONTENT_URI, null, null); mPbapClientStateMachine.obtainMessage( PbapClientStateMachine.MSG_CONNECTION_CLOSED).sendToTarget(); break; case MSG_DOWNLOAD: if (mAccountCreated == true) { // If the account exists download has already completed, don't try again. return; } try { mAccountCreated = addAccount(mAccount); if (mAccountCreated == false) { Log.d(TAG,"Account creation failed, normal durring startup"); return; } BluetoothPbapRequestPullPhoneBook request = new BluetoothPbapRequestPullPhoneBook(PB_PATH, null, 0, VCARD_TYPE_21, 0, 0); new BluetoothPbapRequestPullPhoneBook(PB_PATH, mAccount, 0, VCARD_TYPE_21, 0, 0); request.execute(mObexSession); if (DBG) Log.d(TAG,"Download success? " + request.isSuccess()); PhonebookPullRequest processor = new PhonebookPullRequest(mPbapClientStateMachine.getContext(), mAccount); processor.setResults(request.getList()); processor.onPullComplete(); downloadCallLog(MCH_PATH); downloadCallLog(ICH_PATH); downloadCallLog(OCH_PATH); } catch (IOException e) { Log.w(TAG,"DOWNLOAD_CONTACTS Failure" + e.toString()); } break; default: Log.w(TAG,"Received Unexpected Message"); } Loading @@ -141,7 +180,10 @@ class PbapClientConnectionHandler extends Handler { } public void abort() { // Perform forced cleanup, it is ok if the handler throws an exception this will free the // handler to complete what it is doing and finish with cleanup. closeSocket(); this.getLooper().getThread().interrupt(); } private void closeSocket() { Loading @@ -152,6 +194,40 @@ class PbapClientConnectionHandler extends Handler { } } catch (IOException e) { Log.e(TAG, "Error when closing socket", e); mSocket = null; } } void downloadCallLog(String path) { try { BluetoothPbapRequestPullPhoneBook request = new BluetoothPbapRequestPullPhoneBook(path,mAccount,0,VCARD_TYPE_21,0,0); request.execute(mObexSession); CallLogPullRequest processor = new CallLogPullRequest(mPbapClientStateMachine.getContext(),path); processor.setResults(request.getList()); processor.onPullComplete(); } catch (IOException e) { Log.w(TAG,"Download call log failure"); } } private boolean addAccount(Account account) { if (mAccountManager.addAccountExplicitly(account, null, null)) { if (DBG) { Log.d(TAG, "Added account " + mAccount); } return true; } return false; } private void removeAccount(Account acc) { if (mAccountManager.removeAccountExplicitly(acc)) { if (DBG) { Log.d(TAG, "Removed account " + acc); } } else { Log.e(TAG, "Failed to remove account " + mAccount); } } } android/app/src/com/android/bluetooth/pbapclient/PbapClientService.java +17 −2 Original line number Diff line number Diff line Loading @@ -74,6 +74,8 @@ public class PbapClientService extends ProfileService { protected boolean start() { IntentFilter filter = new IntentFilter(); filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED); // delay initial download until after the user is unlocked to add an account. filter.addAction(Intent.ACTION_USER_UNLOCKED); try { registerReceiver(mPbapBroadcastReceiver, filter); } catch (Exception e) { Loading @@ -92,7 +94,9 @@ public class PbapClientService extends ProfileService { } catch (Exception e) { Log.w(TAG,"Unable to unregister pbapclient receiver",e); } mPbapClientStateMachine.disconnect(null); if (mPbapClientStateMachine != null) { mPbapClientStateMachine.doQuit(); } return true; } Loading @@ -109,8 +113,12 @@ public class PbapClientService extends ProfileService { String action = intent.getAction(); if (action.equals(BluetoothDevice.ACTION_ACL_DISCONNECTED)) { BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); if (getConnectionState(device) != BluetoothProfile.STATE_DISCONNECTED) { disconnect(device); } } else if(action.equals(Intent.ACTION_USER_UNLOCKED)) { mPbapClientStateMachine.resumeDownload(); } } } Loading Loading @@ -307,4 +315,11 @@ public class PbapClientService extends ProfileService { return priority; } @Override public void dump(StringBuilder sb) { super.dump(sb); if (mPbapClientStateMachine != null) { mPbapClientStateMachine.dump(sb); } } } android/app/src/com/android/bluetooth/pbapclient/PbapClientStateMachine.java +63 −11 Original line number Diff line number Diff line Loading @@ -41,6 +41,8 @@ */ package com.android.bluetooth.pbapclient; import android.accounts.Account; import android.accounts.AccountManager; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothProfile; import android.bluetooth.BluetoothPbapClient; Loading @@ -49,9 +51,11 @@ import android.content.Intent; import android.os.Message; import android.os.Process; import android.os.HandlerThread; import android.provider.CallLog; import android.util.Log; import com.android.bluetooth.btservice.ProfileService; import com.android.bluetooth.R; import com.android.internal.util.IState; import com.android.internal.util.State; import com.android.internal.util.StateMachine; Loading @@ -76,6 +80,7 @@ final class PbapClientStateMachine extends StateMachine { static final int MSG_CONNECTION_COMPLETE = 5; static final int MSG_CONNECTION_FAILED = 6; static final int MSG_CONNECTION_CLOSED = 7; static final int MSG_RESUME_DOWNLOAD = 8; static final int CONNECT_TIMEOUT = 6000; static final int DISCONNECT_TIMEOUT = 3000; Loading Loading @@ -142,6 +147,9 @@ final class PbapClientStateMachine extends StateMachine { break; case MSG_DISCONNECT: Log.w(TAG,"Received unexpected disconnect while disconnected."); // It is possible if something crashed for others to think we are connected // already, just remind them. if (message.obj instanceof BluetoothDevice) { onConnectionStateChanged((BluetoothDevice) message.obj, BluetoothProfile.STATE_DISCONNECTED, Loading @@ -149,6 +157,10 @@ final class PbapClientStateMachine extends StateMachine { } break; case MSG_RESUME_DOWNLOAD: // Do nothing. break; default: Log.w(TAG,"Received unexpected message while disconnected."); return NOT_HANDLED; Loading @@ -158,15 +170,9 @@ final class PbapClientStateMachine extends StateMachine { } class Connecting extends State { private boolean mAccountCreated; private boolean mObexAuthorized; @Override public void enter() { if (DBG) Log.d(TAG,"Enter Connecting: " + getCurrentMessage().what); mAccountCreated = false; mObexAuthorized = false; onConnectionStateChanged(mCurrentDevice, mMostRecentState, BluetoothProfile.STATE_CONNECTING); mMostRecentState = BluetoothProfile.STATE_CONNECTING; Loading @@ -180,7 +186,6 @@ final class PbapClientStateMachine extends StateMachine { mConnectionHandler.obtainMessage(PbapClientConnectionHandler.MSG_CONNECT) .sendToTarget(); sendMessageDelayed(MSG_CONNECT_TIMEOUT, CONNECT_TIMEOUT); // TODO: create account } @Override Loading @@ -206,6 +211,10 @@ final class PbapClientStateMachine extends StateMachine { Log.w(TAG,"Connecting already in progress"); break; case MSG_RESUME_DOWNLOAD: // Do nothing. break; default: Log.w(TAG,"Received unexpected message while Connecting"); return NOT_HANDLED; Loading @@ -221,7 +230,8 @@ final class PbapClientStateMachine extends StateMachine { onConnectionStateChanged(mCurrentDevice, mMostRecentState, BluetoothProfile.STATE_DISCONNECTING); mMostRecentState = BluetoothProfile.STATE_DISCONNECTING; mConnectionHandler.obtainMessage(PbapClientConnectionHandler.MSG_DISCONNECT).sendToTarget(); mConnectionHandler.obtainMessage(PbapClientConnectionHandler.MSG_DISCONNECT) .sendToTarget(); sendMessageDelayed(MSG_DISCONNECT_TIMEOUT,DISCONNECT_TIMEOUT); } Loading @@ -245,6 +255,10 @@ final class PbapClientStateMachine extends StateMachine { mConnectionHandler.abort(); break; case MSG_RESUME_DOWNLOAD: // Do nothing. break; default: Log.w(TAG,"Received unexpected message while Disconnecting"); return NOT_HANDLED; Loading @@ -260,8 +274,8 @@ final class PbapClientStateMachine extends StateMachine { onConnectionStateChanged(mCurrentDevice, mMostRecentState, BluetoothProfile.STATE_CONNECTED); mMostRecentState = BluetoothProfile.STATE_CONNECTED; // mConnectionHandler.obtainMessage(PbapClientConnectionHandler.MSG_DOWNLOAD) // .sendToTarget(); mConnectionHandler.obtainMessage(PbapClientConnectionHandler.MSG_DOWNLOAD) .sendToTarget(); } @Override Loading @@ -280,6 +294,11 @@ final class PbapClientStateMachine extends StateMachine { transitionTo(mDisconnecting); break; case MSG_RESUME_DOWNLOAD: mConnectionHandler.obtainMessage(PbapClientConnectionHandler.MSG_DOWNLOAD) .sendToTarget(); break; default: Log.w(TAG,"Received unexpected message while Connected"); return NOT_HANDLED; Loading Loading @@ -312,6 +331,15 @@ final class PbapClientStateMachine extends StateMachine { sendMessage(MSG_DISCONNECT, device); } public void resumeDownload() { removeUncleanAccounts(); sendMessage(MSG_RESUME_DOWNLOAD); } void doQuit() { quitNow(); } public int getConnectionState() { IState currentState = getCurrentState(); if (currentState instanceof Disconnected) { Loading Loading @@ -370,4 +398,28 @@ final class PbapClientStateMachine extends StateMachine { } return mCurrentDevice; } Context getContext() { return mContext; } private void removeUncleanAccounts() { // Find all accounts that match the type "pbap" and delete them. AccountManager accountManager = AccountManager.get(mContext); Account[] accounts = accountManager.getAccountsByType( mContext.getString(R.string.pbap_account_type)); Log.w(TAG, "Found " + accounts.length + " unclean accounts"); for (Account acc : accounts) { Log.w(TAG, "Deleting " + acc); // The device ID is the name of the account. accountManager.removeAccountExplicitly(acc); } mContext.getContentResolver().delete(CallLog.Calls.CONTENT_URI, null, null); } public void dump(StringBuilder sb) { ProfileService.println(sb, "mCurrentDevice: " + mCurrentDevice); ProfileService.println(sb, "StateMachine: " + this.toString()); } } Loading
android/app/src/com/android/bluetooth/pbapclient/PbapClientConnectionHandler.java +79 −3 Original line number Diff line number Diff line Loading @@ -15,17 +15,23 @@ */ package com.android.bluetooth.pbapclient; import android.accounts.Account; import android.accounts.AccountManager; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothSocket; import android.bluetooth.BluetoothUuid; import android.content.Context; import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; import android.os.Message; import android.os.Process; import android.provider.CallLog; import android.util.Log; import com.android.bluetooth.R; import java.io.IOException; import javax.obex.ClientSession; Loading @@ -44,6 +50,8 @@ class PbapClientConnectionHandler extends Handler { static final int MSG_DISCONNECT = 2; static final int MSG_DOWNLOAD = 3; // The following constants are pulled from the Bluetooth Phone Book Access Profile specification // 1.1 private static final byte[] PBAP_TARGET = new byte[] { 0x79, 0x61, 0x35, (byte) 0xf0, (byte) 0xf0, (byte) 0xc5, 0x11, (byte) 0xd8, 0x09, 0x66, 0x08, 0x00, 0x20, 0x0c, (byte) 0x9a, 0x66 Loading @@ -51,14 +59,19 @@ class PbapClientConnectionHandler extends Handler { public static final String PB_PATH = "telecom/pb.vcf"; public static final String MCH_PATH = "telecom/mch.vcf"; public static final String ICH_PATH = "telecom/ich.vcf"; public static final String OCH_PATH = "telecom/och.vcf"; public static final byte VCARD_TYPE_21 = 0; private Account mAccount; private AccountManager mAccountManager; private BluetoothSocket mSocket; private final BluetoothAdapter mAdapter; private final BluetoothDevice mDevice; private ClientSession mObexSession; private BluetoothPbapObexAuthenticator mAuth = null; private final PbapClientStateMachine mPbapClientStateMachine; private boolean mAccountCreated; PbapClientConnectionHandler(Looper looper, PbapClientStateMachine stateMachine, BluetoothDevice device) { Loading @@ -67,6 +80,7 @@ class PbapClientConnectionHandler extends Handler { mDevice = device; mPbapClientStateMachine = stateMachine; mAuth = new BluetoothPbapObexAuthenticator(this); mAccountManager = AccountManager.get(mPbapClientStateMachine.getContext()); } @Override Loading @@ -80,6 +94,10 @@ class PbapClientConnectionHandler extends Handler { /* To establish a connection first open a socket, establish a OBEX Transport * abstraction, establish a Bluetooth Authenticator, and finally attempt to * connect via an OBEX session */ mAccount = new Account(mDevice.getAddress(), mPbapClientStateMachine.getContext() .getString(R.string.pbap_account_type)); mSocket = mDevice.createRfcommSocketToServiceRecord( BluetoothUuid.PBAP_PSE.getUuid()); mSocket.connect(); Loading Loading @@ -116,24 +134,45 @@ class PbapClientConnectionHandler extends Handler { if (mObexSession != null) { mObexSession.disconnect(null); } closeSocket(); } catch (IOException e) { Log.w(TAG,"DISCONNECT Failure " + e.toString()); } removeAccount(mAccount); mPbapClientStateMachine.getContext().getContentResolver() .delete(CallLog.Calls.CONTENT_URI, null, null); mPbapClientStateMachine.obtainMessage( PbapClientStateMachine.MSG_CONNECTION_CLOSED).sendToTarget(); break; case MSG_DOWNLOAD: if (mAccountCreated == true) { // If the account exists download has already completed, don't try again. return; } try { mAccountCreated = addAccount(mAccount); if (mAccountCreated == false) { Log.d(TAG,"Account creation failed, normal durring startup"); return; } BluetoothPbapRequestPullPhoneBook request = new BluetoothPbapRequestPullPhoneBook(PB_PATH, null, 0, VCARD_TYPE_21, 0, 0); new BluetoothPbapRequestPullPhoneBook(PB_PATH, mAccount, 0, VCARD_TYPE_21, 0, 0); request.execute(mObexSession); if (DBG) Log.d(TAG,"Download success? " + request.isSuccess()); PhonebookPullRequest processor = new PhonebookPullRequest(mPbapClientStateMachine.getContext(), mAccount); processor.setResults(request.getList()); processor.onPullComplete(); downloadCallLog(MCH_PATH); downloadCallLog(ICH_PATH); downloadCallLog(OCH_PATH); } catch (IOException e) { Log.w(TAG,"DOWNLOAD_CONTACTS Failure" + e.toString()); } break; default: Log.w(TAG,"Received Unexpected Message"); } Loading @@ -141,7 +180,10 @@ class PbapClientConnectionHandler extends Handler { } public void abort() { // Perform forced cleanup, it is ok if the handler throws an exception this will free the // handler to complete what it is doing and finish with cleanup. closeSocket(); this.getLooper().getThread().interrupt(); } private void closeSocket() { Loading @@ -152,6 +194,40 @@ class PbapClientConnectionHandler extends Handler { } } catch (IOException e) { Log.e(TAG, "Error when closing socket", e); mSocket = null; } } void downloadCallLog(String path) { try { BluetoothPbapRequestPullPhoneBook request = new BluetoothPbapRequestPullPhoneBook(path,mAccount,0,VCARD_TYPE_21,0,0); request.execute(mObexSession); CallLogPullRequest processor = new CallLogPullRequest(mPbapClientStateMachine.getContext(),path); processor.setResults(request.getList()); processor.onPullComplete(); } catch (IOException e) { Log.w(TAG,"Download call log failure"); } } private boolean addAccount(Account account) { if (mAccountManager.addAccountExplicitly(account, null, null)) { if (DBG) { Log.d(TAG, "Added account " + mAccount); } return true; } return false; } private void removeAccount(Account acc) { if (mAccountManager.removeAccountExplicitly(acc)) { if (DBG) { Log.d(TAG, "Removed account " + acc); } } else { Log.e(TAG, "Failed to remove account " + mAccount); } } }
android/app/src/com/android/bluetooth/pbapclient/PbapClientService.java +17 −2 Original line number Diff line number Diff line Loading @@ -74,6 +74,8 @@ public class PbapClientService extends ProfileService { protected boolean start() { IntentFilter filter = new IntentFilter(); filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED); // delay initial download until after the user is unlocked to add an account. filter.addAction(Intent.ACTION_USER_UNLOCKED); try { registerReceiver(mPbapBroadcastReceiver, filter); } catch (Exception e) { Loading @@ -92,7 +94,9 @@ public class PbapClientService extends ProfileService { } catch (Exception e) { Log.w(TAG,"Unable to unregister pbapclient receiver",e); } mPbapClientStateMachine.disconnect(null); if (mPbapClientStateMachine != null) { mPbapClientStateMachine.doQuit(); } return true; } Loading @@ -109,8 +113,12 @@ public class PbapClientService extends ProfileService { String action = intent.getAction(); if (action.equals(BluetoothDevice.ACTION_ACL_DISCONNECTED)) { BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); if (getConnectionState(device) != BluetoothProfile.STATE_DISCONNECTED) { disconnect(device); } } else if(action.equals(Intent.ACTION_USER_UNLOCKED)) { mPbapClientStateMachine.resumeDownload(); } } } Loading Loading @@ -307,4 +315,11 @@ public class PbapClientService extends ProfileService { return priority; } @Override public void dump(StringBuilder sb) { super.dump(sb); if (mPbapClientStateMachine != null) { mPbapClientStateMachine.dump(sb); } } }
android/app/src/com/android/bluetooth/pbapclient/PbapClientStateMachine.java +63 −11 Original line number Diff line number Diff line Loading @@ -41,6 +41,8 @@ */ package com.android.bluetooth.pbapclient; import android.accounts.Account; import android.accounts.AccountManager; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothProfile; import android.bluetooth.BluetoothPbapClient; Loading @@ -49,9 +51,11 @@ import android.content.Intent; import android.os.Message; import android.os.Process; import android.os.HandlerThread; import android.provider.CallLog; import android.util.Log; import com.android.bluetooth.btservice.ProfileService; import com.android.bluetooth.R; import com.android.internal.util.IState; import com.android.internal.util.State; import com.android.internal.util.StateMachine; Loading @@ -76,6 +80,7 @@ final class PbapClientStateMachine extends StateMachine { static final int MSG_CONNECTION_COMPLETE = 5; static final int MSG_CONNECTION_FAILED = 6; static final int MSG_CONNECTION_CLOSED = 7; static final int MSG_RESUME_DOWNLOAD = 8; static final int CONNECT_TIMEOUT = 6000; static final int DISCONNECT_TIMEOUT = 3000; Loading Loading @@ -142,6 +147,9 @@ final class PbapClientStateMachine extends StateMachine { break; case MSG_DISCONNECT: Log.w(TAG,"Received unexpected disconnect while disconnected."); // It is possible if something crashed for others to think we are connected // already, just remind them. if (message.obj instanceof BluetoothDevice) { onConnectionStateChanged((BluetoothDevice) message.obj, BluetoothProfile.STATE_DISCONNECTED, Loading @@ -149,6 +157,10 @@ final class PbapClientStateMachine extends StateMachine { } break; case MSG_RESUME_DOWNLOAD: // Do nothing. break; default: Log.w(TAG,"Received unexpected message while disconnected."); return NOT_HANDLED; Loading @@ -158,15 +170,9 @@ final class PbapClientStateMachine extends StateMachine { } class Connecting extends State { private boolean mAccountCreated; private boolean mObexAuthorized; @Override public void enter() { if (DBG) Log.d(TAG,"Enter Connecting: " + getCurrentMessage().what); mAccountCreated = false; mObexAuthorized = false; onConnectionStateChanged(mCurrentDevice, mMostRecentState, BluetoothProfile.STATE_CONNECTING); mMostRecentState = BluetoothProfile.STATE_CONNECTING; Loading @@ -180,7 +186,6 @@ final class PbapClientStateMachine extends StateMachine { mConnectionHandler.obtainMessage(PbapClientConnectionHandler.MSG_CONNECT) .sendToTarget(); sendMessageDelayed(MSG_CONNECT_TIMEOUT, CONNECT_TIMEOUT); // TODO: create account } @Override Loading @@ -206,6 +211,10 @@ final class PbapClientStateMachine extends StateMachine { Log.w(TAG,"Connecting already in progress"); break; case MSG_RESUME_DOWNLOAD: // Do nothing. break; default: Log.w(TAG,"Received unexpected message while Connecting"); return NOT_HANDLED; Loading @@ -221,7 +230,8 @@ final class PbapClientStateMachine extends StateMachine { onConnectionStateChanged(mCurrentDevice, mMostRecentState, BluetoothProfile.STATE_DISCONNECTING); mMostRecentState = BluetoothProfile.STATE_DISCONNECTING; mConnectionHandler.obtainMessage(PbapClientConnectionHandler.MSG_DISCONNECT).sendToTarget(); mConnectionHandler.obtainMessage(PbapClientConnectionHandler.MSG_DISCONNECT) .sendToTarget(); sendMessageDelayed(MSG_DISCONNECT_TIMEOUT,DISCONNECT_TIMEOUT); } Loading @@ -245,6 +255,10 @@ final class PbapClientStateMachine extends StateMachine { mConnectionHandler.abort(); break; case MSG_RESUME_DOWNLOAD: // Do nothing. break; default: Log.w(TAG,"Received unexpected message while Disconnecting"); return NOT_HANDLED; Loading @@ -260,8 +274,8 @@ final class PbapClientStateMachine extends StateMachine { onConnectionStateChanged(mCurrentDevice, mMostRecentState, BluetoothProfile.STATE_CONNECTED); mMostRecentState = BluetoothProfile.STATE_CONNECTED; // mConnectionHandler.obtainMessage(PbapClientConnectionHandler.MSG_DOWNLOAD) // .sendToTarget(); mConnectionHandler.obtainMessage(PbapClientConnectionHandler.MSG_DOWNLOAD) .sendToTarget(); } @Override Loading @@ -280,6 +294,11 @@ final class PbapClientStateMachine extends StateMachine { transitionTo(mDisconnecting); break; case MSG_RESUME_DOWNLOAD: mConnectionHandler.obtainMessage(PbapClientConnectionHandler.MSG_DOWNLOAD) .sendToTarget(); break; default: Log.w(TAG,"Received unexpected message while Connected"); return NOT_HANDLED; Loading Loading @@ -312,6 +331,15 @@ final class PbapClientStateMachine extends StateMachine { sendMessage(MSG_DISCONNECT, device); } public void resumeDownload() { removeUncleanAccounts(); sendMessage(MSG_RESUME_DOWNLOAD); } void doQuit() { quitNow(); } public int getConnectionState() { IState currentState = getCurrentState(); if (currentState instanceof Disconnected) { Loading Loading @@ -370,4 +398,28 @@ final class PbapClientStateMachine extends StateMachine { } return mCurrentDevice; } Context getContext() { return mContext; } private void removeUncleanAccounts() { // Find all accounts that match the type "pbap" and delete them. AccountManager accountManager = AccountManager.get(mContext); Account[] accounts = accountManager.getAccountsByType( mContext.getString(R.string.pbap_account_type)); Log.w(TAG, "Found " + accounts.length + " unclean accounts"); for (Account acc : accounts) { Log.w(TAG, "Deleting " + acc); // The device ID is the name of the account. accountManager.removeAccountExplicitly(acc); } mContext.getContentResolver().delete(CallLog.Calls.CONTENT_URI, null, null); } public void dump(StringBuilder sb) { ProfileService.println(sb, "mCurrentDevice: " + mCurrentDevice); ProfileService.println(sb, "StateMachine: " + this.toString()); } }