Loading android/app/src/com/android/bluetooth/btservice/PhonePolicy.java +108 −72 Original line number Original line Diff line number Diff line Loading @@ -41,6 +41,7 @@ import com.android.bluetooth.hfp.HeadsetService; import com.android.bluetooth.pan.PanService; import com.android.bluetooth.pan.PanService; import com.android.internal.R; import com.android.internal.R; import java.util.HashSet; import java.util.List; import java.util.List; // Describes the phone policy // Describes the phone policy Loading Loading @@ -78,41 +79,53 @@ class PhonePolicy { final private static int MESSAGE_CONNECT_OTHER_PROFILES = 3; final private static int MESSAGE_CONNECT_OTHER_PROFILES = 3; final private static int MESSAGE_ADAPTER_STATE_TURNED_ON = 4; final private static int MESSAGE_ADAPTER_STATE_TURNED_ON = 4; public static final int PROFILE_CONN_CONNECTED = 1; // Timeouts // Timeouts final private static int CONNECT_OTHER_PROFILES_TIMEOUT = 6000; // 6s final private static int CONNECT_OTHER_PROFILES_TIMEOUT = 6000; // 6s final private AdapterService mAdapterService; final private AdapterService mAdapterService; final private ServiceFactory mFactory; final private ServiceFactory mFactory; final private Handler mHandler; final private Handler mHandler; final private HashSet<BluetoothDevice> mHeadsetRetrySet = new HashSet<>(); final private HashSet<BluetoothDevice> mA2dpRetrySet = new HashSet<>(); // Broadcast receiver for all changes to states of various profiles // Broadcast receiver for all changes to states of various profiles private final BroadcastReceiver mReceiver = new BroadcastReceiver() { private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override @Override public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) { Log.d(TAG, "Received intent " + intent); String action = intent.getAction(); if (BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED.equals(intent.getAction())) { if (action == null) { errorLog("Received intent with null action"); return; } switch (action) { case BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED: mHandler.obtainMessage(MESSAGE_PROFILE_CONNECTION_STATE_CHANGED, mHandler.obtainMessage(MESSAGE_PROFILE_CONNECTION_STATE_CHANGED, BluetoothProfile.HEADSET, BluetoothProfile.HEADSET, -1, // No-op argument -1, // No-op argument intent) intent) .sendToTarget(); .sendToTarget(); } else if (BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED.equals(intent.getAction())) { break; case BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED: mHandler.obtainMessage(MESSAGE_PROFILE_CONNECTION_STATE_CHANGED, mHandler.obtainMessage(MESSAGE_PROFILE_CONNECTION_STATE_CHANGED, BluetoothProfile.A2DP, BluetoothProfile.A2DP, -1, // No-op argument -1, // No-op argument intent) intent) .sendToTarget(); .sendToTarget(); } else if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(intent.getAction())) { break; case BluetoothAdapter.ACTION_STATE_CHANGED: // Only pass the message on if the adapter has actually changed state from // Only pass the message on if the adapter has actually changed state from // non-ON to ON. NOTE: ON is the state depicting BREDR ON and not just BLE ON. // non-ON to ON. NOTE: ON is the state depicting BREDR ON and not just BLE ON. int newState = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1); int newState = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1); if (newState == BluetoothAdapter.STATE_ON) { if (newState == BluetoothAdapter.STATE_ON) { mHandler.obtainMessage(MESSAGE_ADAPTER_STATE_TURNED_ON).sendToTarget(); mHandler.obtainMessage(MESSAGE_ADAPTER_STATE_TURNED_ON).sendToTarget(); } } } else if (BluetoothDevice.ACTION_UUID.equals(intent.getAction())) { break; case BluetoothDevice.ACTION_UUID: mHandler.obtainMessage(MESSAGE_PROFILE_INIT_PRIORITIES, intent).sendToTarget(); mHandler.obtainMessage(MESSAGE_PROFILE_INIT_PRIORITIES, intent).sendToTarget(); break; default: Log.e(TAG, "Received unexpected intent, action=" + action); break; } } } } }; }; Loading @@ -132,17 +145,16 @@ class PhonePolicy { public void handleMessage(Message msg) { public void handleMessage(Message msg) { switch (msg.what) { switch (msg.what) { case MESSAGE_PROFILE_INIT_PRIORITIES: { case MESSAGE_PROFILE_INIT_PRIORITIES: { Intent intent = (Intent) msg.obj; BluetoothDevice device = BluetoothDevice device = (BluetoothDevice) ((Intent) msg.obj) intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); .getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); Parcelable[] uuids = intent.getParcelableArrayExtra(BluetoothDevice.EXTRA_UUID); Parcelable[] uuids = debugLog("Received ACTION_UUID for device " + device); ((Intent) msg.obj).getParcelableArrayExtra(BluetoothDevice.EXTRA_UUID); Log.d(TAG, "UUIDs on ACTION_UUID: " + uuids + " for device " + device); if (uuids != null) { if (uuids != null) { ParcelUuid[] uuidsToSend = new ParcelUuid[uuids.length]; ParcelUuid[] uuidsToSend = new ParcelUuid[uuids.length]; for (int i = 0; i < uuidsToSend.length; i++) { for (int i = 0; i < uuidsToSend.length; i++) { uuidsToSend[i] = (ParcelUuid) uuids[i]; uuidsToSend[i] = (ParcelUuid) uuids[i]; debugLog("index=" + i + "uuid=" + uuidsToSend[i]); } } processInitProfilePriorities(device, uuidsToSend); processInitProfilePriorities(device, uuidsToSend); } } Loading @@ -165,6 +177,7 @@ class PhonePolicy { case MESSAGE_ADAPTER_STATE_TURNED_ON: case MESSAGE_ADAPTER_STATE_TURNED_ON: // Call auto connect when adapter switches state to ON // Call auto connect when adapter switches state to ON resetStates(); autoConnect(); autoConnect(); break; break; } } Loading @@ -182,6 +195,7 @@ class PhonePolicy { } } protected void cleanup() { protected void cleanup() { mAdapterService.unregisterReceiver(mReceiver); mAdapterService.unregisterReceiver(mReceiver); resetStates(); } } PhonePolicy(AdapterService service, ServiceFactory factory) { PhonePolicy(AdapterService service, ServiceFactory factory) { Loading @@ -192,7 +206,7 @@ class PhonePolicy { // Policy implementation, all functions MUST be private // Policy implementation, all functions MUST be private private void processInitProfilePriorities(BluetoothDevice device, ParcelUuid[] uuids) { private void processInitProfilePriorities(BluetoothDevice device, ParcelUuid[] uuids) { debugLog("processInitProfilePriorities() - device " + device + " UUIDs " + uuids); debugLog("processInitProfilePriorities() - device " + device); HidService hidService = mFactory.getHidService(); HidService hidService = mFactory.getHidService(); A2dpService a2dpService = mFactory.getA2dpService(); A2dpService a2dpService = mFactory.getA2dpService(); HeadsetService headsetService = mFactory.getHeadsetService(); HeadsetService headsetService = mFactory.getHeadsetService(); Loading Loading @@ -235,23 +249,35 @@ class PhonePolicy { private void processProfileStateChanged( private void processProfileStateChanged( BluetoothDevice device, int profileId, int nextState, int prevState) { BluetoothDevice device, int profileId, int nextState, int prevState) { // Profiles relevant to phones. debugLog("processProfileStateChanged, device=" + device + ", profile=" + profileId + ", " + prevState + " -> " + nextState); if (((profileId == BluetoothProfile.A2DP) || (profileId == BluetoothProfile.HEADSET)) if (((profileId == BluetoothProfile.A2DP) || (profileId == BluetoothProfile.HEADSET)) && (nextState == BluetoothProfile.STATE_CONNECTED)) { && (nextState == BluetoothProfile.STATE_CONNECTED)) { debugLog("Profile connected id: " + profileId switch (profileId) { + " Schedule missing profile connection if any"); case BluetoothProfile.A2DP: mA2dpRetrySet.remove(device); break; case BluetoothProfile.HEADSET: mHeadsetRetrySet.remove(device); break; } connectOtherProfile(device); connectOtherProfile(device); setProfileAutoConnectionPriority(device, profileId); setProfileAutoConnectionPriority(device, profileId); } } } } private void resetStates() { mHeadsetRetrySet.clear(); mA2dpRetrySet.clear(); } private void autoConnect() { private void autoConnect() { if (mAdapterService.getState() != BluetoothAdapter.STATE_ON) { if (mAdapterService.getState() != BluetoothAdapter.STATE_ON) { errorLog("autoConnect() - BT is not ON. Exiting autoConnect"); errorLog("autoConnect() - BT is not ON. Exiting autoConnect"); return; return; } } if (mAdapterService.isQuietModeEnabled() == false) { if (!mAdapterService.isQuietModeEnabled()) { debugLog("autoConnect() - Initiate auto connection on BT on..."); debugLog("autoConnect() - Initiate auto connection on BT on..."); // Phone profiles. // Phone profiles. autoConnectHeadset(); autoConnectHeadset(); Loading @@ -262,45 +288,48 @@ class PhonePolicy { } } private void autoConnectHeadset() { private void autoConnectHeadset() { HeadsetService hsService = mFactory.getHeadsetService(); final HeadsetService hsService = mFactory.getHeadsetService(); if (hsService == null) { if (hsService == null) { errorLog("autoConnectHeadset() - service is null"); errorLog("autoConnectHeadset, service is null"); return; return; } } final BluetoothDevice bondedDevices[] = mAdapterService.getBondedDevices(); BluetoothDevice bondedDevices[] = mAdapterService.getBondedDevices(); if (bondedDevices == null) { if (bondedDevices == null) { errorLog("autoConnectHeadset() - devices are null"); errorLog("autoConnectHeadset, bondedDevices are null"); return; return; } } debugLog("autoConnectHeadset() - bondedDevices: " + bondedDevices); for (BluetoothDevice device : bondedDevices) { for (BluetoothDevice device : bondedDevices) { debugLog("autoConnectHeadset() - attempt autoconnect with device " + device); debugLog("autoConnectHeadset, attempt auto-connect with device " + device); if (hsService.getPriority(device) == BluetoothProfile.PRIORITY_AUTO_CONNECT) { if (hsService.getPriority(device) == BluetoothProfile.PRIORITY_AUTO_CONNECT) { debugLog("autoConnectHeadset() - Connecting HFP with " + device.toString()); debugLog("autoConnectHeadset, Connecting HFP with " + device); hsService.connect(device); hsService.connect(device); } } } } } } private void autoConnectA2dp() { private void autoConnectA2dp() { A2dpService a2dpSservice = mFactory.getA2dpService(); final A2dpService a2dpService = mFactory.getA2dpService(); BluetoothDevice bondedDevices[] = mAdapterService.getBondedDevices(); if (a2dpService == null) { if ((bondedDevices == null) || (a2dpSservice == null)) { errorLog("autoConnectA2dp, service is null"); return; } final BluetoothDevice bondedDevices[] = mAdapterService.getBondedDevices(); if (bondedDevices == null) { errorLog("autoConnectA2dp, bondedDevices are null"); return; return; } } for (BluetoothDevice device : bondedDevices) { for (BluetoothDevice device : bondedDevices) { if (a2dpSservice.getPriority(device) == BluetoothProfile.PRIORITY_AUTO_CONNECT) { debugLog("autoConnectA2dp, attempt auto-connect with device " + device); debugLog("autoConnectA2dp() - Connecting A2DP with " + device.toString()); if (a2dpService.getPriority(device) == BluetoothProfile.PRIORITY_AUTO_CONNECT) { a2dpSservice.connect(device); debugLog("autoConnectA2dp, connecting A2DP with " + device); a2dpService.connect(device); } } } } } } public void connectOtherProfile(BluetoothDevice device) { private void connectOtherProfile(BluetoothDevice device) { if ((mHandler.hasMessages(MESSAGE_CONNECT_OTHER_PROFILES) == false) if ((!mHandler.hasMessages(MESSAGE_CONNECT_OTHER_PROFILES)) && (mAdapterService.isQuietModeEnabled() == false)) { && (!mAdapterService.isQuietModeEnabled())) { Message m = mHandler.obtainMessage(MESSAGE_CONNECT_OTHER_PROFILES); Message m = mHandler.obtainMessage(MESSAGE_CONNECT_OTHER_PROFILES); m.obj = device; m.obj = device; mHandler.sendMessageDelayed(m, CONNECT_OTHER_PROFILES_TIMEOUT); mHandler.sendMessageDelayed(m, CONNECT_OTHER_PROFILES_TIMEOUT); Loading @@ -312,8 +341,9 @@ class PhonePolicy { // connect to the device that initiated the connection. In the event that this function is // connect to the device that initiated the connection. In the event that this function is // invoked and there are no current bluetooth connections no new profiles will be connected. // invoked and there are no current bluetooth connections no new profiles will be connected. private void processConnectOtherProfiles(BluetoothDevice device) { private void processConnectOtherProfiles(BluetoothDevice device) { debugLog("processConnectOtherProfiles() - device " + device); debugLog("processConnectOtherProfiles, device=" + device); if (mAdapterService.getState() != BluetoothAdapter.STATE_ON) { if (mAdapterService.getState() != BluetoothAdapter.STATE_ON) { warnLog("processConnectOtherProfiles, adapter is not ON " + mAdapterService.getState()); return; return; } } HeadsetService hsService = mFactory.getHeadsetService(); HeadsetService hsService = mFactory.getHeadsetService(); Loading @@ -338,29 +368,31 @@ class PhonePolicy { allProfilesEmpty = allProfilesEmpty && panConnDevList.isEmpty(); allProfilesEmpty = allProfilesEmpty && panConnDevList.isEmpty(); } } debugLog("processConnectOtherProfiles() - allProfilesEmpty " + allProfilesEmpty + " device " + device); if (allProfilesEmpty) { if (allProfilesEmpty) { // must have connected then disconnected, don't bother connecting others. // considered as fully disconnected, don't bother connecting others. debugLog("processConnectOtherProfiles, all profiles disconnected for " + device); // reset retry status so that in the next round we can start retrying connections again resetStates(); return; return; } } if (hsService != null) { if (hsService != null) { if (hsConnDevList.isEmpty() if (hsConnDevList.isEmpty() && !mHeadsetRetrySet.contains(device) && (hsService.getPriority(device) >= BluetoothProfile.PRIORITY_ON) && (hsService.getPriority(device) >= BluetoothProfile.PRIORITY_ON) && (hsService.getConnectionState(device) && (hsService.getConnectionState(device) == BluetoothProfile.STATE_DISCONNECTED)) { == BluetoothProfile.STATE_DISCONNECTED)) { debugLog("Retrying connection to HS with device " + device); debugLog("Retrying connection to Headset with device " + device); mHeadsetRetrySet.add(device); hsService.connect(device); hsService.connect(device); } } } } if (a2dpService != null) { if (a2dpService != null) { if (a2dpConnDevList.isEmpty() if (a2dpConnDevList.isEmpty() && !mA2dpRetrySet.contains(device) && (a2dpService.getPriority(device) >= BluetoothProfile.PRIORITY_ON) && (a2dpService.getPriority(device) >= BluetoothProfile.PRIORITY_ON) && (a2dpService.getConnectionState(device) && (a2dpService.getConnectionState(device) == BluetoothProfile.STATE_DISCONNECTED)) { == BluetoothProfile.STATE_DISCONNECTED)) { debugLog("Retrying connection to A2DP with device " + device); debugLog("Retrying connection to A2DP with device " + device); mA2dpRetrySet.add(device); a2dpService.connect(device); a2dpService.connect(device); } } } } Loading @@ -369,21 +401,13 @@ class PhonePolicy { && (panService.getPriority(device) >= BluetoothProfile.PRIORITY_ON) && (panService.getPriority(device) >= BluetoothProfile.PRIORITY_ON) && (panService.getConnectionState(device) && (panService.getConnectionState(device) == BluetoothProfile.STATE_DISCONNECTED)) { == BluetoothProfile.STATE_DISCONNECTED)) { debugLog("Retrying connection to HF with device " + device); debugLog("Retrying connection to PAN with device " + device); panService.connect(device); panService.connect(device); } } } } } } private void debugLog(String msg) { private void setProfileAutoConnectionPriority(BluetoothDevice device, int profileId) { if (DBG) Log.d(TAG, msg); } private void errorLog(String msg) { Log.e(TAG, msg); } void setProfileAutoConnectionPriority(BluetoothDevice device, int profileId) { switch (profileId) { switch (profileId) { case BluetoothProfile.HEADSET: case BluetoothProfile.HEADSET: HeadsetService hsService = mFactory.getHeadsetService(); HeadsetService hsService = mFactory.getHeadsetService(); Loading @@ -406,7 +430,7 @@ class PhonePolicy { break; break; default: default: Log.w(TAG, "Attempting to set Auto Connect priority on invalid profile"); Log.w(TAG, "Tried to set AutoConnect priority on invalid profile " + profileId); break; break; } } } } Loading @@ -430,4 +454,16 @@ class PhonePolicy { } } } } } } private static void debugLog(String msg) { if (DBG) Log.d(TAG, msg); } private static void warnLog(String msg) { Log.w(TAG, msg); } private static void errorLog(String msg) { Log.e(TAG, msg); } } } Loading
android/app/src/com/android/bluetooth/btservice/PhonePolicy.java +108 −72 Original line number Original line Diff line number Diff line Loading @@ -41,6 +41,7 @@ import com.android.bluetooth.hfp.HeadsetService; import com.android.bluetooth.pan.PanService; import com.android.bluetooth.pan.PanService; import com.android.internal.R; import com.android.internal.R; import java.util.HashSet; import java.util.List; import java.util.List; // Describes the phone policy // Describes the phone policy Loading Loading @@ -78,41 +79,53 @@ class PhonePolicy { final private static int MESSAGE_CONNECT_OTHER_PROFILES = 3; final private static int MESSAGE_CONNECT_OTHER_PROFILES = 3; final private static int MESSAGE_ADAPTER_STATE_TURNED_ON = 4; final private static int MESSAGE_ADAPTER_STATE_TURNED_ON = 4; public static final int PROFILE_CONN_CONNECTED = 1; // Timeouts // Timeouts final private static int CONNECT_OTHER_PROFILES_TIMEOUT = 6000; // 6s final private static int CONNECT_OTHER_PROFILES_TIMEOUT = 6000; // 6s final private AdapterService mAdapterService; final private AdapterService mAdapterService; final private ServiceFactory mFactory; final private ServiceFactory mFactory; final private Handler mHandler; final private Handler mHandler; final private HashSet<BluetoothDevice> mHeadsetRetrySet = new HashSet<>(); final private HashSet<BluetoothDevice> mA2dpRetrySet = new HashSet<>(); // Broadcast receiver for all changes to states of various profiles // Broadcast receiver for all changes to states of various profiles private final BroadcastReceiver mReceiver = new BroadcastReceiver() { private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override @Override public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) { Log.d(TAG, "Received intent " + intent); String action = intent.getAction(); if (BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED.equals(intent.getAction())) { if (action == null) { errorLog("Received intent with null action"); return; } switch (action) { case BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED: mHandler.obtainMessage(MESSAGE_PROFILE_CONNECTION_STATE_CHANGED, mHandler.obtainMessage(MESSAGE_PROFILE_CONNECTION_STATE_CHANGED, BluetoothProfile.HEADSET, BluetoothProfile.HEADSET, -1, // No-op argument -1, // No-op argument intent) intent) .sendToTarget(); .sendToTarget(); } else if (BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED.equals(intent.getAction())) { break; case BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED: mHandler.obtainMessage(MESSAGE_PROFILE_CONNECTION_STATE_CHANGED, mHandler.obtainMessage(MESSAGE_PROFILE_CONNECTION_STATE_CHANGED, BluetoothProfile.A2DP, BluetoothProfile.A2DP, -1, // No-op argument -1, // No-op argument intent) intent) .sendToTarget(); .sendToTarget(); } else if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(intent.getAction())) { break; case BluetoothAdapter.ACTION_STATE_CHANGED: // Only pass the message on if the adapter has actually changed state from // Only pass the message on if the adapter has actually changed state from // non-ON to ON. NOTE: ON is the state depicting BREDR ON and not just BLE ON. // non-ON to ON. NOTE: ON is the state depicting BREDR ON and not just BLE ON. int newState = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1); int newState = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1); if (newState == BluetoothAdapter.STATE_ON) { if (newState == BluetoothAdapter.STATE_ON) { mHandler.obtainMessage(MESSAGE_ADAPTER_STATE_TURNED_ON).sendToTarget(); mHandler.obtainMessage(MESSAGE_ADAPTER_STATE_TURNED_ON).sendToTarget(); } } } else if (BluetoothDevice.ACTION_UUID.equals(intent.getAction())) { break; case BluetoothDevice.ACTION_UUID: mHandler.obtainMessage(MESSAGE_PROFILE_INIT_PRIORITIES, intent).sendToTarget(); mHandler.obtainMessage(MESSAGE_PROFILE_INIT_PRIORITIES, intent).sendToTarget(); break; default: Log.e(TAG, "Received unexpected intent, action=" + action); break; } } } } }; }; Loading @@ -132,17 +145,16 @@ class PhonePolicy { public void handleMessage(Message msg) { public void handleMessage(Message msg) { switch (msg.what) { switch (msg.what) { case MESSAGE_PROFILE_INIT_PRIORITIES: { case MESSAGE_PROFILE_INIT_PRIORITIES: { Intent intent = (Intent) msg.obj; BluetoothDevice device = BluetoothDevice device = (BluetoothDevice) ((Intent) msg.obj) intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); .getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); Parcelable[] uuids = intent.getParcelableArrayExtra(BluetoothDevice.EXTRA_UUID); Parcelable[] uuids = debugLog("Received ACTION_UUID for device " + device); ((Intent) msg.obj).getParcelableArrayExtra(BluetoothDevice.EXTRA_UUID); Log.d(TAG, "UUIDs on ACTION_UUID: " + uuids + " for device " + device); if (uuids != null) { if (uuids != null) { ParcelUuid[] uuidsToSend = new ParcelUuid[uuids.length]; ParcelUuid[] uuidsToSend = new ParcelUuid[uuids.length]; for (int i = 0; i < uuidsToSend.length; i++) { for (int i = 0; i < uuidsToSend.length; i++) { uuidsToSend[i] = (ParcelUuid) uuids[i]; uuidsToSend[i] = (ParcelUuid) uuids[i]; debugLog("index=" + i + "uuid=" + uuidsToSend[i]); } } processInitProfilePriorities(device, uuidsToSend); processInitProfilePriorities(device, uuidsToSend); } } Loading @@ -165,6 +177,7 @@ class PhonePolicy { case MESSAGE_ADAPTER_STATE_TURNED_ON: case MESSAGE_ADAPTER_STATE_TURNED_ON: // Call auto connect when adapter switches state to ON // Call auto connect when adapter switches state to ON resetStates(); autoConnect(); autoConnect(); break; break; } } Loading @@ -182,6 +195,7 @@ class PhonePolicy { } } protected void cleanup() { protected void cleanup() { mAdapterService.unregisterReceiver(mReceiver); mAdapterService.unregisterReceiver(mReceiver); resetStates(); } } PhonePolicy(AdapterService service, ServiceFactory factory) { PhonePolicy(AdapterService service, ServiceFactory factory) { Loading @@ -192,7 +206,7 @@ class PhonePolicy { // Policy implementation, all functions MUST be private // Policy implementation, all functions MUST be private private void processInitProfilePriorities(BluetoothDevice device, ParcelUuid[] uuids) { private void processInitProfilePriorities(BluetoothDevice device, ParcelUuid[] uuids) { debugLog("processInitProfilePriorities() - device " + device + " UUIDs " + uuids); debugLog("processInitProfilePriorities() - device " + device); HidService hidService = mFactory.getHidService(); HidService hidService = mFactory.getHidService(); A2dpService a2dpService = mFactory.getA2dpService(); A2dpService a2dpService = mFactory.getA2dpService(); HeadsetService headsetService = mFactory.getHeadsetService(); HeadsetService headsetService = mFactory.getHeadsetService(); Loading Loading @@ -235,23 +249,35 @@ class PhonePolicy { private void processProfileStateChanged( private void processProfileStateChanged( BluetoothDevice device, int profileId, int nextState, int prevState) { BluetoothDevice device, int profileId, int nextState, int prevState) { // Profiles relevant to phones. debugLog("processProfileStateChanged, device=" + device + ", profile=" + profileId + ", " + prevState + " -> " + nextState); if (((profileId == BluetoothProfile.A2DP) || (profileId == BluetoothProfile.HEADSET)) if (((profileId == BluetoothProfile.A2DP) || (profileId == BluetoothProfile.HEADSET)) && (nextState == BluetoothProfile.STATE_CONNECTED)) { && (nextState == BluetoothProfile.STATE_CONNECTED)) { debugLog("Profile connected id: " + profileId switch (profileId) { + " Schedule missing profile connection if any"); case BluetoothProfile.A2DP: mA2dpRetrySet.remove(device); break; case BluetoothProfile.HEADSET: mHeadsetRetrySet.remove(device); break; } connectOtherProfile(device); connectOtherProfile(device); setProfileAutoConnectionPriority(device, profileId); setProfileAutoConnectionPriority(device, profileId); } } } } private void resetStates() { mHeadsetRetrySet.clear(); mA2dpRetrySet.clear(); } private void autoConnect() { private void autoConnect() { if (mAdapterService.getState() != BluetoothAdapter.STATE_ON) { if (mAdapterService.getState() != BluetoothAdapter.STATE_ON) { errorLog("autoConnect() - BT is not ON. Exiting autoConnect"); errorLog("autoConnect() - BT is not ON. Exiting autoConnect"); return; return; } } if (mAdapterService.isQuietModeEnabled() == false) { if (!mAdapterService.isQuietModeEnabled()) { debugLog("autoConnect() - Initiate auto connection on BT on..."); debugLog("autoConnect() - Initiate auto connection on BT on..."); // Phone profiles. // Phone profiles. autoConnectHeadset(); autoConnectHeadset(); Loading @@ -262,45 +288,48 @@ class PhonePolicy { } } private void autoConnectHeadset() { private void autoConnectHeadset() { HeadsetService hsService = mFactory.getHeadsetService(); final HeadsetService hsService = mFactory.getHeadsetService(); if (hsService == null) { if (hsService == null) { errorLog("autoConnectHeadset() - service is null"); errorLog("autoConnectHeadset, service is null"); return; return; } } final BluetoothDevice bondedDevices[] = mAdapterService.getBondedDevices(); BluetoothDevice bondedDevices[] = mAdapterService.getBondedDevices(); if (bondedDevices == null) { if (bondedDevices == null) { errorLog("autoConnectHeadset() - devices are null"); errorLog("autoConnectHeadset, bondedDevices are null"); return; return; } } debugLog("autoConnectHeadset() - bondedDevices: " + bondedDevices); for (BluetoothDevice device : bondedDevices) { for (BluetoothDevice device : bondedDevices) { debugLog("autoConnectHeadset() - attempt autoconnect with device " + device); debugLog("autoConnectHeadset, attempt auto-connect with device " + device); if (hsService.getPriority(device) == BluetoothProfile.PRIORITY_AUTO_CONNECT) { if (hsService.getPriority(device) == BluetoothProfile.PRIORITY_AUTO_CONNECT) { debugLog("autoConnectHeadset() - Connecting HFP with " + device.toString()); debugLog("autoConnectHeadset, Connecting HFP with " + device); hsService.connect(device); hsService.connect(device); } } } } } } private void autoConnectA2dp() { private void autoConnectA2dp() { A2dpService a2dpSservice = mFactory.getA2dpService(); final A2dpService a2dpService = mFactory.getA2dpService(); BluetoothDevice bondedDevices[] = mAdapterService.getBondedDevices(); if (a2dpService == null) { if ((bondedDevices == null) || (a2dpSservice == null)) { errorLog("autoConnectA2dp, service is null"); return; } final BluetoothDevice bondedDevices[] = mAdapterService.getBondedDevices(); if (bondedDevices == null) { errorLog("autoConnectA2dp, bondedDevices are null"); return; return; } } for (BluetoothDevice device : bondedDevices) { for (BluetoothDevice device : bondedDevices) { if (a2dpSservice.getPriority(device) == BluetoothProfile.PRIORITY_AUTO_CONNECT) { debugLog("autoConnectA2dp, attempt auto-connect with device " + device); debugLog("autoConnectA2dp() - Connecting A2DP with " + device.toString()); if (a2dpService.getPriority(device) == BluetoothProfile.PRIORITY_AUTO_CONNECT) { a2dpSservice.connect(device); debugLog("autoConnectA2dp, connecting A2DP with " + device); a2dpService.connect(device); } } } } } } public void connectOtherProfile(BluetoothDevice device) { private void connectOtherProfile(BluetoothDevice device) { if ((mHandler.hasMessages(MESSAGE_CONNECT_OTHER_PROFILES) == false) if ((!mHandler.hasMessages(MESSAGE_CONNECT_OTHER_PROFILES)) && (mAdapterService.isQuietModeEnabled() == false)) { && (!mAdapterService.isQuietModeEnabled())) { Message m = mHandler.obtainMessage(MESSAGE_CONNECT_OTHER_PROFILES); Message m = mHandler.obtainMessage(MESSAGE_CONNECT_OTHER_PROFILES); m.obj = device; m.obj = device; mHandler.sendMessageDelayed(m, CONNECT_OTHER_PROFILES_TIMEOUT); mHandler.sendMessageDelayed(m, CONNECT_OTHER_PROFILES_TIMEOUT); Loading @@ -312,8 +341,9 @@ class PhonePolicy { // connect to the device that initiated the connection. In the event that this function is // connect to the device that initiated the connection. In the event that this function is // invoked and there are no current bluetooth connections no new profiles will be connected. // invoked and there are no current bluetooth connections no new profiles will be connected. private void processConnectOtherProfiles(BluetoothDevice device) { private void processConnectOtherProfiles(BluetoothDevice device) { debugLog("processConnectOtherProfiles() - device " + device); debugLog("processConnectOtherProfiles, device=" + device); if (mAdapterService.getState() != BluetoothAdapter.STATE_ON) { if (mAdapterService.getState() != BluetoothAdapter.STATE_ON) { warnLog("processConnectOtherProfiles, adapter is not ON " + mAdapterService.getState()); return; return; } } HeadsetService hsService = mFactory.getHeadsetService(); HeadsetService hsService = mFactory.getHeadsetService(); Loading @@ -338,29 +368,31 @@ class PhonePolicy { allProfilesEmpty = allProfilesEmpty && panConnDevList.isEmpty(); allProfilesEmpty = allProfilesEmpty && panConnDevList.isEmpty(); } } debugLog("processConnectOtherProfiles() - allProfilesEmpty " + allProfilesEmpty + " device " + device); if (allProfilesEmpty) { if (allProfilesEmpty) { // must have connected then disconnected, don't bother connecting others. // considered as fully disconnected, don't bother connecting others. debugLog("processConnectOtherProfiles, all profiles disconnected for " + device); // reset retry status so that in the next round we can start retrying connections again resetStates(); return; return; } } if (hsService != null) { if (hsService != null) { if (hsConnDevList.isEmpty() if (hsConnDevList.isEmpty() && !mHeadsetRetrySet.contains(device) && (hsService.getPriority(device) >= BluetoothProfile.PRIORITY_ON) && (hsService.getPriority(device) >= BluetoothProfile.PRIORITY_ON) && (hsService.getConnectionState(device) && (hsService.getConnectionState(device) == BluetoothProfile.STATE_DISCONNECTED)) { == BluetoothProfile.STATE_DISCONNECTED)) { debugLog("Retrying connection to HS with device " + device); debugLog("Retrying connection to Headset with device " + device); mHeadsetRetrySet.add(device); hsService.connect(device); hsService.connect(device); } } } } if (a2dpService != null) { if (a2dpService != null) { if (a2dpConnDevList.isEmpty() if (a2dpConnDevList.isEmpty() && !mA2dpRetrySet.contains(device) && (a2dpService.getPriority(device) >= BluetoothProfile.PRIORITY_ON) && (a2dpService.getPriority(device) >= BluetoothProfile.PRIORITY_ON) && (a2dpService.getConnectionState(device) && (a2dpService.getConnectionState(device) == BluetoothProfile.STATE_DISCONNECTED)) { == BluetoothProfile.STATE_DISCONNECTED)) { debugLog("Retrying connection to A2DP with device " + device); debugLog("Retrying connection to A2DP with device " + device); mA2dpRetrySet.add(device); a2dpService.connect(device); a2dpService.connect(device); } } } } Loading @@ -369,21 +401,13 @@ class PhonePolicy { && (panService.getPriority(device) >= BluetoothProfile.PRIORITY_ON) && (panService.getPriority(device) >= BluetoothProfile.PRIORITY_ON) && (panService.getConnectionState(device) && (panService.getConnectionState(device) == BluetoothProfile.STATE_DISCONNECTED)) { == BluetoothProfile.STATE_DISCONNECTED)) { debugLog("Retrying connection to HF with device " + device); debugLog("Retrying connection to PAN with device " + device); panService.connect(device); panService.connect(device); } } } } } } private void debugLog(String msg) { private void setProfileAutoConnectionPriority(BluetoothDevice device, int profileId) { if (DBG) Log.d(TAG, msg); } private void errorLog(String msg) { Log.e(TAG, msg); } void setProfileAutoConnectionPriority(BluetoothDevice device, int profileId) { switch (profileId) { switch (profileId) { case BluetoothProfile.HEADSET: case BluetoothProfile.HEADSET: HeadsetService hsService = mFactory.getHeadsetService(); HeadsetService hsService = mFactory.getHeadsetService(); Loading @@ -406,7 +430,7 @@ class PhonePolicy { break; break; default: default: Log.w(TAG, "Attempting to set Auto Connect priority on invalid profile"); Log.w(TAG, "Tried to set AutoConnect priority on invalid profile " + profileId); break; break; } } } } Loading @@ -430,4 +454,16 @@ class PhonePolicy { } } } } } } private static void debugLog(String msg) { if (DBG) Log.d(TAG, msg); } private static void warnLog(String msg) { Log.w(TAG, msg); } private static void errorLog(String msg) { Log.e(TAG, msg); } } }