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

Commit f33884ee authored by Hemant Gupta's avatar Hemant Gupta Committed by Andre Eisenbach
Browse files

PBAP: Implement Folder Version Counter(s)

Primary version counter should be updated on any change to
contact. Secondary version counter should not update when
there is change to fields other than F, FN, TEL, EMAIL or
ADDRESS. There is no default API available in android to determine
which field is updated as required for updating secondary
version counter. Implemented logic to increment the secondary
version counter by comparing updated contacts with old cached
contacts of the contact database.

Test: Verified that folder version counter gets incremented for
      change(s) in fields of Contacts as per PBAP specification.
      TestTracker: 89053
Bug: 33011817
Change-Id: I90a1ced3713c369bcde0edd627bbde57a9676708
(cherry picked from commit 738dab24)
parent 283a15c5
Loading
Loading
Loading
Loading
+8 −20
Original line number Diff line number Diff line
@@ -365,6 +365,8 @@ public class BluetoothPbapObexServer extends ServerRequestHandler {
            return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
        }

        /* TODO: block Get request if contacts are not completely loaded locally */

        if (V) logHeader(request);
        if (D) Log.d(TAG, "OnGet type is " + type + "; name is " + name);

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

@@ -1118,6 +1121,7 @@ public class BluetoothPbapObexServer extends ServerRequestHandler {
        int pbSize = mVcardManager.getPhonebookSize(appParamValue.needTag);
        int needSendBody = handleAppParaForResponse(appParamValue, pbSize, reply, op, name);
        if (needSendBody != NEED_SEND_BODY) {
            op.noBodyHeader();
            return needSendBody;
        }

@@ -1334,34 +1338,18 @@ public class BluetoothPbapObexServer extends ServerRequestHandler {
        ByteBuffer pvc = ByteBuffer.allocate(16);
        pvc.putLong(primaryVcMsb);

        Log.d(TAG, "primaryVersionCounter is " + BluetoothPbapService.primaryVersionCounter);

        updatePBSecondaryFolderVersion(BluetoothPbapService.primaryVersionCounter);
        pvc.putLong(BluetoothPbapService.primaryVersionCounter);
        BluetoothPbapService.primaryVersionCounter = 0;
        Log.d(TAG, "primaryVersionCounter is " + BluetoothPbapUtils.primaryVersionCounter);
        pvc.putLong(BluetoothPbapUtils.primaryVersionCounter);
        return pvc.array();
    }

    private void updatePBSecondaryFolderVersion(long counterValue) {
        // Workaround for passing PTS test case TC_PSE_PBD_BV_9_C
        if (SystemProperties.getBoolean("ro.bluetooth.pbap.sec", false)) {
            Log.d(TAG, "Reset secondary folder version bit for PTS case");
            BluetoothPbapService.secondaryVersionCounter = 0;
        } else {
            BluetoothPbapService.secondaryVersionCounter =
                    BluetoothPbapService.primaryVersionCounter;
        }
    }

    private byte[] getPBSecondaryFolderVersion() {
        long secondaryVcMsb = 0;
        ByteBuffer svc = ByteBuffer.allocate(16);
        svc.putLong(secondaryVcMsb);

        Log.d(TAG, "secondaryVersionCounter is " + BluetoothPbapService.secondaryVersionCounter);

        svc.putLong(BluetoothPbapService.secondaryVersionCounter);
        BluetoothPbapService.secondaryVersionCounter = 0;
        Log.d(TAG, "secondaryVersionCounter is " + BluetoothPbapUtils.secondaryVersionCounter);
        svc.putLong(BluetoothPbapUtils.secondaryVersionCounter);
        return svc.array();
    }

+54 −21
Original line number Diff line number Diff line
@@ -74,6 +74,7 @@ import com.android.bluetooth.util.DevicePolicyUtils;
import java.io.IOException;
import java.util.Calendar;
import java.util.concurrent.atomic.AtomicLong;
import java.util.HashMap;

import javax.obex.ServerSession;

@@ -146,6 +147,14 @@ public class BluetoothPbapService extends ProfileService implements IObexConnect

    private static final int AUTH_TIMEOUT = 3;

    private static final int SHUTDOWN = 4;

    protected static final int LOAD_CONTACTS = 5;

    private static final int CHECK_SECONDARY_VERSION_COUNTER = 6;

    protected static final int ROLLOVER_COUNTERS = 7;

    private static final int USER_CONFIRM_TIMEOUT_VALUE = 30000;

    private static final int RELEASE_WAKE_LOCK_DELAY = 10000;
@@ -201,15 +210,9 @@ public class BluetoothPbapService extends ProfileService implements IObexConnect

    private boolean mSdpSearchInitiated = false;

    private static AtomicLong mDbIndetifier = new AtomicLong();

    static long primaryVersionCounter = 0;

    static long secondaryVersionCounter = 0;

    private boolean isRegisteredObserver = false;

    private static final int SHUTDOWN = 4;
    protected Context mContext;

    // package and class name to which we send intent to check phone book access permission
    private static final String ACCESS_AUTHORITY_PACKAGE = "com.android.settings";
@@ -224,7 +227,12 @@ public class BluetoothPbapService extends ProfileService implements IObexConnect
        @Override
        public void onChange(boolean selfChange) {
            Log.d(TAG, " onChange on contact uri ");
            primaryVersionCounter++;
            if (BluetoothPbapUtils.contactsLoaded) {
                if (!mSessionStatusHandler.hasMessages(CHECK_SECONDARY_VERSION_COUNTER)) {
                    mSessionStatusHandler.sendMessage(
                            mSessionStatusHandler.obtainMessage(CHECK_SECONDARY_VERSION_COUNTER));
                }
            }
        }
    }

@@ -232,6 +240,7 @@ public class BluetoothPbapService extends ProfileService implements IObexConnect

    public BluetoothPbapService() {
        mState = BluetoothPbap.STATE_DISCONNECTED;
        mContext = this;
    }

    // process the intent from receiver
@@ -250,11 +259,11 @@ public class BluetoothPbapService extends ProfileService implements IObexConnect
                }
                // Release all resources
                closeService();
                return;
            } else if (state == BluetoothAdapter.STATE_ON) {
                // start RFCOMM listener
                mSessionStatusHandler.sendMessage(mSessionStatusHandler.obtainMessage(START_LISTENER));
            }
            return;
        }

        if (action.equals(BluetoothDevice.ACTION_ACL_DISCONNECTED) && mIsWaitingAuthorization) {
@@ -416,6 +425,11 @@ public class BluetoothPbapService extends ProfileService implements IObexConnect
    private final void closeService() {
        if (VERBOSE) Log.v(TAG, "Pbap Service closeService in");

        BluetoothPbapUtils.savePbapParams(this, BluetoothPbapUtils.primaryVersionCounter,
                BluetoothPbapUtils.secondaryVersionCounter, BluetoothPbapUtils.mDbIdentifier.get(),
                BluetoothPbapUtils.contactsLastUpdated, BluetoothPbapUtils.totalFields,
                BluetoothPbapUtils.totalSvcFields, BluetoothPbapUtils.totalContacts);

        // exit initSocket early
        mInterrupted = true;
        if (mWakeLock != null) {
@@ -475,7 +489,6 @@ public class BluetoothPbapService extends ProfileService implements IObexConnect

    private void stopObexServerSession() {
        if (VERBOSE) Log.v(TAG, "Pbap Service stopObexServerSession");

        mSessionStatusHandler.removeMessages(MSG_ACQUIRE_WAKE_LOCK);
        mSessionStatusHandler.removeMessages(MSG_RELEASE_WAKE_LOCK);
        // Release the wake lock if obex transaction is over
@@ -626,7 +639,7 @@ public class BluetoothPbapService extends ProfileService implements IObexConnect
        }
    }

    private final Handler mSessionStatusHandler = new Handler() {
    protected final Handler mSessionStatusHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            if (VERBOSE) Log.v(TAG, "Handler(): got msg=" + msg.what);
@@ -690,6 +703,15 @@ public class BluetoothPbapService extends ProfileService implements IObexConnect
                case SHUTDOWN:
                    closeService();
                    break;
                case LOAD_CONTACTS:
                    BluetoothPbapUtils.loadAllContacts(mContext, this);
                    break;
                case CHECK_SECONDARY_VERSION_COUNTER:
                    BluetoothPbapUtils.updateSecondaryVersionCounter(mContext, this);
                    break;
                case ROLLOVER_COUNTERS:
                    BluetoothPbapUtils.rolloverCounters();
                    break;
                default:
                    break;
            }
@@ -802,9 +824,17 @@ public class BluetoothPbapService extends ProfileService implements IObexConnect
        mSessionStatusHandler.sendMessage(mSessionStatusHandler.obtainMessage(START_LISTENER));
        if (mContactChangeObserver == null) {
            registerReceiver(mPbapReceiver, filter);
            try {
                if (DEBUG) Log.d(TAG, "Registering observer");
                mContactChangeObserver = new BluetoothPbapContentObserver();
                getContentResolver().registerContentObserver(
                    DevicePolicyUtils.getEnterprisePhoneUri(this), false, mContactChangeObserver);
                        DevicePolicyUtils.getEnterprisePhoneUri(this), false,
                        mContactChangeObserver);
            } catch (SQLiteException e) {
                Log.e(TAG, "SQLite exception: " + e);
            } catch (IllegalStateException e) {
                Log.e(TAG, "Illegal state exception, content observer is already registered");
            }
        }
        return true;
    }
@@ -937,18 +967,15 @@ public class BluetoothPbapService extends ProfileService implements IObexConnect
                    "OBEX Phonebook Access Server", mServerSockets.getRfcommChannel(),
                    mServerSockets.getL2capPsm(), SDP_PBAP_SERVER_VERSION,
                    SDP_PBAP_SUPPORTED_REPOSITORIES, SDP_PBAP_SUPPORTED_FEATURES);
            /* Here we might have changed crucial data, hence reset DB identifier */
            updateDbIdentifier();
            // fetch Pbap Params to check if significant change has happened to Database
            BluetoothPbapUtils.fetchPbapParams(mContext);

            if (DEBUG) Log.d(TAG, "PBAP server with handle:" + mSdpHandle);
        }
    }

    private void updateDbIdentifier() {
        mDbIndetifier.set(Calendar.getInstance().getTime().getTime());
    }

    long getDbIdentifier() {
        return mDbIndetifier.get();
        return BluetoothPbapUtils.mDbIdentifier.get();
    }

    private void setUserTimeoutAlarm() {
@@ -985,6 +1012,12 @@ public class BluetoothPbapService extends ProfileService implements IObexConnect
            } catch (IOException ex) {
                Log.e(TAG, "Caught exception starting obex server session" + ex.toString());
            }

            if (!BluetoothPbapUtils.contactsLoaded) {
                mSessionStatusHandler.sendMessage(
                        mSessionStatusHandler.obtainMessage(LOAD_CONTACTS));
            }

        } else if (permission == BluetoothDevice.ACCESS_REJECTED) {
            if (DEBUG) {
                Log.d(TAG, "incoming connection rejected from: " + sRemoteDeviceName
+427 −1

File changed.

Preview size limit exceeded, changes collapsed.

+1 −1
Original line number Diff line number Diff line
@@ -458,7 +458,7 @@ public class BluetoothPbapVcardManager {
        Log.d(TAG, "getCallHistoryPrimaryFolderVersion count is " + count + " type is " + type);
        ByteBuffer pvc = ByteBuffer.allocate(16);
        pvc.putLong(primaryVcMsb);
        Log.d(TAG, "primaryVersionCounter is " + BluetoothPbapService.primaryVersionCounter);
        Log.d(TAG, "primaryVersionCounter is " + BluetoothPbapUtils.primaryVersionCounter);
        pvc.putLong(count);
        return pvc.array();
    }