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

Commit 3701a405 authored by sravan voleti's avatar sravan voleti Committed by Chienyuan Huang
Browse files

PBAP: Add PBAP SIM Feature

Add changes to support PBAP SIM which fetches
phone book stored on the phone's SIM card.
Test: Connect with remote PBAP Client supporting PBAP SIM and verify
that connect and pull contacts from SIM repository.
Submitted on behalf of a third-party:
The Linux Foundation, The Android Open Source Project, Google, Inc
License rights, if any, to the submission are granted solely by the
copyright owner of such submission under its applicable intellectual
property.
/*
* Copyright (c) 2015, The Linux Foundation. All rights reserved.
* Copyright (C) 2014 Samsung System LSI
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
Third Party code includes additions/modifications from Qualcomm Innovation Center, Inc
Test: Used Mecapp PC tool as PBAP Client for validating SIM features.
Tag: #feature
Bug: 208528052

Change-Id: I823b8d7b972bcb251944fb70b734fc23955f6470
Merged-In: I823b8d7b972bcb251944fb70b734fc23955f6470
parent a3eec79e
Loading
Loading
Loading
Loading
+97 −37
Original line number Diff line number Diff line
@@ -93,18 +93,7 @@ public class BluetoothPbapObexServer extends ServerRequestHandler {
            0x66
    };

    // Currently not support SIM card
    private static final String[] LEGAL_PATH = {
            "/telecom",
            "/telecom/pb",
            "/telecom/fav",
            "/telecom/ich",
            "/telecom/och",
            "/telecom/mch",
            "/telecom/cch"
    };

    @SuppressWarnings("unused") private static final String[] LEGAL_PATH_WITH_SIM = {
            "/telecom",
            "/telecom/pb",
            "/telecom/fav",
@@ -157,6 +146,19 @@ public class BluetoothPbapObexServer extends ServerRequestHandler {

    private static final String FAV_PATH = "/telecom/fav";

    // SIM Support
    private static final String SIM_PATH = "/SIM1/telecom";

    private static final String SIM_ICH_PATH = "/SIM1/telecom/ich";

    private static final String SIM_OCH_PATH = "/SIM1/telecom/och";

    private static final String SIM_MCH_PATH = "/SIM1/telecom/mch";

    private static final String SIM_CCH_PATH = "/SIM1/telecom/cch";

    private static final String SIM_PB_PATH = "/SIM1/telecom/pb";

    // type for list vcard objects
    private static final String TYPE_LISTING = "x-bt/vcard-listing";

@@ -187,6 +189,8 @@ public class BluetoothPbapObexServer extends ServerRequestHandler {

    private BluetoothPbapVcardManager mVcardManager;

    BluetoothPbapSimVcardManager mVcardSimManager;

    private int mOrderBy = ORDER_BY_INDEXED;

    private static final int CALLLOG_NUM_LIMIT = 50;
@@ -209,6 +213,10 @@ public class BluetoothPbapObexServer extends ServerRequestHandler {

    private PbapStateMachine mStateMachine;

    private enum ContactsType {
        TYPE_PHONEBOOK , TYPE_SIM ;
    }

    public static class ContentType {
        public static final int PHONEBOOK = 1;

@@ -221,6 +229,8 @@ public class BluetoothPbapObexServer extends ServerRequestHandler {
        public static final int COMBINED_CALL_HISTORY = 5;

        public static final int FAVORITES = 6;

        public static final int SIM_PHONEBOOK = 7;
    }

    public BluetoothPbapObexServer(Handler callback, Context context,
@@ -229,6 +239,7 @@ public class BluetoothPbapObexServer extends ServerRequestHandler {
        mCallback = callback;
        mContext = context;
        mVcardManager = new BluetoothPbapVcardManager(mContext);
        mVcardSimManager = new BluetoothPbapSimVcardManager(mContext);
        mStateMachine = stateMachine;
    }

@@ -452,21 +463,23 @@ public class BluetoothPbapObexServer extends ServerRequestHandler {
                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) || mCurrentPath.equals(SIM_ICH_PATH)) {
                appParamValue.needTag = ContentType.INCOMING_CALL_HISTORY;
            } else if (mCurrentPath.equals(OCH_PATH)) {
            } else if (mCurrentPath.equals(OCH_PATH)|| mCurrentPath.equals(SIM_OCH_PATH)) {
                appParamValue.needTag = ContentType.OUTGOING_CALL_HISTORY;
            } else if (mCurrentPath.equals(MCH_PATH)) {
            } else if (mCurrentPath.equals(MCH_PATH)|| mCurrentPath.equals(SIM_MCH_PATH)) {
                appParamValue.needTag = ContentType.MISSED_CALL_HISTORY;
                mNeedNewMissedCallsNum = true;
            } else if (mCurrentPath.equals(CCH_PATH)) {
            } else if (mCurrentPath.equals(CCH_PATH)|| mCurrentPath.equals(SIM_CCH_PATH)) {
                appParamValue.needTag = ContentType.COMBINED_CALL_HISTORY;
            } else if (mCurrentPath.equals(TELECOM_PATH)) {
            } else if (mCurrentPath.equals(TELECOM_PATH)|| mCurrentPath.equals(SIM_PATH)) {
                /* PBAP 1.1.1 change */
                if (!validName && type.equals(TYPE_LISTING)) {
                    Log.e(TAG, "invalid vcard listing request in default folder");
                    return ResponseCodes.OBEX_HTTP_NOT_FOUND;
                }
            } else if (mCurrentPath.equals(SIM_PB_PATH)) {
                appParamValue.needTag = ContentType.SIM_PHONEBOOK;
            } else {
                Log.w(TAG, "mCurrentpath is not valid path!!!");
                return ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE;
@@ -475,16 +488,14 @@ public class BluetoothPbapObexServer extends ServerRequestHandler {
                Log.v(TAG, "onGet(): appParamValue.needTag=" + appParamValue.needTag);
            }
        } else {
            // Not support SIM card currently
            if (name.contains(SIM1.subSequence(0, SIM1.length()))) {
                Log.w(TAG, "Not support access SIM card info!");
                return ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE;
            }

            // we have weak name checking here to provide better
            // compatibility with other devices,although unique name such as
            // "pb.vcf" is required by SIG spec.
            if (isNameMatchTarget(name, PB)) {
            if (mVcardSimManager.isSimPhoneBook(name, type, PB, SIM1,
                TYPE_PB, TYPE_LISTING, mCurrentPath)) {
                appParamValue.needTag = ContentType.SIM_PHONEBOOK;
                if (D) Log.d(TAG, "download SIM phonebook request");
            } else if (isNameMatchTarget(name, PB)) {
                appParamValue.needTag = ContentType.PHONEBOOK;
                if (D) {
                    Log.v(TAG, "download phonebook request");
@@ -765,23 +776,32 @@ public class BluetoothPbapObexServer extends ServerRequestHandler {
        result.append("<?xml version=\"1.0\"?>");
        result.append("<!DOCTYPE vcard-listing SYSTEM \"vcard-listing.dtd\">");
        result.append("<vCard-listing version=\"1.0\">");

        String type = "";
        // Phonebook listing request
        if ((appParamValue.needTag == ContentType.PHONEBOOK)
                || (appParamValue.needTag == ContentType.FAVORITES)) {
            String type = "";
            if (appParamValue.searchAttr.equals("0")) {
                type = "name";
            } else if (appParamValue.searchAttr.equals("1")) {
                type = "number";
            }
            if (type.length() > 0) {
                itemsFound = createList(appParamValue, needSendBody, size, result, type);
                itemsFound = createList(appParamValue, needSendBody, size, result, type,
                        ContactsType.TYPE_PHONEBOOK);
            } else {
                return ResponseCodes.OBEX_HTTP_PRECON_FAILED;
            }
        // SIM Phonebook listing Request
        } else if (appParamValue.needTag == ContentType.SIM_PHONEBOOK) {
            type = mVcardSimManager.getType(appParamValue.searchAttr);
            if (type.length() > 0) {
                itemsFound = createList(appParamValue, needSendBody, size, result, type,
                        ContactsType.TYPE_SIM);
            } else {
                return ResponseCodes.OBEX_HTTP_PRECON_FAILED;
            }
        // Call history listing request
        } else {
            ArrayList<String> nameList = mVcardManager.loadCallHistoryList(appParamValue.needTag);
            int requestSize =
                    nameList.size() >= appParamValue.maxListCount ? appParamValue.maxListCount
@@ -810,16 +830,24 @@ public class BluetoothPbapObexServer extends ServerRequestHandler {
    }

    private int createList(AppParamValue appParamValue, int needSendBody, int size,
            StringBuilder result, String type) {
            StringBuilder result, String type, ContactsType contactType) {
        int itemsFound = 0;

        ArrayList<String> nameList = null;
        if (mVcardSelector) {
            nameList = mVcardManager.getSelectedPhonebookNameList(mOrderBy, appParamValue.vcard21,
                    needSendBody, size, appParamValue.vCardSelector,
            if (contactType == ContactsType.TYPE_PHONEBOOK) {
                nameList = mVcardManager.getSelectedPhonebookNameList(mOrderBy,
                    appParamValue.vcard21, needSendBody, size, appParamValue.vCardSelector,
                    appParamValue.vCardSelectorOperator);
            } else if(contactType == ContactsType.TYPE_SIM) {
                nameList = mVcardSimManager.getSIMPhonebookNameList(mOrderBy);
            }
        } else {
            if (contactType == ContactsType.TYPE_PHONEBOOK) {
                nameList = mVcardManager.getPhonebookNameList(mOrderBy);
            } else if( contactType == ContactsType.TYPE_SIM) {
                nameList = mVcardSimManager.getSIMPhonebookNameList(mOrderBy);
            }
        }

        final int requestSize =
@@ -837,8 +865,12 @@ public class BluetoothPbapObexServer extends ServerRequestHandler {
            ArrayList<Integer> savedPosList = new ArrayList<>();
            ArrayList<String> selectedNameList = new ArrayList<String>();
            // query the number, to get the names
            ArrayList<String> names =
                    mVcardManager.getContactNamesByNumber(appParamValue.searchValue);
            ArrayList<String> names =  new ArrayList<>();
            if (contactType == ContactsType.TYPE_PHONEBOOK) {
                names = mVcardManager.getContactNamesByNumber(appParamValue.searchValue);
            } else if(contactType== ContactsType.TYPE_SIM) {
                names = mVcardSimManager.getSIMContactNamesByNumber(appParamValue.searchValue);
            }
            if (mOrderBy == ORDER_BY_ALPHABETICAL) Collections.sort(names);
            for (int i = 0; i < names.size(); i++) {
                compareValue = names.get(i).trim();
@@ -1134,7 +1166,7 @@ public class BluetoothPbapObexServer extends ServerRequestHandler {
            Log.i(TAG, "searchAttr is valid: " + searchAttr);
        }

        int size = mVcardManager.getPhonebookSize(appParamValue.needTag);
        int size = mVcardManager.getPhonebookSize(appParamValue.needTag, mVcardSimManager);
        int needSendBody = handleAppParaForResponse(appParamValue, size, reply, op, name);
        if (needSendBody != NEED_SEND_BODY) {
            op.noBodyHeader();
@@ -1198,7 +1230,7 @@ public class BluetoothPbapObexServer extends ServerRequestHandler {
            }
        }

        int size = mVcardManager.getPhonebookSize(appParamValue.needTag);
        int size = mVcardManager.getPhonebookSize(appParamValue.needTag, mVcardSimManager);
        int needSendBody = handleAppParaForResponse(appParamValue, size, reply, op, name);
        if (size == 0) {
            if (D) {
@@ -1225,6 +1257,19 @@ public class BluetoothPbapObexServer extends ServerRequestHandler {
                return mVcardManager.composeAndSendPhonebookOneVcard(op, intIndex, vcard21, null,
                        mOrderBy, appParamValue.ignorefilter, appParamValue.propertySelector);
            }
        } else if (appParamValue.needTag == ContentType.SIM_PHONEBOOK) {
            if (intIndex < 0 || intIndex >= size) {
                Log.w(TAG, "The requested vcard is not acceptable! name= " + name);
                return ResponseCodes.OBEX_HTTP_NOT_FOUND;
            } else if (intIndex == 0) {
                // For PB_PATH, 0.vcf is the phone number of this phone.
                String ownerVcard = mVcardManager.getOwnerPhoneNumberVcard(vcard21,
                        appParamValue.ignorefilter ? null : appParamValue.propertySelector);
                return pushBytes(op, ownerVcard);
            } else {
                return mVcardSimManager.composeAndSendSIMPhonebookOneVcard(op, intIndex,
                        vcard21, null, mOrderBy);
            }
        } else {
            if (intIndex <= 0 || intIndex > size) {
                Log.w(TAG, "The requested vcard is not acceptable! name= " + name);
@@ -1256,7 +1301,7 @@ public class BluetoothPbapObexServer extends ServerRequestHandler {
            }
        } // code end for passing PTS3.2 TC_PSE_PBD_BI_01_C

        int pbSize = mVcardManager.getPhonebookSize(appParamValue.needTag);
        int pbSize = mVcardManager.getPhonebookSize(appParamValue.needTag, mVcardSimManager);
        int needSendBody = handleAppParaForResponse(appParamValue, pbSize, reply, op, name);
        if (needSendBody != NEED_SEND_BODY) {
            op.noBodyHeader();
@@ -1299,7 +1344,8 @@ public class BluetoothPbapObexServer extends ServerRequestHandler {

        // Limit the number of call log to CALLLOG_NUM_LIMIT
        if ((appParamValue.needTag != BluetoothPbapObexServer.ContentType.PHONEBOOK)
                && (appParamValue.needTag != BluetoothPbapObexServer.ContentType.FAVORITES)) {
                && (appParamValue.needTag != BluetoothPbapObexServer.ContentType.FAVORITES)
               && (appParamValue.needTag != BluetoothPbapObexServer.ContentType.SIM_PHONEBOOK)) {
            if (requestSize > CALLLOG_NUM_LIMIT) {
                requestSize = CALLLOG_NUM_LIMIT;
            }
@@ -1332,6 +1378,20 @@ public class BluetoothPbapObexServer extends ServerRequestHandler {
                        appParamValue.propertySelector, appParamValue.vCardSelector,
                        appParamValue.vCardSelectorOperator, mVcardSelector, favorites);
            }
        } else if (appParamValue.needTag == BluetoothPbapObexServer.ContentType.SIM_PHONEBOOK) {
            if (startPoint == 0) {
                String ownerVcard = mVcardManager.getOwnerPhoneNumberVcard(vcard21,
                        appParamValue.propertySelector);
                if (endPoint == 0) {
                    return pushBytes(op, ownerVcard);
                } else {
                    return mVcardSimManager.composeAndSendSIMPhonebookVcards(op, 1, endPoint,
                        vcard21, ownerVcard);
                }
            } else {
                return mVcardSimManager.composeAndSendSIMPhonebookVcards(op, startPoint,
                        endPoint, vcard21, null);
            }
        } else {
            return mVcardManager.composeAndSendSelectedCallLogVcards(appParamValue.needTag, op,
                    startPoint, endPoint, vcard21, needSendBody, pbSize,
+2 −2
Original line number Diff line number Diff line
@@ -86,7 +86,7 @@ public class BluetoothPbapService extends ProfileService implements IObexConnect

    public static final boolean DEBUG = true;

    public static final boolean VERBOSE = false;
    public static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);

    /**
     * Intent indicating incoming obex authentication request which is from
@@ -147,7 +147,7 @@ public class BluetoothPbapService extends ProfileService implements IObexConnect

    private static final int SDP_PBAP_SERVER_VERSION = 0x0102;
    // 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_REPOSITORIES = 0x000B;
    private static final int SDP_PBAP_SUPPORTED_FEATURES = 0x021F;

    /* PBAP will use Bluetooth notification ID from 1000000 (included) to 2000000 (excluded).
+540 −0

File added.

Preview size limit exceeded, changes collapsed.

+5 −1
Original line number Diff line number Diff line
@@ -148,13 +148,17 @@ public class BluetoothPbapVcardManager {
        return vcard;
    }

    public final int getPhonebookSize(final int type) {
    public final int getPhonebookSize(final int type,
            BluetoothPbapSimVcardManager vCardSimManager) {
        int size;
        switch (type) {
            case BluetoothPbapObexServer.ContentType.PHONEBOOK:
            case BluetoothPbapObexServer.ContentType.FAVORITES:
                size = getContactsSize(type);
                break;
            case BluetoothPbapObexServer.ContentType.SIM_PHONEBOOK:
                size = vCardSimManager.getSIMContactsSize();
                break;
            default:
                size = getCallHistorySize(type);
                break;