Loading src/com/android/bluetooth/pbapclient/CallLogPullRequest.java +4 −9 Original line number Diff line number Diff line Loading @@ -48,14 +48,14 @@ public class CallLogPullRequest extends PullRequest { } @Override public void onPullComplete(boolean success, List<VCardEntry> entries) { if (entries == null) { public void onPullComplete() { if (mEntries == null) { Log.e(TAG, "onPullComplete entries is null."); return; } if (DBG) { Log.d(TAG, "onPullComplete with " + entries.size() + " count."); Log.d(TAG, "onPullComplete with " + mEntries.size() + " count."); } int type; try { Loading @@ -70,13 +70,8 @@ public class CallLogPullRequest extends PullRequest { return; } if (entries == null) { // Nothing to do. Return. return; } ArrayList<ContentProviderOperation> ops = new ArrayList<>(); for (VCardEntry vcard : entries) { for (VCardEntry vcard : mEntries) { List<PhoneData> phones = vcard.getPhoneList(); if (phones == null || phones.size() != 1) { Log.d(TAG, "Incorrect number of phones: " + vcard); Loading src/com/android/bluetooth/pbapclient/PbapPCEClient.java +133 −120 Original line number Diff line number Diff line Loading @@ -27,7 +27,11 @@ import android.content.Intent; import android.os.AsyncTask; import android.os.Bundle; import android.os.Handler; import android.os.HandlerThread; import android.os.IBinder; import android.os.Looper; import android.os.Message; import android.os.Process; import android.net.Uri; import android.provider.CallLog; import android.provider.ContactsContract; Loading @@ -42,8 +46,7 @@ import java.util.ArrayDeque; import java.util.ArrayList; import java.util.List; import java.util.Queue; import java.util.concurrent.atomic.AtomicBoolean; import java.lang.InterruptedException; import java.lang.Thread; /** * These are the possible paths that can be pulled: Loading @@ -58,26 +61,29 @@ import java.lang.Thread; */ public class PbapPCEClient implements PbapHandler.PbapListener { private static final String TAG = "PbapPCEClient"; private static final boolean DBG = false; private static final boolean DBG = true; private final Queue<PullRequest> mPendingRequests = new ArrayDeque<PullRequest>(); private final AtomicBoolean mPendingPull = new AtomicBoolean(false); private BluetoothDevice mDevice; private BluetoothPbapClient mClient; private boolean mClientConnected = false; private PbapHandler mHandler; private Handler mSelfHandler; private PullRequest mLastPull; private HandlerThread mContactHandlerThread; private Handler mContactHandler; private Account mAccount = null; private Context mContext = null; private AccountManager mAccountManager; private DeleteCallLogTask mDeleteCallLogTask; PbapPCEClient(Context context) { mContext = context; mSelfHandler = new Handler(mContext.getMainLooper()); mHandler = new PbapHandler(this); mAccountManager = AccountManager.get(mContext); mContactHandlerThread = new HandlerThread("PBAP contact handler", Process.THREAD_PRIORITY_BACKGROUND); mContactHandlerThread.start(); mContactHandler = new ContactHandler(mContactHandlerThread.getLooper()); } public int getConnectionState() { Loading Loading @@ -109,46 +115,30 @@ public class PbapPCEClient implements PbapHandler.PbapListener { return mDevice; } private synchronized boolean maybePull() { if (DBG) { Log.d(TAG,"Attempting to Pull"); } if (!mClientConnected) { Log.w(TAG, "Client not connected yet -- will execute on next cycle."); return false; } return maybePullLocked(); } private boolean maybePullLocked() { private boolean processNextRequest() { if (DBG) { Log.d(TAG,"maybePullLocked()"); Log.d(TAG,"processNextRequest()"); } if (mPendingPull.compareAndSet(false, true)) { if (mPendingRequests.isEmpty()) { mPendingPull.set(false); return false; } if (mClient != null) { if (mClient != null && mClient.getState() == BluetoothPbapClient.ConnectionState.CONNECTED) { mLastPull = mPendingRequests.remove(); if (DBG) { Log.d(TAG, "Pulling phone book from: " + mLastPull.path); } return mClient.pullPhoneBook(mLastPull.path); } } return false; } private void pullComplete() { mPendingPull.set(false); maybePull(); } @Override public void onPhoneBookPullDone(List<VCardEntry> entries) { mLastPull.onPullComplete(true, entries); pullComplete(); mLastPull.setResults(entries); mContactHandler.obtainMessage(ContactHandler.EVENT_ADD_CONTACTS,mLastPull).sendToTarget(); processNextRequest(); } @Override Loading @@ -156,8 +146,7 @@ public class PbapPCEClient implements PbapHandler.PbapListener { if (DBG) { Log.d(TAG, "Error, mLastPull = " + mLastPull); } mLastPull.onPullComplete(false, null); pullComplete(); processNextRequest(); } @Override Loading @@ -167,7 +156,9 @@ public class PbapPCEClient implements PbapHandler.PbapListener { // If we are disconnected then whatever the current device is we should simply clean up. handleDisconnect(null); } if (mClientConnected == true) maybePullLocked(); if (mClientConnected == true) { processNextRequest(); } } public void handleConnect(BluetoothDevice device) { Loading @@ -184,26 +175,15 @@ public class PbapPCEClient implements PbapHandler.PbapListener { Log.w(TAG, "Got a connected event for the same device. Ignoring!"); return; } resetState(); // Cancel any pending delete tasks that might race. if (mDeleteCallLogTask != null) { mDeleteCallLogTask.cancel(true); } mDeleteCallLogTask = new DeleteCallLogTask(); // Cleanup any existing accounts if we get a connected event but previous account state was // left hanging (such as unclean shutdown). removeUncleanAccounts(); // Update the device. mDevice = device; mClient = new BluetoothPbapClient(mDevice, mAccount, mHandler); mClient.connect(); // Add the account. This should give us a place to stash the data. addAccount(device.getAddress()); mAccount = new Account(device.getAddress(), mContext.getString(R.string.pbap_account_type)); mContactHandler.obtainMessage(ContactHandler.EVENT_ADD_ACCOUNT,mAccount).sendToTarget(); downloadPhoneBook(); downloadCallLogs(); mClient.connect(); } public void handleDisconnect(BluetoothDevice device) { Loading @@ -220,11 +200,6 @@ public class PbapPCEClient implements PbapHandler.PbapListener { " disconnecting device = " + device); return; } if (device != null) { removeAccount(mAccount); mAccount = null; } resetState(); } Loading @@ -235,52 +210,47 @@ public class PbapPCEClient implements PbapHandler.PbapListener { return; } // Device is NULL, we go on remove any unclean shutdown accounts. removeUncleanAccounts(); resetState(); mContactHandler.obtainMessage(ContactHandler.EVENT_CLEANUP).sendToTarget(); } private void resetState() { if (DBG) { Log.d(TAG,"resetState()"); } if (mClient != null) { // This should abort any inflight messages. mClient.disconnect(); } mClient = null; mClientConnected = false; if (mDeleteCallLogTask != null && mDeleteCallLogTask.getStatus() == AsyncTask.Status.PENDING) { mDeleteCallLogTask.execute(); } mContactHandler.removeCallbacksAndMessages(null); mContactHandlerThread.interrupt(); mContactHandler.obtainMessage(ContactHandler.EVENT_CLEANUP).sendToTarget(); mDevice = null; mAccount = null; mPendingRequests.clear(); if (DBG) { Log.d(TAG,"resetState Complete"); } private void removeUncleanAccounts() { // Find all accounts that match the type "pbap" and delete them. This section is // executed only if the device was shut down in an unclean state and contacts persisted. Account[] accounts = mAccountManager.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. removeAccount(acc); } } private void downloadCallLogs() { // Download Incoming Call Logs. CallLogPullRequest ichCallLog = new CallLogPullRequest(mContext, BluetoothPbapClient.ICH_PATH); CallLogPullRequest ichCallLog = new CallLogPullRequest(mContext, BluetoothPbapClient.ICH_PATH); addPullRequest(ichCallLog); // Downoad Outgoing Call Logs. CallLogPullRequest ochCallLog = new CallLogPullRequest(mContext, BluetoothPbapClient.OCH_PATH); CallLogPullRequest ochCallLog = new CallLogPullRequest(mContext, BluetoothPbapClient.OCH_PATH); addPullRequest(ochCallLog); // Downoad Missed Call Logs. CallLogPullRequest mchCallLog = new CallLogPullRequest(mContext, BluetoothPbapClient.MCH_PATH); CallLogPullRequest mchCallLog = new CallLogPullRequest(mContext, BluetoothPbapClient.MCH_PATH); addPullRequest(mchCallLog); } Loading @@ -290,24 +260,82 @@ public class PbapPCEClient implements PbapHandler.PbapListener { addPullRequest(pb); } private class DeleteCallLogTask extends AsyncTask<Void, Void, Void> { private void addPullRequest(PullRequest r) { if (DBG) { Log.d(TAG, "pull request mClient=" + mClient + " connected= " + mClientConnected + " mDevice=" + mDevice + " path= " + r.path); } if (mClient == null || mDevice == null) { // It seems we want to pull but the bt connection isn't up, fail it // immediately. Log.w(TAG, "aborting pull request."); return; } mPendingRequests.add(r); } private class ContactHandler extends Handler { public static final int EVENT_ADD_ACCOUNT = 1; public static final int EVENT_ADD_CONTACTS = 2; public static final int EVENT_CLEANUP = 3; public ContactHandler(Looper looper) { super(looper); } @Override protected Void doInBackground(Void... unused) { if (isCancelled()) { return null; public void handleMessage(Message msg) { if (DBG) { Log.d(TAG, "Contact Handler Message " + msg.what + " with " + msg.obj); } switch (msg.what) { case EVENT_ADD_ACCOUNT: if (msg.obj instanceof Account) { Account account = (Account) msg.obj; addAccount(account); } break; case EVENT_ADD_CONTACTS: if (msg.obj instanceof PullRequest) { PullRequest req = (PullRequest) msg.obj; req.onPullComplete(); } else { Log.w(TAG, "invalid Instance in contact handler"); } break; case EVENT_CLEANUP: Thread.currentThread().interrupted(); //clear state of interrupt. removeUncleanAccounts(); mContext.getContentResolver().delete(CallLog.Calls.CONTENT_URI, null, null); if (DBG) { Log.d(TAG, "Call logs deleted."); } return null; break; default: Log.e(TAG, "Unknown Request to Contact Handler"); break; } } private void removeUncleanAccounts() { // Find all accounts that match the type "pbap" and delete them. This section is // executed only if the device was shut down in an unclean state and contacts persisted. Account[] accounts = mAccountManager.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. removeAccount(acc); } } private boolean addAccount(String id) { mAccount = new Account(id, mContext.getString(R.string.pbap_account_type)); if (mAccountManager.addAccountExplicitly(mAccount, null, null)) { private boolean addAccount(Account account) { if (mAccountManager.addAccountExplicitly(account, null, null)) { if (DBG) { Log.d(TAG, "Added account " + mAccount); } Loading @@ -326,20 +354,5 @@ public class PbapPCEClient implements PbapHandler.PbapListener { Log.e(TAG, "Failed to remove account " + mAccount); return false; } public void addPullRequest(PullRequest r) { if (DBG) { Log.d(TAG, "pull request mClient=" + mClient + " connected= " + mClientConnected + " mDevice=" + mDevice + " path= " + r.path); } if (mClient == null || mDevice == null) { // It seems we want to pull but the bt connection isn't up, fail it // immediately. Log.w(TAG, "aborting pull request."); r.onPullComplete(false, null); return; } mPendingRequests.add(r); maybePull(); } } src/com/android/bluetooth/pbapclient/PhonebookPullRequest.java +11 −9 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import android.util.Log; import com.android.vcard.VCardEntry; import java.lang.InterruptedException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; Loading Loading @@ -119,9 +120,12 @@ public class PhonebookPullRequest extends PullRequest { } private void addContacts(List<PhonebookEntry> entries) throws RemoteException, OperationApplicationException { throws RemoteException, OperationApplicationException, InterruptedException { ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>(); for (PhonebookEntry e : entries) { if (Thread.currentThread().isInterrupted()) { throw new InterruptedException(); } int index = ops.size(); // Add an entry. ops.add(ContentProviderOperation.newInsert(RawContacts.CONTENT_URI) Loading Loading @@ -177,27 +181,23 @@ public class PhonebookPullRequest extends PullRequest { } @Override public void onPullComplete(boolean success, List<VCardEntry> entries) { if (entries == null) { public void onPullComplete() { if (mEntries == null) { Log.e(TAG, "onPullComplete entries is null."); return; } if (DBG) { Log.d(TAG, "onPullComplete with " + entries.size() + " count."); Log.d(TAG, "onPullComplete with " + mEntries.size() + " count."); } try { if (!success) { Log.e(TAG, "Pull finished with errors."); return; } HashMap<PhonebookEntry.Name, PhonebookEntry> contacts = fetchExistingContacts(); List<PhonebookEntry> contactsToAdd = new ArrayList<PhonebookEntry>(); List<PhonebookEntry> contactsToDelete = new ArrayList<PhonebookEntry>(); for (VCardEntry e : entries) { for (VCardEntry e : mEntries) { PhonebookEntry current = new PhonebookEntry(e); PhonebookEntry.Name key = current.name; Loading Loading @@ -229,6 +229,8 @@ public class PhonebookPullRequest extends PullRequest { + " delete=" + contactsToDelete.size()); } catch (OperationApplicationException | RemoteException | NumberFormatException e) { Log.d(TAG, "Got exception: ", e); } catch (InterruptedException e) { Log.d(TAG, "Interrupted durring insert."); } finally { complete = true; } Loading src/com/android/bluetooth/pbapclient/PullRequest.java +6 −1 Original line number Diff line number Diff line Loading @@ -21,11 +21,16 @@ import java.util.List; public abstract class PullRequest { public String path; public abstract void onPullComplete(boolean success, List<VCardEntry> entries); protected List<VCardEntry> mEntries; public abstract void onPullComplete(); @Override public String toString() { return "PullRequest: { path=" + path + " }"; } public void setResults(List<VCardEntry> results) { mEntries = results; } } Loading
src/com/android/bluetooth/pbapclient/CallLogPullRequest.java +4 −9 Original line number Diff line number Diff line Loading @@ -48,14 +48,14 @@ public class CallLogPullRequest extends PullRequest { } @Override public void onPullComplete(boolean success, List<VCardEntry> entries) { if (entries == null) { public void onPullComplete() { if (mEntries == null) { Log.e(TAG, "onPullComplete entries is null."); return; } if (DBG) { Log.d(TAG, "onPullComplete with " + entries.size() + " count."); Log.d(TAG, "onPullComplete with " + mEntries.size() + " count."); } int type; try { Loading @@ -70,13 +70,8 @@ public class CallLogPullRequest extends PullRequest { return; } if (entries == null) { // Nothing to do. Return. return; } ArrayList<ContentProviderOperation> ops = new ArrayList<>(); for (VCardEntry vcard : entries) { for (VCardEntry vcard : mEntries) { List<PhoneData> phones = vcard.getPhoneList(); if (phones == null || phones.size() != 1) { Log.d(TAG, "Incorrect number of phones: " + vcard); Loading
src/com/android/bluetooth/pbapclient/PbapPCEClient.java +133 −120 Original line number Diff line number Diff line Loading @@ -27,7 +27,11 @@ import android.content.Intent; import android.os.AsyncTask; import android.os.Bundle; import android.os.Handler; import android.os.HandlerThread; import android.os.IBinder; import android.os.Looper; import android.os.Message; import android.os.Process; import android.net.Uri; import android.provider.CallLog; import android.provider.ContactsContract; Loading @@ -42,8 +46,7 @@ import java.util.ArrayDeque; import java.util.ArrayList; import java.util.List; import java.util.Queue; import java.util.concurrent.atomic.AtomicBoolean; import java.lang.InterruptedException; import java.lang.Thread; /** * These are the possible paths that can be pulled: Loading @@ -58,26 +61,29 @@ import java.lang.Thread; */ public class PbapPCEClient implements PbapHandler.PbapListener { private static final String TAG = "PbapPCEClient"; private static final boolean DBG = false; private static final boolean DBG = true; private final Queue<PullRequest> mPendingRequests = new ArrayDeque<PullRequest>(); private final AtomicBoolean mPendingPull = new AtomicBoolean(false); private BluetoothDevice mDevice; private BluetoothPbapClient mClient; private boolean mClientConnected = false; private PbapHandler mHandler; private Handler mSelfHandler; private PullRequest mLastPull; private HandlerThread mContactHandlerThread; private Handler mContactHandler; private Account mAccount = null; private Context mContext = null; private AccountManager mAccountManager; private DeleteCallLogTask mDeleteCallLogTask; PbapPCEClient(Context context) { mContext = context; mSelfHandler = new Handler(mContext.getMainLooper()); mHandler = new PbapHandler(this); mAccountManager = AccountManager.get(mContext); mContactHandlerThread = new HandlerThread("PBAP contact handler", Process.THREAD_PRIORITY_BACKGROUND); mContactHandlerThread.start(); mContactHandler = new ContactHandler(mContactHandlerThread.getLooper()); } public int getConnectionState() { Loading Loading @@ -109,46 +115,30 @@ public class PbapPCEClient implements PbapHandler.PbapListener { return mDevice; } private synchronized boolean maybePull() { if (DBG) { Log.d(TAG,"Attempting to Pull"); } if (!mClientConnected) { Log.w(TAG, "Client not connected yet -- will execute on next cycle."); return false; } return maybePullLocked(); } private boolean maybePullLocked() { private boolean processNextRequest() { if (DBG) { Log.d(TAG,"maybePullLocked()"); Log.d(TAG,"processNextRequest()"); } if (mPendingPull.compareAndSet(false, true)) { if (mPendingRequests.isEmpty()) { mPendingPull.set(false); return false; } if (mClient != null) { if (mClient != null && mClient.getState() == BluetoothPbapClient.ConnectionState.CONNECTED) { mLastPull = mPendingRequests.remove(); if (DBG) { Log.d(TAG, "Pulling phone book from: " + mLastPull.path); } return mClient.pullPhoneBook(mLastPull.path); } } return false; } private void pullComplete() { mPendingPull.set(false); maybePull(); } @Override public void onPhoneBookPullDone(List<VCardEntry> entries) { mLastPull.onPullComplete(true, entries); pullComplete(); mLastPull.setResults(entries); mContactHandler.obtainMessage(ContactHandler.EVENT_ADD_CONTACTS,mLastPull).sendToTarget(); processNextRequest(); } @Override Loading @@ -156,8 +146,7 @@ public class PbapPCEClient implements PbapHandler.PbapListener { if (DBG) { Log.d(TAG, "Error, mLastPull = " + mLastPull); } mLastPull.onPullComplete(false, null); pullComplete(); processNextRequest(); } @Override Loading @@ -167,7 +156,9 @@ public class PbapPCEClient implements PbapHandler.PbapListener { // If we are disconnected then whatever the current device is we should simply clean up. handleDisconnect(null); } if (mClientConnected == true) maybePullLocked(); if (mClientConnected == true) { processNextRequest(); } } public void handleConnect(BluetoothDevice device) { Loading @@ -184,26 +175,15 @@ public class PbapPCEClient implements PbapHandler.PbapListener { Log.w(TAG, "Got a connected event for the same device. Ignoring!"); return; } resetState(); // Cancel any pending delete tasks that might race. if (mDeleteCallLogTask != null) { mDeleteCallLogTask.cancel(true); } mDeleteCallLogTask = new DeleteCallLogTask(); // Cleanup any existing accounts if we get a connected event but previous account state was // left hanging (such as unclean shutdown). removeUncleanAccounts(); // Update the device. mDevice = device; mClient = new BluetoothPbapClient(mDevice, mAccount, mHandler); mClient.connect(); // Add the account. This should give us a place to stash the data. addAccount(device.getAddress()); mAccount = new Account(device.getAddress(), mContext.getString(R.string.pbap_account_type)); mContactHandler.obtainMessage(ContactHandler.EVENT_ADD_ACCOUNT,mAccount).sendToTarget(); downloadPhoneBook(); downloadCallLogs(); mClient.connect(); } public void handleDisconnect(BluetoothDevice device) { Loading @@ -220,11 +200,6 @@ public class PbapPCEClient implements PbapHandler.PbapListener { " disconnecting device = " + device); return; } if (device != null) { removeAccount(mAccount); mAccount = null; } resetState(); } Loading @@ -235,52 +210,47 @@ public class PbapPCEClient implements PbapHandler.PbapListener { return; } // Device is NULL, we go on remove any unclean shutdown accounts. removeUncleanAccounts(); resetState(); mContactHandler.obtainMessage(ContactHandler.EVENT_CLEANUP).sendToTarget(); } private void resetState() { if (DBG) { Log.d(TAG,"resetState()"); } if (mClient != null) { // This should abort any inflight messages. mClient.disconnect(); } mClient = null; mClientConnected = false; if (mDeleteCallLogTask != null && mDeleteCallLogTask.getStatus() == AsyncTask.Status.PENDING) { mDeleteCallLogTask.execute(); } mContactHandler.removeCallbacksAndMessages(null); mContactHandlerThread.interrupt(); mContactHandler.obtainMessage(ContactHandler.EVENT_CLEANUP).sendToTarget(); mDevice = null; mAccount = null; mPendingRequests.clear(); if (DBG) { Log.d(TAG,"resetState Complete"); } private void removeUncleanAccounts() { // Find all accounts that match the type "pbap" and delete them. This section is // executed only if the device was shut down in an unclean state and contacts persisted. Account[] accounts = mAccountManager.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. removeAccount(acc); } } private void downloadCallLogs() { // Download Incoming Call Logs. CallLogPullRequest ichCallLog = new CallLogPullRequest(mContext, BluetoothPbapClient.ICH_PATH); CallLogPullRequest ichCallLog = new CallLogPullRequest(mContext, BluetoothPbapClient.ICH_PATH); addPullRequest(ichCallLog); // Downoad Outgoing Call Logs. CallLogPullRequest ochCallLog = new CallLogPullRequest(mContext, BluetoothPbapClient.OCH_PATH); CallLogPullRequest ochCallLog = new CallLogPullRequest(mContext, BluetoothPbapClient.OCH_PATH); addPullRequest(ochCallLog); // Downoad Missed Call Logs. CallLogPullRequest mchCallLog = new CallLogPullRequest(mContext, BluetoothPbapClient.MCH_PATH); CallLogPullRequest mchCallLog = new CallLogPullRequest(mContext, BluetoothPbapClient.MCH_PATH); addPullRequest(mchCallLog); } Loading @@ -290,24 +260,82 @@ public class PbapPCEClient implements PbapHandler.PbapListener { addPullRequest(pb); } private class DeleteCallLogTask extends AsyncTask<Void, Void, Void> { private void addPullRequest(PullRequest r) { if (DBG) { Log.d(TAG, "pull request mClient=" + mClient + " connected= " + mClientConnected + " mDevice=" + mDevice + " path= " + r.path); } if (mClient == null || mDevice == null) { // It seems we want to pull but the bt connection isn't up, fail it // immediately. Log.w(TAG, "aborting pull request."); return; } mPendingRequests.add(r); } private class ContactHandler extends Handler { public static final int EVENT_ADD_ACCOUNT = 1; public static final int EVENT_ADD_CONTACTS = 2; public static final int EVENT_CLEANUP = 3; public ContactHandler(Looper looper) { super(looper); } @Override protected Void doInBackground(Void... unused) { if (isCancelled()) { return null; public void handleMessage(Message msg) { if (DBG) { Log.d(TAG, "Contact Handler Message " + msg.what + " with " + msg.obj); } switch (msg.what) { case EVENT_ADD_ACCOUNT: if (msg.obj instanceof Account) { Account account = (Account) msg.obj; addAccount(account); } break; case EVENT_ADD_CONTACTS: if (msg.obj instanceof PullRequest) { PullRequest req = (PullRequest) msg.obj; req.onPullComplete(); } else { Log.w(TAG, "invalid Instance in contact handler"); } break; case EVENT_CLEANUP: Thread.currentThread().interrupted(); //clear state of interrupt. removeUncleanAccounts(); mContext.getContentResolver().delete(CallLog.Calls.CONTENT_URI, null, null); if (DBG) { Log.d(TAG, "Call logs deleted."); } return null; break; default: Log.e(TAG, "Unknown Request to Contact Handler"); break; } } private void removeUncleanAccounts() { // Find all accounts that match the type "pbap" and delete them. This section is // executed only if the device was shut down in an unclean state and contacts persisted. Account[] accounts = mAccountManager.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. removeAccount(acc); } } private boolean addAccount(String id) { mAccount = new Account(id, mContext.getString(R.string.pbap_account_type)); if (mAccountManager.addAccountExplicitly(mAccount, null, null)) { private boolean addAccount(Account account) { if (mAccountManager.addAccountExplicitly(account, null, null)) { if (DBG) { Log.d(TAG, "Added account " + mAccount); } Loading @@ -326,20 +354,5 @@ public class PbapPCEClient implements PbapHandler.PbapListener { Log.e(TAG, "Failed to remove account " + mAccount); return false; } public void addPullRequest(PullRequest r) { if (DBG) { Log.d(TAG, "pull request mClient=" + mClient + " connected= " + mClientConnected + " mDevice=" + mDevice + " path= " + r.path); } if (mClient == null || mDevice == null) { // It seems we want to pull but the bt connection isn't up, fail it // immediately. Log.w(TAG, "aborting pull request."); r.onPullComplete(false, null); return; } mPendingRequests.add(r); maybePull(); } }
src/com/android/bluetooth/pbapclient/PhonebookPullRequest.java +11 −9 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import android.util.Log; import com.android.vcard.VCardEntry; import java.lang.InterruptedException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; Loading Loading @@ -119,9 +120,12 @@ public class PhonebookPullRequest extends PullRequest { } private void addContacts(List<PhonebookEntry> entries) throws RemoteException, OperationApplicationException { throws RemoteException, OperationApplicationException, InterruptedException { ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>(); for (PhonebookEntry e : entries) { if (Thread.currentThread().isInterrupted()) { throw new InterruptedException(); } int index = ops.size(); // Add an entry. ops.add(ContentProviderOperation.newInsert(RawContacts.CONTENT_URI) Loading Loading @@ -177,27 +181,23 @@ public class PhonebookPullRequest extends PullRequest { } @Override public void onPullComplete(boolean success, List<VCardEntry> entries) { if (entries == null) { public void onPullComplete() { if (mEntries == null) { Log.e(TAG, "onPullComplete entries is null."); return; } if (DBG) { Log.d(TAG, "onPullComplete with " + entries.size() + " count."); Log.d(TAG, "onPullComplete with " + mEntries.size() + " count."); } try { if (!success) { Log.e(TAG, "Pull finished with errors."); return; } HashMap<PhonebookEntry.Name, PhonebookEntry> contacts = fetchExistingContacts(); List<PhonebookEntry> contactsToAdd = new ArrayList<PhonebookEntry>(); List<PhonebookEntry> contactsToDelete = new ArrayList<PhonebookEntry>(); for (VCardEntry e : entries) { for (VCardEntry e : mEntries) { PhonebookEntry current = new PhonebookEntry(e); PhonebookEntry.Name key = current.name; Loading Loading @@ -229,6 +229,8 @@ public class PhonebookPullRequest extends PullRequest { + " delete=" + contactsToDelete.size()); } catch (OperationApplicationException | RemoteException | NumberFormatException e) { Log.d(TAG, "Got exception: ", e); } catch (InterruptedException e) { Log.d(TAG, "Interrupted durring insert."); } finally { complete = true; } Loading
src/com/android/bluetooth/pbapclient/PullRequest.java +6 −1 Original line number Diff line number Diff line Loading @@ -21,11 +21,16 @@ import java.util.List; public abstract class PullRequest { public String path; public abstract void onPullComplete(boolean success, List<VCardEntry> entries); protected List<VCardEntry> mEntries; public abstract void onPullComplete(); @Override public String toString() { return "PullRequest: { path=" + path + " }"; } public void setResults(List<VCardEntry> results) { mEntries = results; } }