Loading src/com/android/bluetooth/pbap/BluetoothPbapObexServer.java +51 −14 Original line number Original line Diff line number Diff line Loading @@ -97,6 +97,7 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { private static final String[] LEGAL_PATH = { private static final String[] LEGAL_PATH = { "/telecom", "/telecom", "/telecom/pb", "/telecom/pb", "/telecom/fav", "/telecom/ich", "/telecom/ich", "/telecom/och", "/telecom/och", "/telecom/mch", "/telecom/mch", Loading @@ -106,6 +107,7 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { @SuppressWarnings("unused") private static final String[] LEGAL_PATH_WITH_SIM = { @SuppressWarnings("unused") private static final String[] LEGAL_PATH_WITH_SIM = { "/telecom", "/telecom", "/telecom/pb", "/telecom/pb", "/telecom/fav", "/telecom/ich", "/telecom/ich", "/telecom/och", "/telecom/och", "/telecom/mch", "/telecom/mch", Loading Loading @@ -138,6 +140,9 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { // phone book // phone book private static final String PB = "pb"; private static final String PB = "pb"; // favorites private static final String FAV = "fav"; private static final String TELECOM_PATH = "/telecom"; private static final String TELECOM_PATH = "/telecom"; private static final String ICH_PATH = "/telecom/ich"; private static final String ICH_PATH = "/telecom/ich"; Loading @@ -150,6 +155,8 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { private static final String PB_PATH = "/telecom/pb"; private static final String PB_PATH = "/telecom/pb"; private static final String FAV_PATH = "/telecom/fav"; // type for list vcard objects // type for list vcard objects private static final String TYPE_LISTING = "x-bt/vcard-listing"; private static final String TYPE_LISTING = "x-bt/vcard-listing"; Loading Loading @@ -212,6 +219,8 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { public static final int MISSED_CALL_HISTORY = 4; public static final int MISSED_CALL_HISTORY = 4; public static final int COMBINED_CALL_HISTORY = 5; public static final int COMBINED_CALL_HISTORY = 5; public static final int FAVORITES = 6; } } public BluetoothPbapObexServer(Handler callback, Context context, public BluetoothPbapObexServer(Handler callback, Context context, Loading Loading @@ -441,6 +450,8 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { if (mCurrentPath.equals(PB_PATH)) { if (mCurrentPath.equals(PB_PATH)) { appParamValue.needTag = ContentType.PHONEBOOK; appParamValue.needTag = ContentType.PHONEBOOK; } else if (mCurrentPath.equals(FAV_PATH)) { appParamValue.needTag = ContentType.FAVORITES; } else if (mCurrentPath.equals(ICH_PATH)) { } else if (mCurrentPath.equals(ICH_PATH)) { appParamValue.needTag = ContentType.INCOMING_CALL_HISTORY; appParamValue.needTag = ContentType.INCOMING_CALL_HISTORY; } else if (mCurrentPath.equals(OCH_PATH)) { } else if (mCurrentPath.equals(OCH_PATH)) { Loading Loading @@ -478,6 +489,11 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { if (D) { if (D) { Log.v(TAG, "download phonebook request"); Log.v(TAG, "download phonebook request"); } } } else if (isNameMatchTarget(name, FAV)) { appParamValue.needTag = ContentType.FAVORITES; if (D) { Log.v(TAG, "download favorites request"); } } else if (isNameMatchTarget(name, ICH)) { } else if (isNameMatchTarget(name, ICH)) { appParamValue.needTag = ContentType.INCOMING_CALL_HISTORY; appParamValue.needTag = ContentType.INCOMING_CALL_HISTORY; appParamValue.callHistoryVersionCounter = appParamValue.callHistoryVersionCounter = Loading Loading @@ -751,7 +767,8 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { result.append("<vCard-listing version=\"1.0\">"); result.append("<vCard-listing version=\"1.0\">"); // Phonebook listing request // Phonebook listing request if (appParamValue.needTag == ContentType.PHONEBOOK) { if ((appParamValue.needTag == ContentType.PHONEBOOK) || (appParamValue.needTag == ContentType.FAVORITES)) { String type = ""; String type = ""; if (appParamValue.searchAttr.equals("0")) { if (appParamValue.searchAttr.equals("0")) { type = "name"; type = "name"; Loading Loading @@ -948,7 +965,7 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { checkPbapFeatureSupport(mFolderVersionCounterbitMask); checkPbapFeatureSupport(mFolderVersionCounterbitMask); } } boolean needSendPhonebookVersionCounters = false; boolean needSendPhonebookVersionCounters = false; if (isNameMatchTarget(name, PB)) { if (isNameMatchTarget(name, PB) || isNameMatchTarget(name, FAV)) { needSendPhonebookVersionCounters = needSendPhonebookVersionCounters = checkPbapFeatureSupport(mFolderVersionCounterbitMask); checkPbapFeatureSupport(mFolderVersionCounterbitMask); } } Loading Loading @@ -1194,11 +1211,12 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { if (appParamValue.needTag == 0) { if (appParamValue.needTag == 0) { Log.w(TAG, "wrong path!"); Log.w(TAG, "wrong path!"); return ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE; return ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE; } else if (appParamValue.needTag == ContentType.PHONEBOOK) { } else if ((appParamValue.needTag == ContentType.PHONEBOOK) || (appParamValue.needTag == ContentType.FAVORITES)) { if (intIndex < 0 || intIndex >= size) { if (intIndex < 0 || intIndex >= size) { Log.w(TAG, "The requested vcard is not acceptable! name= " + name); Log.w(TAG, "The requested vcard is not acceptable! name= " + name); return ResponseCodes.OBEX_HTTP_NOT_FOUND; return ResponseCodes.OBEX_HTTP_NOT_FOUND; } else if (intIndex == 0) { } else if ((intIndex == 0) && (appParamValue.needTag == ContentType.PHONEBOOK)) { // For PB_PATH, 0.vcf is the phone number of this phone. // For PB_PATH, 0.vcf is the phone number of this phone. String ownerVcard = mVcardManager.getOwnerPhoneNumberVcard(vcard21, String ownerVcard = mVcardManager.getOwnerPhoneNumberVcard(vcard21, appParamValue.ignorefilter ? null : appParamValue.propertySelector); appParamValue.ignorefilter ? null : appParamValue.propertySelector); Loading Loading @@ -1254,30 +1272,49 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { int requestSize = int requestSize = pbSize >= appParamValue.maxListCount ? appParamValue.maxListCount : pbSize; pbSize >= appParamValue.maxListCount ? appParamValue.maxListCount : pbSize; int startPoint = appParamValue.listStartOffset; /** if (startPoint < 0 || startPoint >= pbSize) { * startIndex (resp., lastIndex) corresponds to the index of the first (resp., last) * vcard entry in the phonebook object. * PBAP v1.2.3: only pb starts indexing at 0.vcf (owner card), the other phonebook * objects (e.g., fav) start at 1.vcf. Additionally, the owner card is included in * pb's pbSize. This means pbSize corresponds to the index of the last vcf in the fav * phonebook object, but does not for the pb phonebook object. */ int startIndex = 1; int lastIndex = pbSize; if (appParamValue.needTag == BluetoothPbapObexServer.ContentType.PHONEBOOK) { startIndex = 0; lastIndex = pbSize - 1; } // [startPoint, endPoint] denote the range of vcf indices to send, inclusive. int startPoint = startIndex + appParamValue.listStartOffset; int endPoint = startPoint + requestSize - 1; if (appParamValue.listStartOffset < 0 || startPoint > lastIndex) { Log.w(TAG, "listStartOffset is not correct! " + startPoint); Log.w(TAG, "listStartOffset is not correct! " + startPoint); return ResponseCodes.OBEX_HTTP_OK; return ResponseCodes.OBEX_HTTP_OK; } } if (endPoint > lastIndex) { endPoint = lastIndex; } // Limit the number of call log to CALLLOG_NUM_LIMIT // Limit the number of call log to CALLLOG_NUM_LIMIT if (appParamValue.needTag != BluetoothPbapObexServer.ContentType.PHONEBOOK) { if ((appParamValue.needTag != BluetoothPbapObexServer.ContentType.PHONEBOOK) && (appParamValue.needTag != BluetoothPbapObexServer.ContentType.FAVORITES)) { if (requestSize > CALLLOG_NUM_LIMIT) { if (requestSize > CALLLOG_NUM_LIMIT) { requestSize = CALLLOG_NUM_LIMIT; requestSize = CALLLOG_NUM_LIMIT; } } } } int endPoint = startPoint + requestSize - 1; if (endPoint > pbSize - 1) { endPoint = pbSize - 1; } if (D) { if (D) { Log.d(TAG, "pullPhonebook(): requestSize=" + requestSize + " startPoint=" + startPoint Log.d(TAG, "pullPhonebook(): requestSize=" + requestSize + " startPoint=" + startPoint + " endPoint=" + endPoint); + " endPoint=" + endPoint); } } boolean vcard21 = appParamValue.vcard21; boolean vcard21 = appParamValue.vcard21; if (appParamValue.needTag == BluetoothPbapObexServer.ContentType.PHONEBOOK) { boolean favorites = (appParamValue.needTag == BluetoothPbapObexServer.ContentType.FAVORITES); if ((appParamValue.needTag == BluetoothPbapObexServer.ContentType.PHONEBOOK) || favorites) { if (startPoint == 0) { if (startPoint == 0) { String ownerVcard = mVcardManager.getOwnerPhoneNumberVcard(vcard21, String ownerVcard = mVcardManager.getOwnerPhoneNumberVcard(vcard21, appParamValue.ignorefilter ? null : appParamValue.propertySelector); appParamValue.ignorefilter ? null : appParamValue.propertySelector); Loading @@ -1287,13 +1324,13 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { return mVcardManager.composeAndSendPhonebookVcards(op, 1, endPoint, vcard21, return mVcardManager.composeAndSendPhonebookVcards(op, 1, endPoint, vcard21, ownerVcard, needSendBody, pbSize, appParamValue.ignorefilter, ownerVcard, needSendBody, pbSize, appParamValue.ignorefilter, appParamValue.propertySelector, appParamValue.vCardSelector, appParamValue.propertySelector, appParamValue.vCardSelector, appParamValue.vCardSelectorOperator, mVcardSelector); appParamValue.vCardSelectorOperator, mVcardSelector, favorites); } } } else { } else { return mVcardManager.composeAndSendPhonebookVcards(op, startPoint, endPoint, return mVcardManager.composeAndSendPhonebookVcards(op, startPoint, endPoint, vcard21, null, needSendBody, pbSize, appParamValue.ignorefilter, vcard21, null, needSendBody, pbSize, appParamValue.ignorefilter, appParamValue.propertySelector, appParamValue.vCardSelector, appParamValue.propertySelector, appParamValue.vCardSelector, appParamValue.vCardSelectorOperator, mVcardSelector); appParamValue.vCardSelectorOperator, mVcardSelector, favorites); } } } else { } else { return mVcardManager.composeAndSendSelectedCallLogVcards(appParamValue.needTag, op, return mVcardManager.composeAndSendSelectedCallLogVcards(appParamValue.needTag, op, Loading src/com/android/bluetooth/pbap/BluetoothPbapService.java +2 −1 Original line number Original line Diff line number Diff line Loading @@ -139,7 +139,8 @@ public class BluetoothPbapService extends ProfileService implements IObexConnect private ObexServerSockets mServerSockets = null; private ObexServerSockets mServerSockets = null; private static final int SDP_PBAP_SERVER_VERSION = 0x0102; private static final int SDP_PBAP_SERVER_VERSION = 0x0102; private static final int SDP_PBAP_SUPPORTED_REPOSITORIES = 0x0001; // PBAP v1.2.3, Sec. 7.1.2: local phonebook and favorites private static final int SDP_PBAP_SUPPORTED_REPOSITORIES = 0x0009; private static final int SDP_PBAP_SUPPORTED_FEATURES = 0x021F; private static final int SDP_PBAP_SUPPORTED_FEATURES = 0x021F; /* PBAP will use Bluetooth notification ID from 1000000 (included) to 2000000 (excluded). /* PBAP will use Bluetooth notification ID from 1000000 (included) to 2000000 (excluded). Loading src/com/android/bluetooth/pbap/BluetoothPbapVcardManager.java +29 −8 Original line number Original line Diff line number Diff line Loading @@ -153,7 +153,8 @@ public class BluetoothPbapVcardManager { int size; int size; switch (type) { switch (type) { case BluetoothPbapObexServer.ContentType.PHONEBOOK: case BluetoothPbapObexServer.ContentType.PHONEBOOK: size = getContactsSize(); case BluetoothPbapObexServer.ContentType.FAVORITES: size = getContactsSize(type); break; break; default: default: size = getCallHistorySize(type); size = getCallHistorySize(type); Loading @@ -165,16 +166,30 @@ public class BluetoothPbapVcardManager { return size; return size; } } public final int getContactsSize() { /** * Returns the number of contacts (i.e., vcf) in a phonebook object. * @param type specifies which phonebook object, e.g., pb, fav * @return */ public final int getContactsSize(final int type) { final Uri myUri = DevicePolicyUtils.getEnterprisePhoneUri(mContext); final Uri myUri = DevicePolicyUtils.getEnterprisePhoneUri(mContext); Cursor contactCursor = null; Cursor contactCursor = null; String selectionClause = null; if (type == BluetoothPbapObexServer.ContentType.FAVORITES) { selectionClause = Phone.STARRED + " = 1"; } try { try { contactCursor = mResolver.query(myUri, new String[]{Phone.CONTACT_ID}, null, null, contactCursor = mResolver.query(myUri, Phone.CONTACT_ID); new String[]{Phone.CONTACT_ID}, selectionClause, null, Phone.CONTACT_ID); if (contactCursor == null) { if (contactCursor == null) { return 0; return 0; } } return getDistinctContactIdSize(contactCursor) + 1; // always has the 0.vcf int contactsSize = getDistinctContactIdSize(contactCursor); if (type == BluetoothPbapObexServer.ContentType.PHONEBOOK) { contactsSize += 1; // pb has the 0.vcf owner's card } return contactsSize; } catch (CursorWindowAllocationException e) { } catch (CursorWindowAllocationException e) { Log.e(TAG, "CursorWindowAllocationException while getting Contacts size"); Log.e(TAG, "CursorWindowAllocationException while getting Contacts size"); } finally { } finally { Loading Loading @@ -551,7 +566,7 @@ public class BluetoothPbapVcardManager { final int composeAndSendPhonebookVcards(Operation op, final int startPoint, final int endPoint, final int composeAndSendPhonebookVcards(Operation op, final int startPoint, final int endPoint, final boolean vcardType21, String ownerVCard, int needSendBody, int pbSize, final boolean vcardType21, String ownerVCard, int needSendBody, int pbSize, boolean ignorefilter, byte[] filter, byte[] vcardselector, String vcardselectorop, boolean ignorefilter, byte[] filter, byte[] vcardselector, String vcardselectorop, boolean vcardselect) { boolean vcardselect, boolean favorites) { if (startPoint < 1 || startPoint > endPoint) { if (startPoint < 1 || startPoint > endPoint) { Log.e(TAG, "internal error: startPoint or endPoint is not correct."); Log.e(TAG, "internal error: startPoint or endPoint is not correct."); return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; Loading @@ -562,9 +577,15 @@ public class BluetoothPbapVcardManager { Cursor contactIdCursor = new MatrixCursor(new String[]{ Cursor contactIdCursor = new MatrixCursor(new String[]{ Phone.CONTACT_ID Phone.CONTACT_ID }); }); String selectionClause = null; if (favorites) { selectionClause = Phone.STARRED + " = 1"; } try { try { contactCursor = mResolver.query(myUri, PHONES_CONTACTS_PROJECTION, null, null, contactCursor = mResolver.query(myUri, PHONES_CONTACTS_PROJECTION, selectionClause, Phone.CONTACT_ID); null, Phone.CONTACT_ID); if (contactCursor != null) { if (contactCursor != null) { contactIdCursor = contactIdCursor = ContactCursorFilter.filterByRange(contactCursor, startPoint, endPoint); ContactCursorFilter.filterByRange(contactCursor, startPoint, endPoint); Loading Loading
src/com/android/bluetooth/pbap/BluetoothPbapObexServer.java +51 −14 Original line number Original line Diff line number Diff line Loading @@ -97,6 +97,7 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { private static final String[] LEGAL_PATH = { private static final String[] LEGAL_PATH = { "/telecom", "/telecom", "/telecom/pb", "/telecom/pb", "/telecom/fav", "/telecom/ich", "/telecom/ich", "/telecom/och", "/telecom/och", "/telecom/mch", "/telecom/mch", Loading @@ -106,6 +107,7 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { @SuppressWarnings("unused") private static final String[] LEGAL_PATH_WITH_SIM = { @SuppressWarnings("unused") private static final String[] LEGAL_PATH_WITH_SIM = { "/telecom", "/telecom", "/telecom/pb", "/telecom/pb", "/telecom/fav", "/telecom/ich", "/telecom/ich", "/telecom/och", "/telecom/och", "/telecom/mch", "/telecom/mch", Loading Loading @@ -138,6 +140,9 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { // phone book // phone book private static final String PB = "pb"; private static final String PB = "pb"; // favorites private static final String FAV = "fav"; private static final String TELECOM_PATH = "/telecom"; private static final String TELECOM_PATH = "/telecom"; private static final String ICH_PATH = "/telecom/ich"; private static final String ICH_PATH = "/telecom/ich"; Loading @@ -150,6 +155,8 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { private static final String PB_PATH = "/telecom/pb"; private static final String PB_PATH = "/telecom/pb"; private static final String FAV_PATH = "/telecom/fav"; // type for list vcard objects // type for list vcard objects private static final String TYPE_LISTING = "x-bt/vcard-listing"; private static final String TYPE_LISTING = "x-bt/vcard-listing"; Loading Loading @@ -212,6 +219,8 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { public static final int MISSED_CALL_HISTORY = 4; public static final int MISSED_CALL_HISTORY = 4; public static final int COMBINED_CALL_HISTORY = 5; public static final int COMBINED_CALL_HISTORY = 5; public static final int FAVORITES = 6; } } public BluetoothPbapObexServer(Handler callback, Context context, public BluetoothPbapObexServer(Handler callback, Context context, Loading Loading @@ -441,6 +450,8 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { if (mCurrentPath.equals(PB_PATH)) { if (mCurrentPath.equals(PB_PATH)) { appParamValue.needTag = ContentType.PHONEBOOK; appParamValue.needTag = ContentType.PHONEBOOK; } else if (mCurrentPath.equals(FAV_PATH)) { appParamValue.needTag = ContentType.FAVORITES; } else if (mCurrentPath.equals(ICH_PATH)) { } else if (mCurrentPath.equals(ICH_PATH)) { appParamValue.needTag = ContentType.INCOMING_CALL_HISTORY; appParamValue.needTag = ContentType.INCOMING_CALL_HISTORY; } else if (mCurrentPath.equals(OCH_PATH)) { } else if (mCurrentPath.equals(OCH_PATH)) { Loading Loading @@ -478,6 +489,11 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { if (D) { if (D) { Log.v(TAG, "download phonebook request"); Log.v(TAG, "download phonebook request"); } } } else if (isNameMatchTarget(name, FAV)) { appParamValue.needTag = ContentType.FAVORITES; if (D) { Log.v(TAG, "download favorites request"); } } else if (isNameMatchTarget(name, ICH)) { } else if (isNameMatchTarget(name, ICH)) { appParamValue.needTag = ContentType.INCOMING_CALL_HISTORY; appParamValue.needTag = ContentType.INCOMING_CALL_HISTORY; appParamValue.callHistoryVersionCounter = appParamValue.callHistoryVersionCounter = Loading Loading @@ -751,7 +767,8 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { result.append("<vCard-listing version=\"1.0\">"); result.append("<vCard-listing version=\"1.0\">"); // Phonebook listing request // Phonebook listing request if (appParamValue.needTag == ContentType.PHONEBOOK) { if ((appParamValue.needTag == ContentType.PHONEBOOK) || (appParamValue.needTag == ContentType.FAVORITES)) { String type = ""; String type = ""; if (appParamValue.searchAttr.equals("0")) { if (appParamValue.searchAttr.equals("0")) { type = "name"; type = "name"; Loading Loading @@ -948,7 +965,7 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { checkPbapFeatureSupport(mFolderVersionCounterbitMask); checkPbapFeatureSupport(mFolderVersionCounterbitMask); } } boolean needSendPhonebookVersionCounters = false; boolean needSendPhonebookVersionCounters = false; if (isNameMatchTarget(name, PB)) { if (isNameMatchTarget(name, PB) || isNameMatchTarget(name, FAV)) { needSendPhonebookVersionCounters = needSendPhonebookVersionCounters = checkPbapFeatureSupport(mFolderVersionCounterbitMask); checkPbapFeatureSupport(mFolderVersionCounterbitMask); } } Loading Loading @@ -1194,11 +1211,12 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { if (appParamValue.needTag == 0) { if (appParamValue.needTag == 0) { Log.w(TAG, "wrong path!"); Log.w(TAG, "wrong path!"); return ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE; return ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE; } else if (appParamValue.needTag == ContentType.PHONEBOOK) { } else if ((appParamValue.needTag == ContentType.PHONEBOOK) || (appParamValue.needTag == ContentType.FAVORITES)) { if (intIndex < 0 || intIndex >= size) { if (intIndex < 0 || intIndex >= size) { Log.w(TAG, "The requested vcard is not acceptable! name= " + name); Log.w(TAG, "The requested vcard is not acceptable! name= " + name); return ResponseCodes.OBEX_HTTP_NOT_FOUND; return ResponseCodes.OBEX_HTTP_NOT_FOUND; } else if (intIndex == 0) { } else if ((intIndex == 0) && (appParamValue.needTag == ContentType.PHONEBOOK)) { // For PB_PATH, 0.vcf is the phone number of this phone. // For PB_PATH, 0.vcf is the phone number of this phone. String ownerVcard = mVcardManager.getOwnerPhoneNumberVcard(vcard21, String ownerVcard = mVcardManager.getOwnerPhoneNumberVcard(vcard21, appParamValue.ignorefilter ? null : appParamValue.propertySelector); appParamValue.ignorefilter ? null : appParamValue.propertySelector); Loading Loading @@ -1254,30 +1272,49 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { int requestSize = int requestSize = pbSize >= appParamValue.maxListCount ? appParamValue.maxListCount : pbSize; pbSize >= appParamValue.maxListCount ? appParamValue.maxListCount : pbSize; int startPoint = appParamValue.listStartOffset; /** if (startPoint < 0 || startPoint >= pbSize) { * startIndex (resp., lastIndex) corresponds to the index of the first (resp., last) * vcard entry in the phonebook object. * PBAP v1.2.3: only pb starts indexing at 0.vcf (owner card), the other phonebook * objects (e.g., fav) start at 1.vcf. Additionally, the owner card is included in * pb's pbSize. This means pbSize corresponds to the index of the last vcf in the fav * phonebook object, but does not for the pb phonebook object. */ int startIndex = 1; int lastIndex = pbSize; if (appParamValue.needTag == BluetoothPbapObexServer.ContentType.PHONEBOOK) { startIndex = 0; lastIndex = pbSize - 1; } // [startPoint, endPoint] denote the range of vcf indices to send, inclusive. int startPoint = startIndex + appParamValue.listStartOffset; int endPoint = startPoint + requestSize - 1; if (appParamValue.listStartOffset < 0 || startPoint > lastIndex) { Log.w(TAG, "listStartOffset is not correct! " + startPoint); Log.w(TAG, "listStartOffset is not correct! " + startPoint); return ResponseCodes.OBEX_HTTP_OK; return ResponseCodes.OBEX_HTTP_OK; } } if (endPoint > lastIndex) { endPoint = lastIndex; } // Limit the number of call log to CALLLOG_NUM_LIMIT // Limit the number of call log to CALLLOG_NUM_LIMIT if (appParamValue.needTag != BluetoothPbapObexServer.ContentType.PHONEBOOK) { if ((appParamValue.needTag != BluetoothPbapObexServer.ContentType.PHONEBOOK) && (appParamValue.needTag != BluetoothPbapObexServer.ContentType.FAVORITES)) { if (requestSize > CALLLOG_NUM_LIMIT) { if (requestSize > CALLLOG_NUM_LIMIT) { requestSize = CALLLOG_NUM_LIMIT; requestSize = CALLLOG_NUM_LIMIT; } } } } int endPoint = startPoint + requestSize - 1; if (endPoint > pbSize - 1) { endPoint = pbSize - 1; } if (D) { if (D) { Log.d(TAG, "pullPhonebook(): requestSize=" + requestSize + " startPoint=" + startPoint Log.d(TAG, "pullPhonebook(): requestSize=" + requestSize + " startPoint=" + startPoint + " endPoint=" + endPoint); + " endPoint=" + endPoint); } } boolean vcard21 = appParamValue.vcard21; boolean vcard21 = appParamValue.vcard21; if (appParamValue.needTag == BluetoothPbapObexServer.ContentType.PHONEBOOK) { boolean favorites = (appParamValue.needTag == BluetoothPbapObexServer.ContentType.FAVORITES); if ((appParamValue.needTag == BluetoothPbapObexServer.ContentType.PHONEBOOK) || favorites) { if (startPoint == 0) { if (startPoint == 0) { String ownerVcard = mVcardManager.getOwnerPhoneNumberVcard(vcard21, String ownerVcard = mVcardManager.getOwnerPhoneNumberVcard(vcard21, appParamValue.ignorefilter ? null : appParamValue.propertySelector); appParamValue.ignorefilter ? null : appParamValue.propertySelector); Loading @@ -1287,13 +1324,13 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { return mVcardManager.composeAndSendPhonebookVcards(op, 1, endPoint, vcard21, return mVcardManager.composeAndSendPhonebookVcards(op, 1, endPoint, vcard21, ownerVcard, needSendBody, pbSize, appParamValue.ignorefilter, ownerVcard, needSendBody, pbSize, appParamValue.ignorefilter, appParamValue.propertySelector, appParamValue.vCardSelector, appParamValue.propertySelector, appParamValue.vCardSelector, appParamValue.vCardSelectorOperator, mVcardSelector); appParamValue.vCardSelectorOperator, mVcardSelector, favorites); } } } else { } else { return mVcardManager.composeAndSendPhonebookVcards(op, startPoint, endPoint, return mVcardManager.composeAndSendPhonebookVcards(op, startPoint, endPoint, vcard21, null, needSendBody, pbSize, appParamValue.ignorefilter, vcard21, null, needSendBody, pbSize, appParamValue.ignorefilter, appParamValue.propertySelector, appParamValue.vCardSelector, appParamValue.propertySelector, appParamValue.vCardSelector, appParamValue.vCardSelectorOperator, mVcardSelector); appParamValue.vCardSelectorOperator, mVcardSelector, favorites); } } } else { } else { return mVcardManager.composeAndSendSelectedCallLogVcards(appParamValue.needTag, op, return mVcardManager.composeAndSendSelectedCallLogVcards(appParamValue.needTag, op, Loading
src/com/android/bluetooth/pbap/BluetoothPbapService.java +2 −1 Original line number Original line Diff line number Diff line Loading @@ -139,7 +139,8 @@ public class BluetoothPbapService extends ProfileService implements IObexConnect private ObexServerSockets mServerSockets = null; private ObexServerSockets mServerSockets = null; private static final int SDP_PBAP_SERVER_VERSION = 0x0102; private static final int SDP_PBAP_SERVER_VERSION = 0x0102; private static final int SDP_PBAP_SUPPORTED_REPOSITORIES = 0x0001; // PBAP v1.2.3, Sec. 7.1.2: local phonebook and favorites private static final int SDP_PBAP_SUPPORTED_REPOSITORIES = 0x0009; private static final int SDP_PBAP_SUPPORTED_FEATURES = 0x021F; private static final int SDP_PBAP_SUPPORTED_FEATURES = 0x021F; /* PBAP will use Bluetooth notification ID from 1000000 (included) to 2000000 (excluded). /* PBAP will use Bluetooth notification ID from 1000000 (included) to 2000000 (excluded). Loading
src/com/android/bluetooth/pbap/BluetoothPbapVcardManager.java +29 −8 Original line number Original line Diff line number Diff line Loading @@ -153,7 +153,8 @@ public class BluetoothPbapVcardManager { int size; int size; switch (type) { switch (type) { case BluetoothPbapObexServer.ContentType.PHONEBOOK: case BluetoothPbapObexServer.ContentType.PHONEBOOK: size = getContactsSize(); case BluetoothPbapObexServer.ContentType.FAVORITES: size = getContactsSize(type); break; break; default: default: size = getCallHistorySize(type); size = getCallHistorySize(type); Loading @@ -165,16 +166,30 @@ public class BluetoothPbapVcardManager { return size; return size; } } public final int getContactsSize() { /** * Returns the number of contacts (i.e., vcf) in a phonebook object. * @param type specifies which phonebook object, e.g., pb, fav * @return */ public final int getContactsSize(final int type) { final Uri myUri = DevicePolicyUtils.getEnterprisePhoneUri(mContext); final Uri myUri = DevicePolicyUtils.getEnterprisePhoneUri(mContext); Cursor contactCursor = null; Cursor contactCursor = null; String selectionClause = null; if (type == BluetoothPbapObexServer.ContentType.FAVORITES) { selectionClause = Phone.STARRED + " = 1"; } try { try { contactCursor = mResolver.query(myUri, new String[]{Phone.CONTACT_ID}, null, null, contactCursor = mResolver.query(myUri, Phone.CONTACT_ID); new String[]{Phone.CONTACT_ID}, selectionClause, null, Phone.CONTACT_ID); if (contactCursor == null) { if (contactCursor == null) { return 0; return 0; } } return getDistinctContactIdSize(contactCursor) + 1; // always has the 0.vcf int contactsSize = getDistinctContactIdSize(contactCursor); if (type == BluetoothPbapObexServer.ContentType.PHONEBOOK) { contactsSize += 1; // pb has the 0.vcf owner's card } return contactsSize; } catch (CursorWindowAllocationException e) { } catch (CursorWindowAllocationException e) { Log.e(TAG, "CursorWindowAllocationException while getting Contacts size"); Log.e(TAG, "CursorWindowAllocationException while getting Contacts size"); } finally { } finally { Loading Loading @@ -551,7 +566,7 @@ public class BluetoothPbapVcardManager { final int composeAndSendPhonebookVcards(Operation op, final int startPoint, final int endPoint, final int composeAndSendPhonebookVcards(Operation op, final int startPoint, final int endPoint, final boolean vcardType21, String ownerVCard, int needSendBody, int pbSize, final boolean vcardType21, String ownerVCard, int needSendBody, int pbSize, boolean ignorefilter, byte[] filter, byte[] vcardselector, String vcardselectorop, boolean ignorefilter, byte[] filter, byte[] vcardselector, String vcardselectorop, boolean vcardselect) { boolean vcardselect, boolean favorites) { if (startPoint < 1 || startPoint > endPoint) { if (startPoint < 1 || startPoint > endPoint) { Log.e(TAG, "internal error: startPoint or endPoint is not correct."); Log.e(TAG, "internal error: startPoint or endPoint is not correct."); return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; Loading @@ -562,9 +577,15 @@ public class BluetoothPbapVcardManager { Cursor contactIdCursor = new MatrixCursor(new String[]{ Cursor contactIdCursor = new MatrixCursor(new String[]{ Phone.CONTACT_ID Phone.CONTACT_ID }); }); String selectionClause = null; if (favorites) { selectionClause = Phone.STARRED + " = 1"; } try { try { contactCursor = mResolver.query(myUri, PHONES_CONTACTS_PROJECTION, null, null, contactCursor = mResolver.query(myUri, PHONES_CONTACTS_PROJECTION, selectionClause, Phone.CONTACT_ID); null, Phone.CONTACT_ID); if (contactCursor != null) { if (contactCursor != null) { contactIdCursor = contactIdCursor = ContactCursorFilter.filterByRange(contactCursor, startPoint, endPoint); ContactCursorFilter.filterByRange(contactCursor, startPoint, endPoint); Loading