OSDN Git Service

PBAP client priority settings.
authorJoseph Pirozzo <pirozzoj@google.com>
Fri, 25 Mar 2016 23:34:34 +0000 (16:34 -0700)
committerJoseph Pirozzo <pirozzoj@google.com>
Wed, 30 Mar 2016 19:01:01 +0000 (12:01 -0700)
Implement get/setPriority for PbapClient such that the settings dialog
and connect at startup work appropriately.

Bug: 27642222
Change-Id: I9c02d4d08809c6cc4230c71031d880b3d09f0cc4

src/com/android/bluetooth/btservice/AdapterService.java
src/com/android/bluetooth/pbapclient/PbapClientService.java
src/com/android/bluetooth/pbapclient/PbapPCEClient.java

index 0d09fe0..769e5e9 100644 (file)
@@ -1701,12 +1701,14 @@ public class AdapterService extends Service {
      private void autoConnectPbapClient(){
          PbapClientService pbapClientService = PbapClientService.getPbapClientService();
          BluetoothDevice bondedDevices[] = getBondedDevices();
-         if ((bondedDevices == null) ||(pbapClientService == null)) {
+         if ((bondedDevices == null) || (pbapClientService == null)) {
              return;
          }
          for (BluetoothDevice device : bondedDevices) {
-             debugLog("autoConnectPbapClient() - Connecting PBAP Client with " + device.toString());
-             pbapClientService.connect(device);
+             if (pbapClientService.getPriority(device) >= BluetoothProfile.PRIORITY_ON ){
+                 debugLog("autoConnectPbapClient() - Connecting PBAP Client with " + device.toString());
+                 pbapClientService.connect(device);
+             }
          }
     }
 
@@ -1763,16 +1765,6 @@ public class AdapterService extends Service {
         }
      }
 
-     private void adjustOtherSinkPriorities(A2dpService a2dpService,
-                                                BluetoothDevice connectedDevice) {
-         for (BluetoothDevice device : getBondedDevices()) {
-             if (a2dpService.getPriority(device) >= BluetoothProfile.PRIORITY_AUTO_CONNECT &&
-                 !device.equals(connectedDevice)) {
-                 a2dpService.setPriority(device, BluetoothProfile.PRIORITY_ON);
-             }
-         }
-     }
-
      void setProfileAutoConnectionPriority (BluetoothDevice device, int profileId){
          if (profileId == BluetoothProfile.HEADSET) {
              HeadsetService  hsService = HeadsetService.getHeadsetService();
index c16c70a..3ffdd83 100644 (file)
@@ -33,6 +33,7 @@ import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.Message;
 import android.os.RemoteException;
+import android.provider.Settings;
 import android.util.Log;
 import android.provider.ContactsContract;
 
@@ -42,6 +43,7 @@ import com.android.vcard.VCardEntry;
 
 
 import java.lang.ref.WeakReference;
+import java.util.Arrays;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.HashMap;
@@ -110,7 +112,7 @@ public class PbapClientService extends ProfileService {
         } catch (Exception e) {
             Log.w(TAG,"Unable to unregister sap receiver",e);
         }
-        mClient.handleDisconnect(null);
+        mClient.disconnect(null);
         return true;
     }
 
@@ -127,20 +129,16 @@ public class PbapClientService extends ProfileService {
             String action = intent.getAction();
             if (action.equals(BluetoothDevice.ACTION_ACL_CONNECTED)) {
                   BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
-                  connect(device);
-            }
-            else if (action.equals(BluetoothDevice.ACTION_ACL_DISCONNECTED)) {
+                  if(getPriority(device) >= BluetoothProfile.PRIORITY_ON) {
+                      connect(device);
+                  }
+            } else if (action.equals(BluetoothDevice.ACTION_ACL_DISCONNECTED)) {
                 BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                 disconnect(device);
             }
         }
     }
 
-
-
-
-
-
     /**
      * Handler for incoming service calls
      */
@@ -213,6 +211,24 @@ public class PbapClientService extends ProfileService {
             }
             return service.getConnectionState(device);
         }
+
+        public boolean setPriority(BluetoothDevice device, int priority) {
+            PbapClientService service = getService();
+            if (service == null) {
+                return false;
+            }
+            return service.setPriority(device, priority);
+        }
+
+        public int getPriority(BluetoothDevice device) {
+            PbapClientService service = getService();
+            if (service == null) {
+                return BluetoothProfile.PRIORITY_UNDEFINED;
+            }
+            return service.getPriority(device);
+        }
+
+
     }
 
 
@@ -264,14 +280,17 @@ public class PbapClientService extends ProfileService {
                 connectionState == BluetoothProfile.STATE_CONNECTING) {
             return false;
         }
-        mClient.handleConnect(device);
-        return true;
+        if (getPriority(device)>BluetoothProfile.PRIORITY_OFF) {
+            mClient.connect(device);
+            return true;
+        }
+        return false;
     }
 
     boolean disconnect(BluetoothDevice device) {
         enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
                 "Need BLUETOOTH ADMIN permission");
-        mClient.handleDisconnect(device);
+        mClient.disconnect(device);
         return true;
     }
     public List<BluetoothDevice> getConnectedDevices() {
@@ -283,6 +302,7 @@ public class PbapClientService extends ProfileService {
     private List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
         enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
         int clientState = mClient.getConnectionState();
+        Log.d(TAG,"getDevicesMatchingConnectionStates " + Arrays.toString(states) + " == " + clientState);
         List<BluetoothDevice> deviceList = new ArrayList<BluetoothDevice>();
         for (int state : states) {
             if (clientState == state) {
@@ -302,4 +322,26 @@ public class PbapClientService extends ProfileService {
         }
         return BluetoothProfile.STATE_DISCONNECTED;
     }
+
+    public boolean setPriority(BluetoothDevice device, int priority) {
+        enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
+                "Need BLUETOOTH_ADMIN permission");
+        Settings.Global.putInt(getContentResolver(),
+                Settings.Global.getBluetoothPbapClientPriorityKey(device.getAddress()),
+                priority);
+        if (DBG) {
+            Log.d(TAG,"Saved priority " + device + " = " + priority);
+        }
+        return true;
+    }
+
+    public int getPriority(BluetoothDevice device) {
+        enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
+                "Need BLUETOOTH_ADMIN permission");
+        int priority = Settings.Global.getInt(getContentResolver(),
+                Settings.Global.getBluetoothPbapClientPriorityKey(device.getAddress()),
+                BluetoothProfile.PRIORITY_UNDEFINED);
+        return priority;
+    }
+
 }
index 7010aab..8c86023 100644 (file)
@@ -39,7 +39,7 @@ import android.util.Log;
 import android.util.Pair;
 
 import com.android.vcard.VCardEntry;
-import com.android.bluetooth.pbapclient.BluetoothPbapClient;
+import com.android.bluetooth.btservice.ProfileService;
 import com.android.bluetooth.R;
 
 import java.util.ArrayDeque;
@@ -67,7 +67,7 @@ public class PbapPCEClient  implements PbapHandler.PbapListener {
     private BluetoothPbapClient mClient;
     private boolean mClientConnected = false;
     private PbapHandler mHandler;
-    private Handler mSelfHandler;
+    private ConnectionHandler mConnectionHandler;
     private PullRequest mLastPull;
     private HandlerThread mContactHandlerThread;
     private Handler mContactHandler;
@@ -77,7 +77,7 @@ public class PbapPCEClient  implements PbapHandler.PbapListener {
 
     PbapPCEClient(Context context) {
         mContext = context;
-        mSelfHandler = new Handler(mContext.getMainLooper());
+        mConnectionHandler = new ConnectionHandler(mContext.getMainLooper());
         mHandler = new PbapHandler(this);
         mAccountManager = AccountManager.get(mContext);
         mContactHandlerThread = new HandlerThread("PBAP contact handler",
@@ -154,53 +154,131 @@ public class PbapPCEClient  implements PbapHandler.PbapListener {
         mClientConnected = status;
         if (mClientConnected == false) {
             // If we are disconnected then whatever the current device is we should simply clean up.
-            handleDisconnect(null);
+            onConnectionStateChanged(mDevice, BluetoothProfile.STATE_CONNECTING,
+                    BluetoothProfile.STATE_DISCONNECTED);
+            disconnect(null);
         }
         if (mClientConnected == true) {
+            onConnectionStateChanged(mDevice, BluetoothProfile.STATE_CONNECTING,
+                    BluetoothProfile.STATE_CONNECTED);
             processNextRequest();
         }
     }
 
-    public void handleConnect(BluetoothDevice device) {
-        if (device == null) {
-            throw new IllegalStateException(TAG + ":Connect with null device!");
-        } else if (mDevice != null && !mDevice.equals(device)) {
-            // Check that we are not already connected to an existing different device.
-            // Since the device can be connected to multiple external devices -- we use the honor
-            // protocol and only accept the first connecting device.
-            Log.e(TAG, ":Got a connected event when connected to a different device. " +
-                  "existing = " + mDevice + " new = " + device);
-            return;
-        } else if (device.equals(mDevice)) {
-            Log.w(TAG, "Got a connected event for the same device. Ignoring!");
-            return;
+    private class ConnectionHandler extends Handler {
+        public static final int EVENT_CONNECT = 1;
+        public static final int EVENT_DISCONNECT = 2;
+
+        public ConnectionHandler(Looper looper) {
+            super(looper);
         }
-        // Update the device.
-        mDevice = device;
-        mClient = new BluetoothPbapClient(mDevice, mAccount, mHandler);
-        // Add the account. This should give us a place to stash the data.
-        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) {
-        Log.w(TAG, "pbap disconnecting from = " + device);
+        @Override
+        public void handleMessage(Message msg) {
+            if (DBG) {
+                Log.d(TAG, "Connection Handler Message " + msg.what + " with " + msg.obj);
+            }
+            switch (msg.what) {
+                case EVENT_CONNECT:
+                    if (msg.obj instanceof BluetoothDevice) {
+                        BluetoothDevice device = (BluetoothDevice) msg.obj;
+                        int oldState = getConnectionState();
+                        if (oldState != BluetoothProfile.STATE_DISCONNECTED) {
+                            return;
+                        }
+                        onConnectionStateChanged(device, oldState,
+                                BluetoothProfile.STATE_CONNECTING);
+                        handleConnect(device);
+                    } else {
+                        Log.e(TAG, "Invalid instance in Connection Handler:Connect");
+                    }
+                    break;
 
-        if (device == null) {
-            // If we have a null device then disconnect the current device.
-            device = mDevice;
-        } else if (mDevice == null) {
-            Log.w(TAG, "No existing device connected to service - ignoring device = " + device);
-            return;
-        } else if (!mDevice.equals(device)) {
-            Log.w(TAG, "Existing device different from disconnected device. existing = " + mDevice +
-                       " disconnecting device = " + device);
-            return;
+                case EVENT_DISCONNECT:
+                    if (mDevice == null) {
+                        return;
+                    }
+                    if (msg.obj == null || msg.obj instanceof BluetoothDevice) {
+                        BluetoothDevice device = (BluetoothDevice) msg.obj;
+                        if (!mDevice.equals(device)) {
+                            return;
+                        }
+                        int oldState = getConnectionState();
+                        handleDisconnect(device);
+                        int newState = getConnectionState();
+                        if (device != null) {
+                            onConnectionStateChanged(device, oldState, newState);
+                        }
+                    } else {
+                        Log.e(TAG, "Invalid instance in Connection Handler:Disconnect");
+                    }
+                    break;
+
+                default:
+                    Log.e(TAG, "Unknown Request to Connection Handler");
+                    break;
+            }
+        }
+
+        private void handleConnect(BluetoothDevice device) {
+            if (device == null) {
+                throw new IllegalStateException(TAG + ":Connect with null device!");
+            } else if (mDevice != null && !mDevice.equals(device)) {
+                // Check that we are not already connected to an existing different device.
+                // Since the device can be connected to multiple external devices -- we use the honor
+                // protocol and only accept the first connecting device.
+                Log.e(TAG, ":Got a connected event when connected to a different device. " +
+                      "existing = " + mDevice + " new = " + device);
+                return;
+            } else if (device.equals(mDevice)) {
+                Log.w(TAG, "Got a connected event for the same device. Ignoring!");
+                return;
+            }
+            // Update the device.
+            mDevice = device;
+            mClient = new BluetoothPbapClient(mDevice, mAccount, mHandler);
+            // Add the account. This should give us a place to stash the data.
+            mAccount = new Account(device.getAddress(), mContext.getString(R.string.pbap_account_type));
+            mContactHandler.obtainMessage(ContactHandler.EVENT_ADD_ACCOUNT,mAccount).sendToTarget();
+            downloadPhoneBook();
+            downloadCallLogs();
+            mClient.connect();
+        }
+
+        private void handleDisconnect(BluetoothDevice device) {
+            Log.w(TAG, "pbap disconnecting from = " + device);
+
+            if (device == null) {
+                // If we have a null device then disconnect the current device.
+                device = mDevice;
+            } else if (mDevice == null) {
+                Log.w(TAG, "No existing device connected to service - ignoring device = " + device);
+                return;
+            } else if (!mDevice.equals(device)) {
+                Log.w(TAG, "Existing device different from disconnected device. existing = " + mDevice +
+                           " disconnecting device = " + device);
+                return;
+            }
+            resetState();
         }
-        resetState();
+    }
+
+    private void onConnectionStateChanged(BluetoothDevice device, int prevState, int state) {
+        Intent intent = new Intent(android.bluetooth.BluetoothPbapClient.ACTION_CONNECTION_STATE_CHANGED);
+        intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, prevState);
+        intent.putExtra(BluetoothProfile.EXTRA_STATE, state);
+        intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
+        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
+        mContext.sendBroadcast(intent, ProfileService.BLUETOOTH_PERM);
+        Log.d(TAG,"Connection state " + device + ": " + prevState + "->" + state);
+    }
+
+    public void connect(BluetoothDevice device) {
+        mConnectionHandler.obtainMessage(ConnectionHandler.EVENT_CONNECT,device).sendToTarget();
+    }
+
+    public void disconnect(BluetoothDevice device) {
+        mConnectionHandler.obtainMessage(ConnectionHandler.EVENT_DISCONNECT,device).sendToTarget();
     }
 
     public void start() {
@@ -293,6 +371,8 @@ public class PbapPCEClient  implements PbapHandler.PbapListener {
                     if (msg.obj instanceof Account) {
                         Account account = (Account) msg.obj;
                         addAccount(account);
+                    } else {
+                        Log.e(TAG, "invalid Instance in Contact Handler: Add Account");
                     }
                     break;
 
@@ -300,9 +380,8 @@ public class PbapPCEClient  implements PbapHandler.PbapListener {
                     if (msg.obj instanceof PullRequest) {
                         PullRequest req = (PullRequest) msg.obj;
                         req.onPullComplete();
-                    }
-                    else {
-                        Log.w(TAG, "invalid Instance in contact handler");
+                    } else {
+                        Log.e(TAG, "invalid Instance in Contact Handler: Add Contacts");
                     }
                     break;