Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ce8d51a3 authored by Yoshiharu Kurita's avatar Yoshiharu Kurita Committed by Jaikumar Ganesh
Browse files

Handle PBAP response packet as raw bytes

Adjust PBAP response packet to be always handled as bytes.
Currently, it is handled as string when is read from internal data.
This causes the lack of PullvCardListing packet and the abort of
PullPhonebook transaction when multi-byte characters are contained
into corresponding contacts.
This fix will avoid the lack and the abort by writing whole packet
into the target stream as byte.

Change-Id: I17ee3ada25718cc263c9e0942f75605bd971b638
parent cab07635
Loading
Loading
Loading
Loading
+4 −39
Original line number Diff line number Diff line
@@ -670,51 +670,16 @@ public class BluetoothPbapObexServer extends ServerRequestHandler {
            return ResponseCodes.OBEX_HTTP_OK;
        }

        byte[] vcardBytes = vcardString.getBytes();
        int vcardStringLen = vcardBytes.length;
        if (D) Log.d(TAG, "Send Data: len=" + vcardStringLen);

        OutputStream outputStream = null;
        int pushResult = ResponseCodes.OBEX_HTTP_OK;
        try {
            outputStream = op.openOutputStream();
            outputStream.write(vcardString.getBytes());
            if (V) Log.v(TAG, "Send Data complete!");
        } catch (IOException e) {
            Log.e(TAG, "open outputstrem failed" + e.toString());
            return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
        }

        int position = 0;
        long timestamp = 0;
        int outputBufferSize = op.getMaxPacketSize();
        if (V) Log.v(TAG, "outputBufferSize = " + outputBufferSize);
        while (position != vcardStringLen) {
            if (sIsAborted) {
                ((ServerOperation)op).isAborted = true;
                sIsAborted = false;
                break;
            }
            if (V) timestamp = System.currentTimeMillis();
            int readLength = outputBufferSize;
            if (vcardStringLen - position < outputBufferSize) {
                readLength = vcardStringLen - position;
            }
            byte[] subByteArray = Arrays.copyOfRange(vcardBytes, position, position + readLength);
            try {
                outputStream.write(subByteArray, 0, readLength);
            } catch (IOException e) {
                Log.e(TAG, "write outputstrem failed" + e.toString());
            Log.e(TAG, "open/write outputstrem failed" + e.toString());
            pushResult = ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
                break;
        }
            if (V) {
                Log.v(TAG, "Sending vcard String position = " + position + " readLength "
                        + readLength + " bytes took " + (System.currentTimeMillis() - timestamp)
                        + " ms");
            }
            position += readLength;
        }

        if (V) Log.v(TAG, "Send Data complete!");

        if (!closeStream(outputStream, op)) {
            pushResult = ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
+17 −53
Original line number Diff line number Diff line
@@ -68,8 +68,6 @@ public class BluetoothPbapVcardManager {

    private Context mContext;

    private StringBuilder mVcardResults = null;

    static final String[] PHONES_PROJECTION = new String[] {
            Data._ID, // 0
            CommonDataKinds.Phone.TYPE, // 1
@@ -522,21 +520,17 @@ public class BluetoothPbapVcardManager {
    }

    /**
     * Handler to emit VCard String to PCE once size grow to maxPacketSize.
     * Handler to emit vCards to PCE.
     */
    public class HandlerForStringBuffer {
        private Operation operation;

        private OutputStream outputStream;

        private int maxPacketSize;

        private String phoneOwnVCard = null;

        public HandlerForStringBuffer(Operation op, String ownerVCard) {
            operation = op;
            maxPacketSize = operation.getMaxPacketSize();
            if (V) Log.v(TAG, "getMaxPacketSize() = " + maxPacketSize);
            if (ownerVCard != null) {
                phoneOwnVCard = ownerVCard;
                if (V) Log.v(TAG, "phone own number vcard:");
@@ -544,66 +538,36 @@ public class BluetoothPbapVcardManager {
            }
        }

        public boolean onInit(Context context) {
        private boolean write(String vCard) {
            try {
                outputStream = operation.openOutputStream();
                mVcardResults = new StringBuilder();
                if (phoneOwnVCard != null) {
                    mVcardResults.append(phoneOwnVCard);
                }
            } catch (IOException e) {
                Log.e(TAG, "open outputstrem failed" + e.toString());
                return false;
            }
            if (V) Log.v(TAG, "openOutputStream() ok.");
                if (vCard != null) {
                    outputStream.write(vCard.getBytes());
                    return true;
                }

        public boolean onEntryCreated(String vcard) {
            int vcardLen = vcard.length();
            if (V) Log.v(TAG, "The length of this vcard is: " + vcardLen);

            mVcardResults.append(vcard);
            int vcardByteLen = mVcardResults.toString().getBytes().length;
            if (V) Log.v(TAG, "The byte length of this vcardResults is: " + vcardByteLen);

            if (vcardByteLen >= maxPacketSize) {
                long timestamp = 0;
                int position = 0;

                // Need while loop to handle the big vcard case
                while (!BluetoothPbapObexServer.sIsAborted
                        && position < (vcardByteLen - maxPacketSize)) {
                    if (V) timestamp = System.currentTimeMillis();

                    String subStr = mVcardResults.toString().substring(position,
                            position + maxPacketSize);
                    try {
                        outputStream.write(subStr.getBytes(), 0, maxPacketSize);
            } catch (IOException e) {
                Log.e(TAG, "write outputstrem failed" + e.toString());
            }
            return false;
        }
                    if (V) Log.v(TAG, "Sending vcard String " + maxPacketSize + " bytes took "
                            + (System.currentTimeMillis() - timestamp) + " ms");

                    position += maxPacketSize;
                }
                mVcardResults.delete(0, position);
        public boolean onInit(Context context) {
            try {
                outputStream = operation.openOutputStream();
                if (phoneOwnVCard != null) {
                    return write(phoneOwnVCard);
                }
                return true;
            } catch (IOException e) {
                Log.e(TAG, "open outputstrem failed" + e.toString());
            }
            return false;
        }

        public void onTerminate() {
            // Send out last packet
            byte[] lastBytes = mVcardResults.toString().getBytes();
            try {
                outputStream.write(lastBytes, 0, lastBytes.length);
            } catch (IOException e) {
                Log.e(TAG, "write outputstrem failed" + e.toString());
        public boolean onEntryCreated(String vcard) {
            return write(vcard);
        }
            if (V) Log.v(TAG, "Last packet sent out, sending process complete!");

        public void onTerminate() {
            if (!BluetoothPbapObexServer.closeStream(outputStream, operation)) {
                if (V) Log.v(TAG, "CloseStream failed!");
            } else {