Loading android/app/src/com/android/bluetooth/btservice/AdapterService.java +100 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 { Loading Loading @@ -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(); Loading Loading @@ -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? Loading android/app/src/com/android/bluetooth/btservice/BondStateMachine.java +4 −0 Original line number Diff line number Diff line Loading @@ -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); } Loading android/app/src/com/android/bluetooth/hfp/AtPhonebook.java +41 −28 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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: Loading Loading @@ -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) { Loading android/app/src/com/android/bluetooth/hfp/HeadsetStateMachine.java +13 −9 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -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, Loading android/app/src/com/android/bluetooth/map/BluetoothMapService.java +44 −37 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -167,7 +167,6 @@ public class BluetoothMapService extends ProfileService { } private final void closeService() { if (DEBUG) Log.d(TAG, "MAP Service closeService in"); Loading @@ -186,7 +185,7 @@ public class BluetoothMapService extends ProfileService { } mIsWaitingAuthorization = false; mTrust = false; mPermission = BluetoothDevice.ACCESS_UNKNOWN; setState(BluetoothMap.STATE_DISCONNECTED); if (mWakeLock != null) { Loading Loading @@ -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); Loading Loading @@ -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(); Loading @@ -418,6 +413,7 @@ public class BluetoothMapService extends ProfileService { } } } public int getState() { return mState; } Loading Loading @@ -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) { Loading @@ -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: " + Loading @@ -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); Loading @@ -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()); } Loading Loading @@ -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; } Loading @@ -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 Loading
android/app/src/com/android/bluetooth/btservice/AdapterService.java +100 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 { Loading Loading @@ -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(); Loading Loading @@ -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? Loading
android/app/src/com/android/bluetooth/btservice/BondStateMachine.java +4 −0 Original line number Diff line number Diff line Loading @@ -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); } Loading
android/app/src/com/android/bluetooth/hfp/AtPhonebook.java +41 −28 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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: Loading Loading @@ -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) { Loading
android/app/src/com/android/bluetooth/hfp/HeadsetStateMachine.java +13 −9 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -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, Loading
android/app/src/com/android/bluetooth/map/BluetoothMapService.java +44 −37 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -167,7 +167,6 @@ public class BluetoothMapService extends ProfileService { } private final void closeService() { if (DEBUG) Log.d(TAG, "MAP Service closeService in"); Loading @@ -186,7 +185,7 @@ public class BluetoothMapService extends ProfileService { } mIsWaitingAuthorization = false; mTrust = false; mPermission = BluetoothDevice.ACCESS_UNKNOWN; setState(BluetoothMap.STATE_DISCONNECTED); if (mWakeLock != null) { Loading Loading @@ -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); Loading Loading @@ -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(); Loading @@ -418,6 +413,7 @@ public class BluetoothMapService extends ProfileService { } } } public int getState() { return mState; } Loading Loading @@ -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) { Loading @@ -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: " + Loading @@ -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); Loading @@ -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()); } Loading Loading @@ -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; } Loading @@ -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