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

Commit 92248abf authored by Edward Jee's avatar Edward Jee Committed by Android Git Automerger
Browse files

am b81b99be: am b7dbc071: am d6ae28f1: am 700ea968: Merge "Migrates PBAP and...

am b81b99be: am b7dbc071: am d6ae28f1: am 700ea968: Merge "Migrates PBAP and MAP access permission data from Settings to Bluetooth." into lmp-dev

* commit 'b81b99be':
  Migrates PBAP and MAP access permission data from Settings to Bluetooth.
parents b451605c b81b99be
Loading
Loading
Loading
Loading
+100 −0
Original line number Diff line number Diff line
@@ -38,6 +38,7 @@ import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
@@ -107,6 +108,11 @@ public class AdapterService extends Service {
    static final String BLUETOOTH_PERM = android.Manifest.permission.BLUETOOTH;
    static final String RECEIVE_MAP_PERM = android.Manifest.permission.RECEIVE_BLUETOOTH_MAP;

    private static final String PHONEBOOK_ACCESS_PERMISSION_PREFERENCE_FILE =
            "phonebook_access_permission";
    private static final String MESSAGE_ACCESS_PERMISSION_PREFERENCE_FILE =
            "message_access_permission";

    private static final int ADAPTER_SERVICE_TYPE=Service.START_STICKY;

    static {
@@ -962,6 +968,50 @@ public class AdapterService extends Service {
            return service.setPairingConfirmation(device, accept);
        }

        public int getPhonebookAccessPermission(BluetoothDevice device) {
            if (!Utils.checkCaller()) {
                Log.w(TAG, "getPhonebookAccessPermission() - Not allowed for non-active user");
                return BluetoothDevice.ACCESS_UNKNOWN;
            }

            AdapterService service = getService();
            if (service == null) return BluetoothDevice.ACCESS_UNKNOWN;
            return service.getPhonebookAccessPermission(device);
        }

        public boolean setPhonebookAccessPermission(BluetoothDevice device, int value) {
            if (!Utils.checkCaller()) {
                Log.w(TAG, "setPhonebookAccessPermission() - Not allowed for non-active user");
                return false;
            }

            AdapterService service = getService();
            if (service == null) return false;
            return service.setPhonebookAccessPermission(device, value);
        }

        public int getMessageAccessPermission(BluetoothDevice device) {
            if (!Utils.checkCaller()) {
                Log.w(TAG, "getMessageAccessPermission() - Not allowed for non-active user");
                return BluetoothDevice.ACCESS_UNKNOWN;
            }

            AdapterService service = getService();
            if (service == null) return BluetoothDevice.ACCESS_UNKNOWN;
            return service.getMessageAccessPermission(device);
        }

        public boolean setMessageAccessPermission(BluetoothDevice device, int value) {
            if (!Utils.checkCaller()) {
                Log.w(TAG, "setMessageAccessPermission() - Not allowed for non-active user");
                return false;
            }

            AdapterService service = getService();
            if (service == null) return false;
            return service.setMessageAccessPermission(device, value);
        }

        public void sendConnectionStateChange(BluetoothDevice
                device, int profile, int state, int prevState) {
            AdapterService service = getService();
@@ -1479,6 +1529,56 @@ public class AdapterService extends Service {
                accept, 0);
    }

    int getPhonebookAccessPermission(BluetoothDevice device) {
        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
        SharedPreferences pref = getSharedPreferences(PHONEBOOK_ACCESS_PERMISSION_PREFERENCE_FILE,
                Context.MODE_PRIVATE);
        if (!pref.contains(device.getAddress())) {
            return BluetoothDevice.ACCESS_UNKNOWN;
        }
        return pref.getBoolean(device.getAddress(), false)
                ? BluetoothDevice.ACCESS_ALLOWED : BluetoothDevice.ACCESS_REJECTED;
    }

    boolean setPhonebookAccessPermission(BluetoothDevice device, int value) {
        enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED,
                                       "Need BLUETOOTH PRIVILEGED permission");
        SharedPreferences pref = getSharedPreferences(PHONEBOOK_ACCESS_PERMISSION_PREFERENCE_FILE,
                Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = pref.edit();
        if (value == BluetoothDevice.ACCESS_UNKNOWN) {
            editor.remove(device.getAddress());
        } else {
            editor.putBoolean(device.getAddress(), value == BluetoothDevice.ACCESS_ALLOWED);
        }
        return editor.commit();
    }

    int getMessageAccessPermission(BluetoothDevice device) {
        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
        SharedPreferences pref = getSharedPreferences(MESSAGE_ACCESS_PERMISSION_PREFERENCE_FILE,
                Context.MODE_PRIVATE);
        if (!pref.contains(device.getAddress())) {
            return BluetoothDevice.ACCESS_UNKNOWN;
        }
        return pref.getBoolean(device.getAddress(), false)
                ? BluetoothDevice.ACCESS_ALLOWED : BluetoothDevice.ACCESS_REJECTED;
    }

    boolean setMessageAccessPermission(BluetoothDevice device, int value) {
        enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED,
                                       "Need BLUETOOTH PRIVILEGED permission");
        SharedPreferences pref = getSharedPreferences(MESSAGE_ACCESS_PERMISSION_PREFERENCE_FILE,
                Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = pref.edit();
        if (value == BluetoothDevice.ACCESS_UNKNOWN) {
            editor.remove(device.getAddress());
        } else {
            editor.putBoolean(device.getAddress(), value == BluetoothDevice.ACCESS_ALLOWED);
        }
        return editor.commit();
    }

     void sendConnectionStateChange(BluetoothDevice
            device, int profile, int state, int prevState) {
        // TODO(BT) permission check?
+4 −0
Original line number Diff line number Diff line
@@ -192,6 +192,10 @@ final class BondStateMachine extends StateMachine {
                        }
                        if (newState == BluetoothDevice.BOND_NONE)
                        {
                            mAdapterService.setPhonebookAccessPermission(dev,
                                    BluetoothDevice.ACCESS_UNKNOWN);
                            mAdapterService.setMessageAccessPermission(dev,
                                    BluetoothDevice.ACCESS_UNKNOWN);
                            // Set the profile Priorities to undefined
                            clearProfilePriorty(dev);
                        }
+41 −28
Original line number Diff line number Diff line
@@ -141,8 +141,8 @@ public class AtPhonebook {
        return mCheckingAccessPermission;
    }

    public void setCheckingAccessPermission(boolean checkAccessPermission) {
        mCheckingAccessPermission = checkAccessPermission;
    public void setCheckingAccessPermission(boolean checkingAccessPermission) {
        mCheckingAccessPermission = checkingAccessPermission;
    }

    public void setCpbrIndex(int cpbrIndex) {
@@ -346,15 +346,24 @@ public class AtPhonebook {
                mCpbrIndex2 = index2;
                mCheckingAccessPermission = true;

                if (checkAccessPermission(remoteDevice)) {
                int permission = checkAccessPermission(remoteDevice);
                if (permission == BluetoothDevice.ACCESS_ALLOWED) {
                    mCheckingAccessPermission = false;
                    atCommandResult = processCpbrCommand(remoteDevice);
                    mCpbrIndex1 = mCpbrIndex2 = -1;
                    mStateMachine.atResponseCodeNative(atCommandResult, atCommandErrorCode,
                                         getByteAddress(remoteDevice));
                    break;
                } else if (permission == BluetoothDevice.ACCESS_REJECTED) {
                    mCheckingAccessPermission = false;
                    mCpbrIndex1 = mCpbrIndex2 = -1;
                    mStateMachine.atResponseCodeNative(HeadsetHalConstants.AT_RESPONSE_ERROR,
                            BluetoothCmeError.AG_FAILURE, getByteAddress(remoteDevice));
                }
                // no reponse here, will continue the process in handleAccessPermissionResult
                // If checkAccessPermission(remoteDevice) has returned
                // BluetoothDevice.ACCESS_UNKNOWN, we will continue the process in
                // HeadsetStateMachine.handleAccessPermissionResult(Intent) once HeadsetService
                // receives BluetoothDevice.ACTION_CONNECTION_ACCESS_REPLY from Settings app.
                break;
            case TYPE_UNKNOWN:
            default:
@@ -579,27 +588,31 @@ public class AtPhonebook {
        return atCommandResult;
    }

    // Check if the remote device has premission to read our phone book
    // Return true if it has the permission
    // false if not known and we have sent our Intent to check
    private boolean checkAccessPermission(BluetoothDevice remoteDevice) {
    /**
     * Checks if the remote device has premission to read our phone book.
     * If the return value is {@link BluetoothDevice#ACCESS_UNKNOWN}, it means this method has sent
     * an Intent to Settings application to ask user preference.
     *
     * @return {@link BluetoothDevice#ACCESS_UNKNOWN}, {@link BluetoothDevice#ACCESS_ALLOWED} or
     *         {@link BluetoothDevice#ACCESS_REJECTED}.
     */
    private int checkAccessPermission(BluetoothDevice remoteDevice) {
        log("checkAccessPermission");
        boolean trust = remoteDevice.getTrustState();

        if (trust) {
            return true;
        }
        int permission = remoteDevice.getPhonebookAccessPermission();

        if (permission == BluetoothDevice.ACCESS_UNKNOWN) {
            log("checkAccessPermission - ACTION_CONNECTION_ACCESS_REQUEST");
            Intent intent = new Intent(BluetoothDevice.ACTION_CONNECTION_ACCESS_REQUEST);
            intent.setClassName(ACCESS_AUTHORITY_PACKAGE, ACCESS_AUTHORITY_CLASS);
            intent.putExtra(BluetoothDevice.EXTRA_ACCESS_REQUEST_TYPE,
            BluetoothDevice.REQUEST_TYPE_PHONEBOOK_ACCESS);
            intent.putExtra(BluetoothDevice.EXTRA_DEVICE, remoteDevice);
        // Leave EXTRA_PACKAGE_NAME and EXTRA_CLASS_NAME field empty
        // BluetoothHandsfree's broadcast receiver is anonymous, cannot be targeted
            // Leave EXTRA_PACKAGE_NAME and EXTRA_CLASS_NAME field empty.
            // BluetoothHandsfree's broadcast receiver is anonymous, cannot be targeted.
            mContext.sendOrderedBroadcast(intent, BLUETOOTH_ADMIN_PERM);
        return false;
        }

        return permission;
    }

    private static String getPhoneType(int type) {
+13 −9
Original line number Diff line number Diff line
@@ -3208,12 +3208,17 @@ final class HeadsetStateMachine extends StateMachine {
            // has set mCheckingAccessPermission to false
            if (intent.getAction().equals(BluetoothDevice.ACTION_CONNECTION_ACCESS_REPLY)) {
                if (intent.getIntExtra(BluetoothDevice.EXTRA_CONNECTION_ACCESS_RESULT,
                    BluetoothDevice.CONNECTION_ACCESS_NO) ==
                    BluetoothDevice.CONNECTION_ACCESS_YES) {
                                       BluetoothDevice.CONNECTION_ACCESS_NO)
                        == BluetoothDevice.CONNECTION_ACCESS_YES) {
                    if (intent.getBooleanExtra(BluetoothDevice.EXTRA_ALWAYS_ALLOWED, false)) {
                        mCurrentDevice.setTrust(true);
                        mCurrentDevice.setPhonebookAccessPermission(BluetoothDevice.ACCESS_ALLOWED);
                    }
                    atCommandResult = mPhonebook.processCpbrCommand(device);
                } else {
                    if (intent.getBooleanExtra(BluetoothDevice.EXTRA_ALWAYS_ALLOWED, false)) {
                        mCurrentDevice.setPhonebookAccessPermission(
                                BluetoothDevice.ACCESS_REJECTED);
                    }
                }
            }
            mPhonebook.setCpbrIndex(-1);
@@ -3221,11 +3226,10 @@ final class HeadsetStateMachine extends StateMachine {

            if (atCommandResult >= 0) {
                atResponseCodeNative(atCommandResult, atCommandErrorCode, getByteAddress(device));
            }
            else
            } else {
                log("handleAccessPermissionResult - RESULT_NONE");
            }
        else {
        } else {
            Log.e(TAG, "Phonebook handle null");
            if (device != null) {
                atResponseCodeNative(HeadsetHalConstants.AT_RESPONSE_ERROR, 0,
+44 −37
Original line number Diff line number Diff line
@@ -149,7 +149,7 @@ public class BluetoothMapService extends ProfileService {

    private boolean mIsWaitingAuthorization = false;
    private boolean mRemoveTimeoutMsg = false;
    private boolean mTrust = false; // Temp. fix for missing BluetoothDevice.getTrustState()
    private int mPermission = BluetoothDevice.ACCESS_UNKNOWN;
    private boolean mAccountChanged = false;

    // package and class name to which we send intent to check phone book access permission
@@ -167,7 +167,6 @@ public class BluetoothMapService extends ProfileService {

    }


    private final void closeService() {
        if (DEBUG) Log.d(TAG, "MAP Service closeService in");

@@ -186,7 +185,7 @@ public class BluetoothMapService extends ProfileService {
        }

        mIsWaitingAuthorization = false;
        mTrust = false;
        mPermission = BluetoothDevice.ACCESS_UNKNOWN;
        setState(BluetoothMap.STATE_DISCONNECTED);

        if (mWakeLock != null) {
@@ -296,7 +295,7 @@ public class BluetoothMapService extends ProfileService {

        if(lastMasInst) {
            setState(BluetoothMap.STATE_DISCONNECTED);
            mTrust = false;
            mPermission = BluetoothDevice.ACCESS_UNKNOWN;
            mRemoteDevice = null;
            if(mAccountChanged) {
                updateMasInstances(UPDATE_MAS_INSTANCES_ACCOUNT_DISCONNECT);
@@ -396,17 +395,13 @@ public class BluetoothMapService extends ProfileService {
            return;
        }
        BluetoothMapMasInstance masInst = mMasInstances.get(masId);
        // getTrustState() is not implemented, use local cache
        // boolean trust = mRemoteDevice.getTrustState(); // Need to ensure we are still trusted
        boolean trust = mTrust;
        if (DEBUG) Log.d(TAG, "GetTrustState() = " + trust);

        if (trust) {
        // Need to ensure we are still allowed.
        if (DEBUG) Log.d(TAG, "mPermission = " + mPermission);
        if (mPermission == BluetoothDevice.ACCESS_ALLOWED) {
            try {
                if (DEBUG) Log.d(TAG, "incoming connection accepted from: "
                        + sRemoteDeviceName + " automatically as trusted device");
                if(mBluetoothMnsObexClient != null
                   && masInst != null) {
                if (mBluetoothMnsObexClient != null && masInst != null) {
                    masInst.startObexServerSession(mBluetoothMnsObexClient);
                } else {
                    startObexServerSessions();
@@ -418,6 +413,7 @@ public class BluetoothMapService extends ProfileService {
            }
        }
    }

    public int getState() {
        return mState;
    }
@@ -756,8 +752,9 @@ public class BluetoothMapService extends ProfileService {
     * @return
     */
    public boolean onConnect(BluetoothDevice remoteDevice, BluetoothMapMasInstance masInst) {

        boolean sendIntent = false;
        boolean cancelConnection = false;

        // As this can be called from each MasInstance, we need to lock access to member variables
        synchronized(this) {
            if (mRemoteDevice == null) {
@@ -768,10 +765,13 @@ public class BluetoothMapService extends ProfileService {
                    sRemoteDeviceName = getString(R.string.defaultname);
                }

                if(mTrust == false) {
                mPermission = mRemoteDevice.getMessageAccessPermission();
                if (mPermission == BluetoothDevice.ACCESS_UNKNOWN) {
                    sendIntent = true;
                    mIsWaitingAuthorization = true;
                    setUserTimeoutAlarm();
                } else if (mPermission == BluetoothDevice.ACCESS_REJECTED) {
                    cancelConnection = true;
                }
            } else if (!mRemoteDevice.equals(remoteDevice)) {
                Log.w(TAG, "Unexpected connection from a second Remote Device received. name: " +
@@ -781,11 +781,9 @@ public class BluetoothMapService extends ProfileService {
            } // Else second connection to same device, just continue
        }


        if(sendIntent == true) {
            /* This will trigger */
            Intent intent = new
                Intent(BluetoothDevice.ACTION_CONNECTION_ACCESS_REQUEST);
        if (sendIntent) {
            // This will trigger Settings app's dialog.
            Intent intent = new Intent(BluetoothDevice.ACTION_CONNECTION_ACCESS_REQUEST);
            intent.setClassName(ACCESS_AUTHORITY_PACKAGE, ACCESS_AUTHORITY_CLASS);
            intent.putExtra(BluetoothDevice.EXTRA_ACCESS_REQUEST_TYPE,
                            BluetoothDevice.REQUEST_TYPE_MESSAGE_ACCESS);
@@ -796,11 +794,9 @@ public class BluetoothMapService extends ProfileService {
                    + sRemoteDeviceName);
            //Queue USER_TIMEOUT to disconnect MAP OBEX session. If user doesn't
            //accept or reject authorization request




        } else {
        } else if (cancelConnection) {
            sendConnectCancelMessage();
        } else if (mPermission == BluetoothDevice.ACCESS_ALLOWED) {
            /* Signal to the service that we have a incoming connection. */
            sendConnectMessage(masInst.getMasId());
        }
@@ -892,8 +888,8 @@ public class BluetoothMapService extends ProfileService {
                                               BluetoothDevice.REQUEST_TYPE_PHONEBOOK_ACCESS);
                if (DEBUG) Log.d(TAG, "Received ACTION_CONNECTION_ACCESS_REPLY:" +
                           requestType + "isWaitingAuthorization:" + mIsWaitingAuthorization);
                if ((!mIsWaitingAuthorization) ||
                    (requestType != BluetoothDevice.REQUEST_TYPE_MESSAGE_ACCESS)) {
                if ((!mIsWaitingAuthorization)
                        || (requestType != BluetoothDevice.REQUEST_TYPE_MESSAGE_ACCESS)) {
                    // this reply is not for us
                    return;
                }
@@ -906,20 +902,31 @@ public class BluetoothMapService extends ProfileService {
                }

                if (intent.getIntExtra(BluetoothDevice.EXTRA_CONNECTION_ACCESS_RESULT,
                                       BluetoothDevice.CONNECTION_ACCESS_NO) ==
                    BluetoothDevice.CONNECTION_ACCESS_YES) {
                                       BluetoothDevice.CONNECTION_ACCESS_NO)
                        == BluetoothDevice.CONNECTION_ACCESS_YES) {
                    // Bluetooth connection accepted by user
                    mPermission = BluetoothDevice.ACCESS_ALLOWED;
                    if (intent.getBooleanExtra(BluetoothDevice.EXTRA_ALWAYS_ALLOWED, false)) {
                        // Not implemented in BluetoothDevice
                        //boolean result = mRemoteDevice.setTrust(true);
                        //if (DEBUG) Log.d(TAG, "setTrust() result=" + result);
                        boolean result = mRemoteDevice.setMessageAccessPermission(
                                BluetoothDevice.ACCESS_ALLOWED);
                        if (DEBUG) {
                            Log.d(TAG, "setMessageAccessPermission(ACCESS_ALLOWED) result="
                                    + result);
                        }
                    }
                    mTrust = true;
                    sendConnectMessage(-1); // -1 indicates all MAS instances
                } else {
                    // Auth. declined by user, serverSession should not be running, but
                    // call stop anyway to restart listener.
                    mTrust = false;
                    mPermission = BluetoothDevice.ACCESS_REJECTED;
                    if (intent.getBooleanExtra(BluetoothDevice.EXTRA_ALWAYS_ALLOWED, false)) {
                        boolean result = mRemoteDevice.setMessageAccessPermission(
                                BluetoothDevice.ACCESS_REJECTED);
                        if (DEBUG) {
                            Log.d(TAG, "setMessageAccessPermission(ACCESS_REJECTED) result="
                                    + result);
                        }
                    }
                    sendConnectCancelMessage();
                }
            } else if (action.equals(ACTION_SHOW_MAPS_EMAIL_SETTINGS)) {
Loading