Loading jni/com_android_bluetooth_sdp.cpp +33 −0 Original line number Diff line number Diff line Loading @@ -307,6 +307,37 @@ static jint sdpCreateMapMnsRecordNative(JNIEnv* env, jobject obj, return handle; } static jint sdpCreatePbapPceRecordNative(JNIEnv* env, jobject obj, jstring name_str, jint version) { ALOGD("%s", __func__); if (!sBluetoothSdpInterface) return -1; bluetooth_sdp_record record = {}; // Must be zero initialized record.pce.hdr.type = SDP_TYPE_PBAP_PCE; const char* service_name = NULL; if (name_str != NULL) { service_name = env->GetStringUTFChars(name_str, NULL); record.pce.hdr.service_name = (char*)service_name; record.pce.hdr.service_name_length = strlen(service_name); } else { record.pce.hdr.service_name = NULL; record.pce.hdr.service_name_length = 0; } record.pce.hdr.profile_version = version; int handle = -1; int ret = sBluetoothSdpInterface->create_sdp_record(&record, &handle); if (ret != BT_STATUS_SUCCESS) { ALOGE("SDP Create record failed: %d", ret); } else { ALOGD("SDP Create record success - handle: %d", handle); } if (service_name) env->ReleaseStringUTFChars(name_str, service_name); return handle; } static jint sdpCreatePbapPseRecordNative(JNIEnv* env, jobject obj, jstring name_str, jint scn, jint l2cap_psm, jint version, Loading Loading @@ -474,6 +505,8 @@ static JNINativeMethod sMethods[] = { (void*)sdpCreateMapMasRecordNative}, {"sdpCreateMapMnsRecordNative", "(Ljava/lang/String;IIII)I", (void*)sdpCreateMapMnsRecordNative}, {"sdpCreatePbapPceRecordNative", "(Ljava/lang/String;I)I", (void*)sdpCreatePbapPceRecordNative}, {"sdpCreatePbapPseRecordNative", "(Ljava/lang/String;IIIII)I", (void*)sdpCreatePbapPseRecordNative}, {"sdpCreateOppOpsRecordNative", "(Ljava/lang/String;III[B)I", Loading src/com/android/bluetooth/pbapclient/PbapClientConnectionHandler.java +1 −1 Original line number Diff line number Diff line Loading @@ -92,7 +92,6 @@ class PbapClientConnectionHandler extends Handler { private static final long PBAP_REQUESTED_FIELDS = PBAP_FILTER_VERSION | PBAP_FILTER_FN | PBAP_FILTER_N | PBAP_FILTER_PHOTO | PBAP_FILTER_ADR | PBAP_FILTER_EMAIL | PBAP_FILTER_TEL | PBAP_FILTER_NICKNAME; private static final int PBAP_V1_2 = 0x0102; private static final int L2CAP_INVALID_PSM = -1; public static final String PB_PATH = "telecom/pb.vcf"; Loading @@ -100,6 +99,7 @@ class PbapClientConnectionHandler extends Handler { public static final String ICH_PATH = "telecom/ich.vcf"; public static final String OCH_PATH = "telecom/och.vcf"; public static final int PBAP_V1_2 = 0x0102; public static final byte VCARD_TYPE_21 = 0; public static final byte VCARD_TYPE_30 = 1; Loading src/com/android/bluetooth/pbapclient/PbapClientService.java +37 −7 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ import android.util.Log; import com.android.bluetooth.R; import com.android.bluetooth.btservice.AdapterService; import com.android.bluetooth.btservice.ProfileService; import com.android.bluetooth.sdp.SdpManager; import java.util.ArrayList; import java.util.List; Loading @@ -47,12 +48,14 @@ public class PbapClientService extends ProfileService { private static final boolean VDBG = Utils.VDBG; private static final String TAG = "PbapClientService"; private static final String SERVICE_NAME = "Phonebook Access PCE"; // MAXIMUM_DEVICES set to 10 to prevent an excessive number of simultaneous devices. private static final int MAXIMUM_DEVICES = 10; private Map<BluetoothDevice, PbapClientStateMachine> mPbapClientStateMachineMap = new ConcurrentHashMap<>(); private static PbapClientService sPbapClientService; private PbapBroadcastReceiver mPbapBroadcastReceiver = new PbapBroadcastReceiver(); private int mSdpHandle = -1; @Override public IProfileServiceBinder initBinder() { Loading @@ -73,13 +76,17 @@ public class PbapClientService extends ProfileService { } catch (Exception e) { Log.w(TAG, "Unable to register pbapclient receiver", e); } removeUncleanAccounts(); registerSdpRecord(); setPbapClientService(this); return true; } @Override protected boolean stop() { setPbapClientService(null); cleanUpSdpRecord(); try { unregisterReceiver(mPbapBroadcastReceiver); } catch (Exception e) { Loading @@ -88,14 +95,8 @@ public class PbapClientService extends ProfileService { for (PbapClientStateMachine pbapClientStateMachine : mPbapClientStateMachineMap.values()) { pbapClientStateMachine.doQuit(); } return true; } @Override protected void cleanup() { removeUncleanAccounts(); // TODO: Should move to stop() setPbapClientService(null); return true; } void cleanupDevice(BluetoothDevice device) { Loading Loading @@ -127,6 +128,35 @@ public class PbapClientService extends ProfileService { } } private void registerSdpRecord() { SdpManager sdpManager = SdpManager.getDefaultManager(); if (sdpManager == null) { Log.e(TAG, "SdpManager is null"); return; } mSdpHandle = sdpManager.createPbapPceRecord(SERVICE_NAME, PbapClientConnectionHandler.PBAP_V1_2); } private void cleanUpSdpRecord() { if (mSdpHandle < 0) { Log.e(TAG, "cleanUpSdpRecord, SDP record never created"); return; } int sdpHandle = mSdpHandle; mSdpHandle = -1; SdpManager sdpManager = SdpManager.getDefaultManager(); if (sdpManager == null) { Log.e(TAG, "cleanUpSdpRecord failed, sdpManager is null, sdpHandle=" + sdpHandle); return; } Log.i(TAG, "cleanUpSdpRecord, mSdpHandle=" + sdpHandle); if (!sdpManager.removeSdpRecord(sdpHandle)) { Log.e(TAG, "cleanUpSdpRecord, removeSdpRecord failed, sdpHandle=" + sdpHandle); } } private class PbapBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Loading src/com/android/bluetooth/sdp/SdpManager.java +24 −0 Original line number Diff line number Diff line Loading @@ -85,6 +85,9 @@ public class SdpManager { private native int sdpCreateMapMnsRecordNative(String serviceName, int rfcommChannel, int l2capPsm, int version, int features); private native int sdpCreatePbapPceRecordNative(String serviceName, int version); private native int sdpCreatePbapPseRecordNative(String serviceName, int rfcommChannel, int l2capPsm, int version, int repositories, int features); Loading Loading @@ -537,6 +540,27 @@ public class SdpManager { return sdpCreateMapMnsRecordNative(serviceName, rfcommChannel, l2capPsm, version, features); } /** * Create a Client side Phone Book Access Profile Service Record. * Create the record once, and reuse it for all connections. * If changes to a record is needed remove the old record using {@link removeSdpRecord} * and then create a new one. * @param serviceName The textual name of the service * @param version The Profile version number (As specified in the Bluetooth * PBAP specification) * @return a handle to the record created. The record can be removed again * using {@link removeSdpRecord}(). The record is not linked to the * creation/destruction of BluetoothSockets, hence SDP record cleanup * is a separate process. */ public int createPbapPceRecord(String serviceName, int version) { if (!sNativeAvailable) { throw new RuntimeException(TAG + " sNativeAvailable == false - native not initialized"); } return sdpCreatePbapPceRecordNative(serviceName, version); } /** * Create a Server side Phone Book Access Profile Service Record. * Create the record once, and reuse it for all connections. Loading Loading
jni/com_android_bluetooth_sdp.cpp +33 −0 Original line number Diff line number Diff line Loading @@ -307,6 +307,37 @@ static jint sdpCreateMapMnsRecordNative(JNIEnv* env, jobject obj, return handle; } static jint sdpCreatePbapPceRecordNative(JNIEnv* env, jobject obj, jstring name_str, jint version) { ALOGD("%s", __func__); if (!sBluetoothSdpInterface) return -1; bluetooth_sdp_record record = {}; // Must be zero initialized record.pce.hdr.type = SDP_TYPE_PBAP_PCE; const char* service_name = NULL; if (name_str != NULL) { service_name = env->GetStringUTFChars(name_str, NULL); record.pce.hdr.service_name = (char*)service_name; record.pce.hdr.service_name_length = strlen(service_name); } else { record.pce.hdr.service_name = NULL; record.pce.hdr.service_name_length = 0; } record.pce.hdr.profile_version = version; int handle = -1; int ret = sBluetoothSdpInterface->create_sdp_record(&record, &handle); if (ret != BT_STATUS_SUCCESS) { ALOGE("SDP Create record failed: %d", ret); } else { ALOGD("SDP Create record success - handle: %d", handle); } if (service_name) env->ReleaseStringUTFChars(name_str, service_name); return handle; } static jint sdpCreatePbapPseRecordNative(JNIEnv* env, jobject obj, jstring name_str, jint scn, jint l2cap_psm, jint version, Loading Loading @@ -474,6 +505,8 @@ static JNINativeMethod sMethods[] = { (void*)sdpCreateMapMasRecordNative}, {"sdpCreateMapMnsRecordNative", "(Ljava/lang/String;IIII)I", (void*)sdpCreateMapMnsRecordNative}, {"sdpCreatePbapPceRecordNative", "(Ljava/lang/String;I)I", (void*)sdpCreatePbapPceRecordNative}, {"sdpCreatePbapPseRecordNative", "(Ljava/lang/String;IIIII)I", (void*)sdpCreatePbapPseRecordNative}, {"sdpCreateOppOpsRecordNative", "(Ljava/lang/String;III[B)I", Loading
src/com/android/bluetooth/pbapclient/PbapClientConnectionHandler.java +1 −1 Original line number Diff line number Diff line Loading @@ -92,7 +92,6 @@ class PbapClientConnectionHandler extends Handler { private static final long PBAP_REQUESTED_FIELDS = PBAP_FILTER_VERSION | PBAP_FILTER_FN | PBAP_FILTER_N | PBAP_FILTER_PHOTO | PBAP_FILTER_ADR | PBAP_FILTER_EMAIL | PBAP_FILTER_TEL | PBAP_FILTER_NICKNAME; private static final int PBAP_V1_2 = 0x0102; private static final int L2CAP_INVALID_PSM = -1; public static final String PB_PATH = "telecom/pb.vcf"; Loading @@ -100,6 +99,7 @@ class PbapClientConnectionHandler extends Handler { public static final String ICH_PATH = "telecom/ich.vcf"; public static final String OCH_PATH = "telecom/och.vcf"; public static final int PBAP_V1_2 = 0x0102; public static final byte VCARD_TYPE_21 = 0; public static final byte VCARD_TYPE_30 = 1; Loading
src/com/android/bluetooth/pbapclient/PbapClientService.java +37 −7 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ import android.util.Log; import com.android.bluetooth.R; import com.android.bluetooth.btservice.AdapterService; import com.android.bluetooth.btservice.ProfileService; import com.android.bluetooth.sdp.SdpManager; import java.util.ArrayList; import java.util.List; Loading @@ -47,12 +48,14 @@ public class PbapClientService extends ProfileService { private static final boolean VDBG = Utils.VDBG; private static final String TAG = "PbapClientService"; private static final String SERVICE_NAME = "Phonebook Access PCE"; // MAXIMUM_DEVICES set to 10 to prevent an excessive number of simultaneous devices. private static final int MAXIMUM_DEVICES = 10; private Map<BluetoothDevice, PbapClientStateMachine> mPbapClientStateMachineMap = new ConcurrentHashMap<>(); private static PbapClientService sPbapClientService; private PbapBroadcastReceiver mPbapBroadcastReceiver = new PbapBroadcastReceiver(); private int mSdpHandle = -1; @Override public IProfileServiceBinder initBinder() { Loading @@ -73,13 +76,17 @@ public class PbapClientService extends ProfileService { } catch (Exception e) { Log.w(TAG, "Unable to register pbapclient receiver", e); } removeUncleanAccounts(); registerSdpRecord(); setPbapClientService(this); return true; } @Override protected boolean stop() { setPbapClientService(null); cleanUpSdpRecord(); try { unregisterReceiver(mPbapBroadcastReceiver); } catch (Exception e) { Loading @@ -88,14 +95,8 @@ public class PbapClientService extends ProfileService { for (PbapClientStateMachine pbapClientStateMachine : mPbapClientStateMachineMap.values()) { pbapClientStateMachine.doQuit(); } return true; } @Override protected void cleanup() { removeUncleanAccounts(); // TODO: Should move to stop() setPbapClientService(null); return true; } void cleanupDevice(BluetoothDevice device) { Loading Loading @@ -127,6 +128,35 @@ public class PbapClientService extends ProfileService { } } private void registerSdpRecord() { SdpManager sdpManager = SdpManager.getDefaultManager(); if (sdpManager == null) { Log.e(TAG, "SdpManager is null"); return; } mSdpHandle = sdpManager.createPbapPceRecord(SERVICE_NAME, PbapClientConnectionHandler.PBAP_V1_2); } private void cleanUpSdpRecord() { if (mSdpHandle < 0) { Log.e(TAG, "cleanUpSdpRecord, SDP record never created"); return; } int sdpHandle = mSdpHandle; mSdpHandle = -1; SdpManager sdpManager = SdpManager.getDefaultManager(); if (sdpManager == null) { Log.e(TAG, "cleanUpSdpRecord failed, sdpManager is null, sdpHandle=" + sdpHandle); return; } Log.i(TAG, "cleanUpSdpRecord, mSdpHandle=" + sdpHandle); if (!sdpManager.removeSdpRecord(sdpHandle)) { Log.e(TAG, "cleanUpSdpRecord, removeSdpRecord failed, sdpHandle=" + sdpHandle); } } private class PbapBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Loading
src/com/android/bluetooth/sdp/SdpManager.java +24 −0 Original line number Diff line number Diff line Loading @@ -85,6 +85,9 @@ public class SdpManager { private native int sdpCreateMapMnsRecordNative(String serviceName, int rfcommChannel, int l2capPsm, int version, int features); private native int sdpCreatePbapPceRecordNative(String serviceName, int version); private native int sdpCreatePbapPseRecordNative(String serviceName, int rfcommChannel, int l2capPsm, int version, int repositories, int features); Loading Loading @@ -537,6 +540,27 @@ public class SdpManager { return sdpCreateMapMnsRecordNative(serviceName, rfcommChannel, l2capPsm, version, features); } /** * Create a Client side Phone Book Access Profile Service Record. * Create the record once, and reuse it for all connections. * If changes to a record is needed remove the old record using {@link removeSdpRecord} * and then create a new one. * @param serviceName The textual name of the service * @param version The Profile version number (As specified in the Bluetooth * PBAP specification) * @return a handle to the record created. The record can be removed again * using {@link removeSdpRecord}(). The record is not linked to the * creation/destruction of BluetoothSockets, hence SDP record cleanup * is a separate process. */ public int createPbapPceRecord(String serviceName, int version) { if (!sNativeAvailable) { throw new RuntimeException(TAG + " sNativeAvailable == false - native not initialized"); } return sdpCreatePbapPceRecordNative(serviceName, version); } /** * Create a Server side Phone Book Access Profile Service Record. * Create the record once, and reuse it for all connections. Loading