Merge "MAP: Add MNS SDP Search during setNotificationRegistration."
diff --git a/src/com/android/bluetooth/map/BluetoothMapContentObserver.java b/src/com/android/bluetooth/map/BluetoothMapContentObserver.java
index cdd5317..335b728 100644
--- a/src/com/android/bluetooth/map/BluetoothMapContentObserver.java
+++ b/src/com/android/bluetooth/map/BluetoothMapContentObserver.java
@@ -327,6 +327,26 @@
}
}
+ public int getObserverRemoteFeatureMask() {
+ if (V) Log.v(TAG, "getObserverRemoteFeatureMask : " + mMapEventReportVersion
+ + " mMapSupportedFeatures: " + mMapSupportedFeatures);
+ return mMapSupportedFeatures;
+ }
+
+ public void setObserverRemoteFeatureMask(int remoteSupportedFeatures) {
+ mMapSupportedFeatures = remoteSupportedFeatures;
+ if ((BluetoothMapUtils.MAP_FEATURE_EXTENDED_EVENT_REPORT_11_BIT
+ & mMapSupportedFeatures) != 0) {
+ mMapEventReportVersion = BluetoothMapUtils.MAP_EVENT_REPORT_V11;
+ }
+ // Make sure support for all formats result in latest version returned
+ if ((BluetoothMapUtils.MAP_FEATURE_EVENT_REPORT_V12_BIT
+ & mMapSupportedFeatures) != 0) {
+ mMapEventReportVersion = BluetoothMapUtils.MAP_EVENT_REPORT_V12;
+ }
+ if (V) Log.d(TAG, "setObserverRemoteFeatureMask : " + mMapEventReportVersion
+ + " mMapSupportedFeatures : " + mMapSupportedFeatures);
+ }
private Map<Long, Msg> getMsgListSms() {
return mMsgListSms;
@@ -865,28 +885,48 @@
public int setNotificationRegistration(int notificationStatus) throws RemoteException {
// Forward the request to the MNS thread as a message - including the MAS instance ID.
if(D) Log.d(TAG,"setNotificationRegistration() enter");
+ if (mMnsClient == null) {
+ return ResponseCodes.OBEX_HTTP_UNAVAILABLE;
+ }
Handler mns = mMnsClient.getMessageHandler();
- if(mns != null) {
+ if (mns != null) {
Message msg = mns.obtainMessage();
- msg.what = BluetoothMnsObexClient.MSG_MNS_NOTIFICATION_REGISTRATION;
+ if (mMnsClient.isValidMnsRecord()) {
+ msg.what = BluetoothMnsObexClient.MSG_MNS_NOTIFICATION_REGISTRATION;
+ } else {
+ //Trigger SDP Search and notificaiton registration , if SDP record not found.
+ msg.what = BluetoothMnsObexClient.MSG_MNS_SDP_SEARCH_REGISTRATION;
+ if (mMnsClient.mMnsLstRegRqst != null &&
+ (mMnsClient.mMnsLstRegRqst.isSearchInProgress())) {
+ /* 1. Disallow next Notification ON Request :
+ * - Respond "Service Unavailable" as SDP Search and last notification
+ * registration ON request is already InProgress.
+ * - Next notification ON Request will be allowed ONLY after search
+ * and connect for last saved request [Replied with OK ] is processed.
+ */
+ if (notificationStatus == BluetoothMapAppParams.NOTIFICATION_STATUS_YES) {
+ return ResponseCodes.OBEX_HTTP_UNAVAILABLE;
+ } else {
+ /* 2. Allow next Notification OFF Request:
+ * - Keep the SDP search still in progress.
+ * - Disconnect and Deregister the contentObserver.
+ */
+ msg.what = BluetoothMnsObexClient.MSG_MNS_NOTIFICATION_REGISTRATION;
+ }
+ }
+ }
msg.arg1 = mMasId;
msg.arg2 = notificationStatus;
mns.sendMessageDelayed(msg, 10); // Send message without forcing a context switch
/* Some devices - e.g. PTS needs to get the unregister confirm before we actually
* disconnect the MNS. */
- if(D) Log.d(TAG,"setNotificationRegistration() MSG_MNS_NOTIFICATION_REGISTRATION " +
- "send to MNS");
+ if(D) Log.d(TAG,"setNotificationRegistration() send : " + msg.what + " to MNS ");
+ return ResponseCodes.OBEX_HTTP_OK;
} else {
// This should not happen except at shutdown.
if(D) Log.d(TAG,"setNotificationRegistration() Unable to send registration request");
return ResponseCodes.OBEX_HTTP_UNAVAILABLE;
}
- if(notificationStatus == BluetoothMapAppParams.NOTIFICATION_STATUS_YES) {
- registerObserver();
- } else {
- unregisterObserver();
- }
- return ResponseCodes.OBEX_HTTP_OK;
}
boolean eventMaskContainsContacts(long mask) {
diff --git a/src/com/android/bluetooth/map/BluetoothMapMasInstance.java b/src/com/android/bluetooth/map/BluetoothMapMasInstance.java
index 66e6d3b..0da7292 100644
--- a/src/com/android/bluetooth/map/BluetoothMapMasInstance.java
+++ b/src/com/android/bluetooth/map/BluetoothMapMasInstance.java
@@ -434,8 +434,13 @@
}
}
- public void setRemoteFeatureMask(int supported_features) {
- mRemoteFeatureMask = supported_features;
+ public void setRemoteFeatureMask(int supportedFeatures) {
+ if(V) Log.v(TAG, "setRemoteFeatureMask : Curr: "+ mRemoteFeatureMask);
+ mRemoteFeatureMask = supportedFeatures;
+ if (mObserver != null) {
+ mObserver.setObserverRemoteFeatureMask(mRemoteFeatureMask);
+ if(V) Log.v(TAG, "setRemoteFeatureMask : set: " + mRemoteFeatureMask);
+ }
}
public int getRemoteFeatureMask(){
diff --git a/src/com/android/bluetooth/map/BluetoothMapService.java b/src/com/android/bluetooth/map/BluetoothMapService.java
old mode 100755
new mode 100644
index 04d7043..9cca2c7
--- a/src/com/android/bluetooth/map/BluetoothMapService.java
+++ b/src/com/android/bluetooth/map/BluetoothMapService.java
@@ -90,6 +90,10 @@
public static final int MSG_RELEASE_WAKE_LOCK = 5006;
+ public static final int MSG_MNS_SDP_SEARCH = 5007;
+
+ public static final int MSG_OBSERVER_REGISTRATION = 5008;
+
private static final String BLUETOOTH_PERM = android.Manifest.permission.BLUETOOTH;
private static final String BLUETOOTH_ADMIN_PERM = android.Manifest.permission.BLUETOOTH_ADMIN;
@@ -389,6 +393,30 @@
if (DEBUG) Log.d(TAG, " Released Wake Lock by message");
}
break;
+ case MSG_MNS_SDP_SEARCH:
+ if (mRemoteDevice != null) {
+ if (DEBUG) Log.d(TAG,"MNS SDP Initiate Search ..");
+ mRemoteDevice.sdpSearch(BluetoothMnsObexClient.BLUETOOTH_UUID_OBEX_MNS);
+ } else {
+ Log.w(TAG, "remoteDevice info not available");
+ }
+ break;
+ case MSG_OBSERVER_REGISTRATION:
+ if (DEBUG) Log.d(TAG,"ContentObserver Registration MASID: " + msg.arg1
+ + " Enable: " + msg.arg2);
+ BluetoothMapMasInstance masInst = mMasInstances.get(msg.arg1);
+ if (masInst != null) {
+ try {
+ if (msg.arg2 == BluetoothMapAppParams.NOTIFICATION_STATUS_YES) {
+ masInst.mObserver.registerObserver();
+ } else {
+ masInst.mObserver.unregisterObserver();
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG,"ContentObserverRegistarion Failed: "+ e);
+ }
+ }
+ break;
default:
break;
}
@@ -965,31 +993,34 @@
}
sendConnectCancelMessage();
}
- } else if (action.equals(BluetoothDevice.ACTION_SDP_RECORD)){
-// Log.v(TAG, "Received ACTION_SDP_RECORD.");
+ } else if (action.equals(BluetoothDevice.ACTION_SDP_RECORD)) {
+ if (DEBUG) Log.d(TAG, "Received ACTION_SDP_RECORD.");
ParcelUuid uuid = intent.getParcelableExtra(BluetoothDevice.EXTRA_UUID);
if (VERBOSE) {
Log.v(TAG, "Received UUID: " + uuid.toString());
Log.v(TAG, "expected UUID: " +
BluetoothMnsObexClient.BLUETOOTH_UUID_OBEX_MNS.toString());
}
- if(uuid.equals(BluetoothMnsObexClient.BLUETOOTH_UUID_OBEX_MNS)
- && mSdpSearchInitiated)
- {
+ if (uuid.equals(BluetoothMnsObexClient.BLUETOOTH_UUID_OBEX_MNS)) {
mMnsRecord = intent.getParcelableExtra(BluetoothDevice.EXTRA_SDP_RECORD);
int status = intent.getIntExtra(BluetoothDevice.EXTRA_SDP_SEARCH_STATUS, -1);
if (VERBOSE) {
Log.v(TAG, " -> MNS Record:" + mMnsRecord);
Log.v(TAG, " -> status: " + status);
}
- mSdpSearchInitiated = false; // done searching
- if(status != -1 && mMnsRecord != null){
- for(int i=0, c=mMasInstances.size(); i < c; i++) {
+ if (mBluetoothMnsObexClient != null && !mSdpSearchInitiated) {
+ mBluetoothMnsObexClient.setMnsRecord(mMnsRecord);
+ }
+ if (status != -1 && mMnsRecord != null) {
+ for (int i = 0, c = mMasInstances.size(); i < c; i++) {
mMasInstances.valueAt(i).setRemoteFeatureMask(
mMnsRecord.getSupportedFeatures());
}
}
- sendConnectMessage(-1); // -1 indicates all MAS instances
+ if (mSdpSearchInitiated) {
+ mSdpSearchInitiated = false; // done searching
+ sendConnectMessage(-1); // -1 indicates all MAS instances
+ }
}
} else if (action.equals(ACTION_SHOW_MAPS_SETTINGS)) {
if (VERBOSE) Log.v(TAG, "Received ACTION_SHOW_MAPS_SETTINGS.");
diff --git a/src/com/android/bluetooth/map/BluetoothMnsObexClient.java b/src/com/android/bluetooth/map/BluetoothMnsObexClient.java
index 39aa873..2558641 100644
--- a/src/com/android/bluetooth/map/BluetoothMnsObexClient.java
+++ b/src/com/android/bluetooth/map/BluetoothMnsObexClient.java
@@ -60,12 +60,16 @@
private HeaderSet mHsConnect = null;
private Handler mCallback = null;
- private final SdpMnsRecord mMnsRecord;
+ private SdpMnsRecord mMnsRecord;
// Used by the MAS to forward notification registrations
public static final int MSG_MNS_NOTIFICATION_REGISTRATION = 1;
public static final int MSG_MNS_SEND_EVENT = 2;
+ public static final int MSG_MNS_SDP_SEARCH_REGISTRATION = 3;
-
+ //Copy SdpManager.SDP_INTENT_DELAY - The timeout to wait for reply from native.
+ private final int MNS_SDP_SEARCH_DELAY = 6000;
+ public MnsSdpSearchInfo mMnsLstRegRqst = null;
+ private static final int MNS_NOTIFICATION_DELAY = 10;
public static final ParcelUuid BLUETOOTH_UUID_OBEX_MNS =
ParcelUuid.fromString("00001133-0000-1000-8000-00805F9B34FB");
@@ -90,6 +94,26 @@
return mHandler;
}
+ class MnsSdpSearchInfo {
+ private boolean isSearchInProgress;
+ int lastMasId;
+ int lastNotificationStatus;
+
+ MnsSdpSearchInfo (boolean isSearchON, int masId, int notification) {
+ isSearchInProgress = isSearchON;
+ lastMasId = masId;
+ lastNotificationStatus = notification;
+ }
+
+ public boolean isSearchInProgress() {
+ return isSearchInProgress;
+ }
+
+ public void setIsSearchInProgress(boolean isSearchON) {
+ isSearchInProgress = isSearchON;
+ }
+ }
+
private final class MnsObexClientHandler extends Handler {
private MnsObexClientHandler(Looper looper) {
super(looper);
@@ -99,11 +123,29 @@
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_MNS_NOTIFICATION_REGISTRATION:
- handleRegistration(msg.arg1 /*masId*/, msg.arg2 /*status*/);
+ if (V) Log.v(TAG, "Reg masId: " + msg.arg1 + " notfStatus: " + msg.arg2);
+ if (isValidMnsRecord()) {
+ handleRegistration(msg.arg1 /*masId*/, msg.arg2 /*status*/);
+ } else {
+ //Should not happen
+ if (D) Log.d(TAG, "MNS SDP info not available yet - Cannot Connect.");
+ }
break;
case MSG_MNS_SEND_EVENT:
sendEventHandler((byte[])msg.obj/*byte[]*/, msg.arg1 /*masId*/);
break;
+ case MSG_MNS_SDP_SEARCH_REGISTRATION:
+ //Initiate SDP Search
+ notifyMnsSdpSearch();
+ //Save the mns search info
+ mMnsLstRegRqst = new MnsSdpSearchInfo(true, msg.arg1, msg.arg2);
+ //Handle notification registration.
+ Message msgReg =
+ mHandler.obtainMessage(MSG_MNS_NOTIFICATION_REGISTRATION,
+ msg.arg1, msg.arg2);
+ if (V) Log.v(TAG, "SearchReg masId: " + msg.arg1 + " notfStatus: " + msg.arg2);
+ mHandler.sendMessageDelayed(msgReg, MNS_SDP_SEARCH_DELAY);
+ break;
default:
break;
}
@@ -180,24 +222,80 @@
*/
public synchronized void handleRegistration(int masId, int notificationStatus){
if(D) Log.d(TAG, "handleRegistration( " + masId + ", " + notificationStatus + ")");
-
- if(notificationStatus == BluetoothMapAppParams.NOTIFICATION_STATUS_NO) {
+ boolean sendObserverRegistration = true;
+ if (notificationStatus == BluetoothMapAppParams.NOTIFICATION_STATUS_NO) {
mRegisteredMasIds.delete(masId);
- } else if(notificationStatus == BluetoothMapAppParams.NOTIFICATION_STATUS_YES) {
+ if (mMnsLstRegRqst != null && mMnsLstRegRqst.lastMasId == masId) {
+ //Clear last saved MNSSdpSearchInfo , if Disconnect requested for same MasId.
+ mMnsLstRegRqst = null;
+ }
+ } else if (notificationStatus == BluetoothMapAppParams.NOTIFICATION_STATUS_YES) {
/* Connect if we do not have a connection, and start the content observers providing
* this thread as Handler.
*/
- if(isConnected() == false) {
+ if (isConnected() == false) {
if(D) Log.d(TAG, "handleRegistration: connect");
connect();
}
+ sendObserverRegistration = isConnected();
mRegisteredMasIds.put(masId, true); // We don't use the value for anything
+
+ // Clear last saved MNSSdpSearchInfo after connect is processed.
+ mMnsLstRegRqst = null;
}
- if(mRegisteredMasIds.size() == 0) {
+
+ if (mRegisteredMasIds.size() == 0) {
// No more registrations - disconnect
if(D) Log.d(TAG, "handleRegistration: disconnect");
disconnect();
}
+
+ //Register ContentObserver After connect/disconnect MNS channel.
+ if (V) Log.v(TAG, "Send registerObserver: " + sendObserverRegistration);
+ if (mCallback != null && sendObserverRegistration) {
+ Message msg = Message.obtain(mCallback);
+ msg.what = BluetoothMapService.MSG_OBSERVER_REGISTRATION;
+ msg.arg1 = masId;
+ msg.arg2 = notificationStatus;
+ msg.sendToTarget();
+ }
+ }
+
+ public boolean isValidMnsRecord() {
+ return (mMnsRecord != null);
+ }
+
+ public void setMnsRecord(SdpMnsRecord mnsRecord) {
+ if (V) Log.v(TAG, "setMNSRecord");
+ if (isValidMnsRecord()) {
+ Log.w(TAG,"MNS Record already available. Still update.");
+ }
+ mMnsRecord = mnsRecord;
+ if (mMnsLstRegRqst != null) {
+ //SDP Search completed.
+ mMnsLstRegRqst.setIsSearchInProgress(false);
+ if (mHandler.hasMessages(MSG_MNS_NOTIFICATION_REGISTRATION)) {
+ mHandler.removeMessages(MSG_MNS_NOTIFICATION_REGISTRATION);
+ //Search Result obtained within MNS_SDP_SEARCH_DELAY timeout
+ if (!isValidMnsRecord()) {
+ // SDP info still not available for last trial.
+ // Clear saved info.
+ mMnsLstRegRqst = null;
+ } else {
+ if (V) Log.v(TAG, "Handle registration for last saved request");
+ Message msgReg =
+ mHandler.obtainMessage(MSG_MNS_NOTIFICATION_REGISTRATION);
+ msgReg.arg1 = mMnsLstRegRqst.lastMasId;
+ msgReg.arg2 = mMnsLstRegRqst.lastNotificationStatus;
+ if (V) Log.v(TAG, "SearchReg masId: " + msgReg.arg1
+ + " notfStatus: " + msgReg.arg2);
+ //Handle notification registration.
+ mHandler.sendMessageDelayed(msgReg, MNS_NOTIFICATION_DELAY);
+ }
+ }
+ } else {
+ if (V) Log.v(TAG, "No last saved MNSSDPInfo to handle");
+ }
}
public void connect() {
@@ -207,11 +305,11 @@
BluetoothSocket btSocket = null;
try {
// TODO: Do SDP record search again?
- if(mMnsRecord != null && mMnsRecord.getL2capPsm() > 0) {
+ if (isValidMnsRecord() && mMnsRecord.getL2capPsm() > 0) {
// Do L2CAP connect
btSocket = mRemoteDevice.createL2capSocket(mMnsRecord.getL2capPsm());
- } else if (mMnsRecord != null && mMnsRecord.getRfcommChannelNumber() > 0) {
+ } else if (isValidMnsRecord() && mMnsRecord.getRfcommChannelNumber() > 0) {
// Do Rfcomm connect
btSocket = mRemoteDevice.createRfcommSocket(mMnsRecord.getRfcommChannelNumber());
} else {
@@ -280,6 +378,14 @@
notifyUpdateWakeLock();
}
+ private void notifyMnsSdpSearch() {
+ if (mCallback != null) {
+ Message msg = Message.obtain(mCallback);
+ msg.what = BluetoothMapService.MSG_MNS_SDP_SEARCH;
+ msg.sendToTarget();
+ }
+ }
+
private int sendEventHandler(byte[] eventBytes, int masInstanceId) {
boolean error = false;