Merge "Make BluetoothCodecConfig and BluetoothCodecStatus public"
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index f367b6f..ec4d8ef 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -325,6 +325,17 @@
                 android:value="true" />
         </activity>
 
+        <activity android:name=".Settings$AdaptiveBrightnessActivity"
+            android:label="@string/auto_brightness_title"
+            android:exported="true">
+            <intent-filter>
+                <action android:name="android.settings.ADAPTIVE_BRIGHTNESS_SETTINGS" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+            <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
+                android:value="com.android.settings.display.AutoBrightnessSettings"/>
+        </activity>
+
         <activity
             android:name="Settings$ConfigureWifiSettingsActivity"
             android:label="@string/wifi_configure_settings_preference_title"
@@ -2279,6 +2290,7 @@
             android:exported="true">
             <intent-filter>
                 <action android:name="android.bluetooth.device.action.PAIRING_REQUEST" />
+                <action android:name="android.bluetooth.action.CSIS_SET_MEMBER_AVAILABLE"/>
             </intent-filter>
         </receiver>
 
diff --git a/res/layout/bluetooth_pin_confirm.xml b/res/layout/bluetooth_pin_confirm.xml
index 4891275..28ad1f6 100644
--- a/res/layout/bluetooth_pin_confirm.xml
+++ b/res/layout/bluetooth_pin_confirm.xml
@@ -65,6 +65,18 @@
             android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Subhead"
             android:visibility="gone" />
 
+        <TextView
+            android:id="@+id/pairing_group_message"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="@dimen/bluetooth_dialog_padding"
+            android:layout_marginEnd="@dimen/bluetooth_dialog_padding"
+            android:layout_marginBottom="@dimen/bluetooth_dialog_padding"
+            android:gravity="center_vertical"
+            android:text="@string/bluetooth_paring_group_msg"
+            android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body1"
+            android:visibility="gone" />
+
         <CheckBox
             android:id="@+id/phonebook_sharing_message_confirm_pin"
             android:layout_width="wrap_content"
diff --git a/res/values/strings.xml b/res/values/strings.xml
index aec90e1..86c80c3 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1832,6 +1832,9 @@
     <!-- Message for confirmation of passkey to complete pairing. [CHAR LIMIT=NONE] -->
     <string name="bluetooth_confirm_passkey_msg">To pair with:&lt;br>&lt;b><xliff:g id="device_name">%1$s</xliff:g>&lt;/b>&lt;br>&lt;br>Make sure it is showing this passkey:&lt;br>&lt;b><xliff:g id="passkey">%2$s</xliff:g>&lt;/b></string>
 
+    <!-- Pairing dialog text to remind user the pairing including all of the devices in a coordinated set. [CHAR LIMIT=NONE] -->
+    <string name="bluetooth_paring_group_msg">Confirm to pair with the coordinated set</string>
+
     <!-- Message when bluetooth incoming pairing request for (2.1 devices) dialog is showing -->
     <string name="bluetooth_incoming_pairing_msg">From:&lt;br>&lt;b><xliff:g id="device_name">%1$s</xliff:g>&lt;/b>&lt;br>&lt;br>Pair with this device?</string>
 
@@ -1909,6 +1912,8 @@
     <string name="device_details_title">Device details</string>
     <!-- Title of the item to show device MAC address -->
     <string name="bluetooth_device_mac_address">Device\'s Bluetooth address: <xliff:g id="address">%1$s</xliff:g></string>
+    <!-- Title of the items to show multuple devices MAC address [CHAR LIMIT=NONE]-->
+    <string name="bluetooth_multuple_devices_mac_address">Device\'s Bluetooth address:\n<xliff:g id="address">%1$s</xliff:g></string>
     <!-- Bluetooth device details. The title of a confirmation dialog for unpairing a paired device. [CHAR LIMIT=60] -->
     <string name="bluetooth_unpair_dialog_title">Forget device?</string>
     <!-- Content Description for companion device app associations removal button [CHAR LIMIT=28]-->
diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java
index 404207d..fdaa7c0 100644
--- a/src/com/android/settings/Settings.java
+++ b/src/com/android/settings/Settings.java
@@ -322,4 +322,6 @@
      * Activity for AppDashboard.
      */
     public static class AppDashboardActivity extends SettingsActivity {}
+
+    public static class AdaptiveBrightnessActivity extends SettingsActivity { /* empty */ }
 }
diff --git a/src/com/android/settings/bluetooth/AvailableMediaBluetoothDeviceUpdater.java b/src/com/android/settings/bluetooth/AvailableMediaBluetoothDeviceUpdater.java
index 27d63bf..14c20f1 100644
--- a/src/com/android/settings/bluetooth/AvailableMediaBluetoothDeviceUpdater.java
+++ b/src/com/android/settings/bluetooth/AvailableMediaBluetoothDeviceUpdater.java
@@ -70,9 +70,10 @@
             if (DBG) {
                 Log.d(TAG, "isFilterMatched() current audio profile : " + currentAudioProfile);
             }
-            // If device is Hearing Aid, it is compatible with HFP and A2DP.
+            // If device is Hearing Aid or LE Audio, it is compatible with HFP and A2DP.
             // It would show in Available Devices group.
-            if (cachedDevice.isConnectedHearingAidDevice()) {
+            if (cachedDevice.isConnectedHearingAidDevice()
+                    || cachedDevice.isConnectedLeAudioDevice()) {
                 return true;
             }
             // According to the current audio profile type,
diff --git a/src/com/android/settings/bluetooth/BluetoothDetailsMacAddressController.java b/src/com/android/settings/bluetooth/BluetoothDetailsMacAddressController.java
index dda247e..ec3e11f 100644
--- a/src/com/android/settings/bluetooth/BluetoothDetailsMacAddressController.java
+++ b/src/com/android/settings/bluetooth/BluetoothDetailsMacAddressController.java
@@ -16,6 +16,7 @@
 
 package com.android.settings.bluetooth;
 
+import android.bluetooth.BluetoothCsipSetCoordinator;
 import android.content.Context;
 
 import androidx.preference.PreferenceFragmentCompat;
@@ -50,8 +51,17 @@
 
     @Override
     protected void refresh() {
-        mFooterPreference.setTitle(mContext.getString(
+        if (mCachedDevice.getGroupId() != BluetoothCsipSetCoordinator.GROUP_ID_INVALID) {
+            StringBuilder title = new StringBuilder(mContext.getString(
+                R.string.bluetooth_multuple_devices_mac_address, mCachedDevice.getAddress()));
+            for (CachedBluetoothDevice member: mCachedDevice.getMemberDevice()) {
+                title.append("\n").append(member.getAddress());
+            }
+            mFooterPreference.setTitle(title);
+        } else {
+            mFooterPreference.setTitle(mContext.getString(
                 R.string.bluetooth_device_mac_address, mCachedDevice.getAddress()));
+        }
     }
 
     @Override
diff --git a/src/com/android/settings/bluetooth/BluetoothPairingController.java b/src/com/android/settings/bluetooth/BluetoothPairingController.java
index ca3dda6..b75e02a 100644
--- a/src/com/android/settings/bluetooth/BluetoothPairingController.java
+++ b/src/com/android/settings/bluetooth/BluetoothPairingController.java
@@ -28,6 +28,7 @@
 
 import com.android.settings.R;
 import com.android.settings.bluetooth.BluetoothPairingDialogFragment.BluetoothPairingDialogListener;
+import com.android.settingslib.bluetooth.CachedBluetoothDevice;
 import com.android.settingslib.bluetooth.LocalBluetoothManager;
 import com.android.settingslib.bluetooth.LocalBluetoothProfile;
 
@@ -64,6 +65,7 @@
     private String mDeviceName;
     private LocalBluetoothProfile mPbapClientProfile;
     private boolean mPbapAllowed;
+    private boolean mIsCoordinatedSetMember;
 
     /**
      * Creates an instance of a BluetoothPairingController.
@@ -90,6 +92,10 @@
         mDeviceName = mBluetoothManager.getCachedDeviceManager().getName(mDevice);
         mPbapClientProfile = mBluetoothManager.getProfileManager().getPbapClientProfile();
         mPasskeyFormatted = formatKey(mPasskey);
+        final CachedBluetoothDevice cachedDevice =
+                mBluetoothManager.getCachedDeviceManager().findDevice(mDevice);
+        mIsCoordinatedSetMember = cachedDevice != null
+                ? cachedDevice.isCoordinatedSetMemberDevice() : false;
     }
 
     @Override
@@ -156,6 +162,15 @@
     }
 
     /**
+     * A method for querying if the bluetooth device is a LE coordinated set member device.
+     *
+     * @return - A boolean indicating if the device is a CSIP supported device.
+     */
+    public boolean isCoordinatedSetMemberDevice() {
+        return mIsCoordinatedSetMember;
+    }
+
+    /**
      * A method for querying if the bluetooth device has a profile already set up on this device.
      *
      * @return - A boolean indicating if the device has previous knowledge of a profile for this
diff --git a/src/com/android/settings/bluetooth/BluetoothPairingDialogFragment.java b/src/com/android/settings/bluetooth/BluetoothPairingDialogFragment.java
index d38302d..9e36247 100644
--- a/src/com/android/settings/bluetooth/BluetoothPairingDialogFragment.java
+++ b/src/com/android/settings/bluetooth/BluetoothPairingDialogFragment.java
@@ -344,6 +344,9 @@
             pairingViewContent.setVisibility(View.VISIBLE);
             pairingViewContent.setText(mPairingController.getPairingContent());
         }
+        final TextView messagePairingSet = (TextView) view.findViewById(R.id.pairing_group_message);
+        messagePairingSet.setVisibility(mPairingController.isCoordinatedSetMemberDevice()
+                ? View.VISIBLE : View.GONE);
         return view;
     }
 
diff --git a/src/com/android/settings/bluetooth/BluetoothPairingRequest.java b/src/com/android/settings/bluetooth/BluetoothPairingRequest.java
index 993f584..6b80256 100644
--- a/src/com/android/settings/bluetooth/BluetoothPairingRequest.java
+++ b/src/com/android/settings/bluetooth/BluetoothPairingRequest.java
@@ -16,12 +16,16 @@
 
 package com.android.settings.bluetooth;
 
+import android.bluetooth.BluetoothCsipSetCoordinator;
 import android.bluetooth.BluetoothDevice;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
 import android.os.PowerManager;
 import android.os.UserHandle;
+import android.text.TextUtils;
+
+import com.android.settingslib.bluetooth.LocalBluetoothManager;
 
 /**
  * BluetoothPairingRequest is a receiver for any Bluetooth pairing request. It
@@ -34,36 +38,55 @@
     @Override
     public void onReceive(Context context, Intent intent) {
         String action = intent.getAction();
-        if (action == null || !action.equals(BluetoothDevice.ACTION_PAIRING_REQUEST)) {
+        if (action == null) {
             return;
         }
 
-        PowerManager powerManager = context.getSystemService(PowerManager.class);
         BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
-        int pairingVariant = intent.getIntExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT,
-                BluetoothDevice.ERROR);
-        String deviceAddress = device != null ? device.getAddress() : null;
-        String deviceName = device != null ? device.getName() : null;
-        boolean shouldShowDialog = LocalBluetoothPreferences.shouldShowDialogInForeground(
-                context, deviceAddress, deviceName);
+        final LocalBluetoothManager mBluetoothManager = Utils.getLocalBtManager(context);
+        if (TextUtils.equals(action, BluetoothDevice.ACTION_PAIRING_REQUEST)) {
+            PowerManager powerManager = context.getSystemService(PowerManager.class);
+            int pairingVariant = intent.getIntExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT,
+                    BluetoothDevice.ERROR);
+            String deviceAddress = device != null ? device.getAddress() : null;
+            String deviceName = device != null ? device.getName() : null;
+            boolean shouldShowDialog = LocalBluetoothPreferences.shouldShowDialogInForeground(
+                    context, deviceAddress, deviceName);
 
-        // Skips consent pairing dialog if the device was recently associated with CDM
-        if (pairingVariant == BluetoothDevice.PAIRING_VARIANT_CONSENT
-                && device.canBondWithoutDialog()) {
-            device.setPairingConfirmation(true);
-        } else if (powerManager.isInteractive() && shouldShowDialog) {
-            // Since the screen is on and the BT-related activity is in the foreground,
-            // just open the dialog
-            // convert broadcast intent into activity intent (same action string)
-            Intent pairingIntent = BluetoothPairingService.getPairingDialogIntent(context, intent,
-                    BluetoothDevice.EXTRA_PAIRING_INITIATOR_FOREGROUND);
+            // Skips consent pairing dialog if the device was recently associated with CDM
+            if (pairingVariant == BluetoothDevice.PAIRING_VARIANT_CONSENT
+                    && (device.canBondWithoutDialog()
+                    || mBluetoothManager.getCachedDeviceManager().isOngoingPairByCsip(device))) {
+                device.setPairingConfirmation(true);
+            } else if (powerManager.isInteractive() && shouldShowDialog) {
+                // Since the screen is on and the BT-related activity is in the foreground,
+                // just open the dialog
+                // convert broadcast intent into activity intent (same action string)
+                Intent pairingIntent = BluetoothPairingService.getPairingDialogIntent(context,
+                        intent, BluetoothDevice.EXTRA_PAIRING_INITIATOR_FOREGROUND);
 
-            context.startActivityAsUser(pairingIntent, UserHandle.CURRENT);
-        } else {
-            // Put up a notification that leads to the dialog
-            intent.setClass(context, BluetoothPairingService.class);
-            intent.setAction(BluetoothDevice.ACTION_PAIRING_REQUEST);
-            context.startServiceAsUser(intent, UserHandle.CURRENT);
+                context.startActivityAsUser(pairingIntent, UserHandle.CURRENT);
+            } else {
+                // Put up a notification that leads to the dialog
+                intent.setClass(context, BluetoothPairingService.class);
+                intent.setAction(BluetoothDevice.ACTION_PAIRING_REQUEST);
+                context.startServiceAsUser(intent, UserHandle.CURRENT);
+            }
+        } else if (TextUtils.equals(action,
+                BluetoothCsipSetCoordinator.ACTION_CSIS_SET_MEMBER_AVAILABLE)) {
+            if (device == null) {
+                return;
+            }
+
+            final int groupId = intent.getIntExtra(BluetoothCsipSetCoordinator.EXTRA_CSIS_GROUP_ID,
+                    BluetoothCsipSetCoordinator.GROUP_ID_INVALID);
+            if (groupId == BluetoothCsipSetCoordinator.GROUP_ID_INVALID) {
+                return;
+            }
+
+            if (mBluetoothManager.getCachedDeviceManager().shouldPairByCsip(device, groupId)) {
+                device.createBond(BluetoothDevice.TRANSPORT_LE);
+            }
         }
     }
 }
diff --git a/src/com/android/settings/bluetooth/ConnectedBluetoothDeviceUpdater.java b/src/com/android/settings/bluetooth/ConnectedBluetoothDeviceUpdater.java
index fc1b9b7..d1c45b6 100644
--- a/src/com/android/settings/bluetooth/ConnectedBluetoothDeviceUpdater.java
+++ b/src/com/android/settings/bluetooth/ConnectedBluetoothDeviceUpdater.java
@@ -70,9 +70,10 @@
             if (DBG) {
                 Log.d(TAG, "isFilterMatched() current audio profile : " + currentAudioProfile);
             }
-            // If device is Hearing Aid, it is compatible with HFP and A2DP.
+            // If device is Hearing Aid or LE Audio, it is compatible with HFP and A2DP.
             // It would not show in Connected Devices group.
-            if (cachedDevice.isConnectedHearingAidDevice()) {
+            if (cachedDevice.isConnectedHearingAidDevice()
+                    || cachedDevice.isConnectedLeAudioDevice()) {
                 return false;
             }
             // According to the current audio profile type,
diff --git a/src/com/android/settings/bluetooth/SavedBluetoothDeviceUpdater.java b/src/com/android/settings/bluetooth/SavedBluetoothDeviceUpdater.java
index dab4f23..f5bc279 100644
--- a/src/com/android/settings/bluetooth/SavedBluetoothDeviceUpdater.java
+++ b/src/com/android/settings/bluetooth/SavedBluetoothDeviceUpdater.java
@@ -65,7 +65,7 @@
             removePreferenceIfNecessary(bluetoothDevices, cachedManager);
             for (BluetoothDevice device : bluetoothDevices) {
                 final CachedBluetoothDevice cachedDevice = cachedManager.findDevice(device);
-                if (cachedDevice != null) {
+                if (cachedDevice != null && !cachedManager.isSubDevice(device)) {
                     update(cachedDevice);
                 }
             }
diff --git a/src/com/android/settings/core/gateway/SettingsGateway.java b/src/com/android/settings/core/gateway/SettingsGateway.java
index d0fb7ab..0ba389e 100644
--- a/src/com/android/settings/core/gateway/SettingsGateway.java
+++ b/src/com/android/settings/core/gateway/SettingsGateway.java
@@ -84,6 +84,7 @@
 import com.android.settings.deviceinfo.aboutphone.MyDeviceInfoFragment;
 import com.android.settings.deviceinfo.firmwareversion.FirmwareVersionSettings;
 import com.android.settings.deviceinfo.legal.ModuleLicensesDashboard;
+import com.android.settings.display.AutoBrightnessSettings;
 import com.android.settings.display.NightDisplaySettings;
 import com.android.settings.display.SmartAutoRotatePreferenceFragment;
 import com.android.settings.display.darkmode.DarkModeSettingsFragment;
@@ -313,7 +314,8 @@
             MediaControlsSettings.class.getName(),
             NetworkProviderSettings.class.getName(),
             AlarmsAndRemindersDetails.class.getName(),
-            MediaManagementAppsDetails.class.getName()
+            MediaManagementAppsDetails.class.getName(),
+            AutoBrightnessSettings.class.getName()
     };
 
     public static final String[] SETTINGS_FOR_RESTRICTED = {
@@ -344,6 +346,8 @@
             Settings.ConfigureNotificationSettingsActivity.class.getName(),
             Settings.ManageApplicationsActivity.class.getName(),
             Settings.PaymentSettingsActivity.class.getName(),
+            // Home page > Display
+            Settings.AdaptiveBrightnessActivity.class.getName(),
             // Home page > Security & screen lock
             Settings.LocationSettingsActivity.class.getName(),
             // Home page > System
diff --git a/src/com/android/settings/network/apn/ApnSettings.java b/src/com/android/settings/network/apn/ApnSettings.java
index 4df2e5e..dbd4ae0 100755
--- a/src/com/android/settings/network/apn/ApnSettings.java
+++ b/src/com/android/settings/network/apn/ApnSettings.java
@@ -322,6 +322,8 @@
         final StringBuilder where =
                 new StringBuilder("NOT (type='ia' AND (apn=\"\" OR apn IS NULL)) AND "
                 + "user_visible!=0");
+        // Remove Emergency type, users should not mess with that
+        where.append(" AND NOT (type='emergency')");
 
         if (mHideImsApn) {
             where.append(" AND NOT (type='ims')");
diff --git a/src/com/android/settings/nfc/NfcPaymentPreferenceController.java b/src/com/android/settings/nfc/NfcPaymentPreferenceController.java
index 9d3673d..edb12dd 100644
--- a/src/com/android/settings/nfc/NfcPaymentPreferenceController.java
+++ b/src/com/android/settings/nfc/NfcPaymentPreferenceController.java
@@ -20,6 +20,7 @@
 import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.nfc.NfcAdapter;
+import android.os.UserManager;
 import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -127,7 +128,10 @@
     public CharSequence getSummary() {
         final PaymentAppInfo defaultApp = mPaymentBackend.getDefaultApp();
         if (defaultApp != null) {
-            return defaultApp.label;
+            UserManager um = mContext.createContextAsUser(
+                    defaultApp.userHandle, /*flags=*/0).getSystemService(UserManager.class);
+
+            return defaultApp.label + " (" + um.getUserName() + ")";
         } else {
             return mContext.getText(R.string.nfc_payment_default_not_set);
         }
@@ -218,12 +222,15 @@
             }
 
             // Prevent checked callback getting called on recycled views
+            UserManager um = mContext.createContextAsUser(
+                    appInfo.userHandle, /*flags=*/0).getSystemService(UserManager.class);
+
             holder.radioButton.setOnCheckedChangeListener(null);
             holder.radioButton.setChecked(appInfo.isDefault);
-            holder.radioButton.setContentDescription(appInfo.label);
+            holder.radioButton.setContentDescription(appInfo.label + " (" + um.getUserName() + ")");
             holder.radioButton.setOnCheckedChangeListener(this);
             holder.radioButton.setTag(appInfo);
-            holder.radioButton.setText(appInfo.label);
+            holder.radioButton.setText(appInfo.label + " (" + um.getUserName() + ")");
             return convertView;
         }
 
@@ -245,7 +252,8 @@
 
         private void makeDefault(PaymentAppInfo appInfo) {
             if (!appInfo.isDefault) {
-                mPaymentBackend.setDefaultPaymentApp(appInfo.componentName);
+                mPaymentBackend.setDefaultPaymentApp(appInfo.componentName,
+                        appInfo.userHandle.getIdentifier());
             }
             final Dialog dialog = mPreference.getDialog();
             if (dialog != null) {
diff --git a/src/com/android/settings/nfc/PaymentBackend.java b/src/com/android/settings/nfc/PaymentBackend.java
index aec7343..542c95b 100644
--- a/src/com/android/settings/nfc/PaymentBackend.java
+++ b/src/com/android/settings/nfc/PaymentBackend.java
@@ -16,11 +16,10 @@
 
 package com.android.settings.nfc;
 
+import android.app.ActivityManager;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.pm.PackageManager;
-import android.content.res.Resources;
-import android.graphics.drawable.Drawable;
 import android.nfc.NfcAdapter;
 import android.nfc.cardemulation.ApduServiceInfo;
 import android.nfc.cardemulation.CardEmulation;
@@ -50,6 +49,15 @@
         boolean isDefault;
         public ComponentName componentName;
         public ComponentName settingsComponent;
+        public UserHandle userHandle;
+    }
+
+    /**
+     * ComponentName of the payment application and the userId that it belongs to.
+     */
+    public static class PaymentInfo {
+        public ComponentName componentName;
+        public int userId;
     }
 
     private final Context mContext;
@@ -80,40 +88,55 @@
 
     public void refresh() {
         PackageManager pm = mContext.getPackageManager();
-        List<ApduServiceInfo> serviceInfos =
-                mCardEmuManager.getServices(CardEmulation.CATEGORY_PAYMENT);
-        ArrayList<PaymentAppInfo> appInfos = new ArrayList<PaymentAppInfo>();
+        ArrayList<PaymentAppInfo> appInfosAllProfiles = new ArrayList<PaymentAppInfo>();
 
-        if (serviceInfos == null) {
-            makeCallbacks();
-            return;
-        }
+        UserManager um = mContext.createContextAsUser(
+                UserHandle.of(ActivityManager.getCurrentUser()), /*flags=*/0)
+                .getSystemService(UserManager.class);
+        List<UserHandle> userHandles = um.getEnabledProfiles();
 
-        ComponentName defaultAppName = getDefaultPaymentApp();
+        PaymentInfo defaultAppName = getDefaultPaymentApp();
         PaymentAppInfo foundDefaultApp = null;
-        for (ApduServiceInfo service : serviceInfos) {
-            PaymentAppInfo appInfo = new PaymentAppInfo();
-            appInfo.label = service.loadLabel(pm);
-            if (appInfo.label == null) {
-                appInfo.label = service.loadAppLabel(pm);
+        for (UserHandle uh : userHandles) {
+            List<ApduServiceInfo> serviceInfosByProfile =
+                    mCardEmuManager.getServices(CardEmulation.CATEGORY_PAYMENT, uh.getIdentifier());
+            if (serviceInfosByProfile == null) continue;
+
+            ArrayList<PaymentAppInfo> appInfos = new ArrayList<PaymentAppInfo>();
+
+            for (ApduServiceInfo service : serviceInfosByProfile) {
+                PaymentAppInfo appInfo = new PaymentAppInfo();
+                appInfo.userHandle = uh;
+                appInfo.label = service.loadLabel(pm);
+                if (appInfo.label == null) {
+                    appInfo.label = service.loadAppLabel(pm);
+                }
+                if (defaultAppName == null) {
+                    appInfo.isDefault = false;
+                } else {
+                    appInfo.isDefault =
+                            service.getComponent().equals(defaultAppName.componentName)
+                            && defaultAppName.userId == uh.getIdentifier();
+                }
+                if (appInfo.isDefault) {
+                    foundDefaultApp = appInfo;
+                }
+                appInfo.componentName = service.getComponent();
+                String settingsActivity = service.getSettingsActivityName();
+                if (settingsActivity != null) {
+                    appInfo.settingsComponent = new ComponentName(
+                            appInfo.componentName.getPackageName(),
+                            settingsActivity);
+                } else {
+                    appInfo.settingsComponent = null;
+                }
+                appInfo.description = service.getDescription();
+
+                appInfos.add(appInfo);
             }
-            appInfo.isDefault = service.getComponent().equals(defaultAppName);
-            if (appInfo.isDefault) {
-                foundDefaultApp = appInfo;
-            }
-            appInfo.componentName = service.getComponent();
-            String settingsActivity = service.getSettingsActivityName();
-            if (settingsActivity != null) {
-                appInfo.settingsComponent = new ComponentName(
-                        appInfo.componentName.getPackageName(),
-                        settingsActivity);
-            } else {
-                appInfo.settingsComponent = null;
-            }
-            appInfo.description = service.getDescription();
-            appInfos.add(appInfo);
+            appInfosAllProfiles.addAll(appInfos);
         }
-        mAppInfos = appInfos;
+        mAppInfos = appInfosAllProfiles;
         mDefaultAppInfo = foundDefaultApp;
         makeCallbacks();
     }
@@ -150,13 +173,36 @@
     }
 
     void setForegroundMode(boolean foreground) {
-        Settings.Secure.putIntForUser(mContext.getContentResolver(),
-                Settings.Secure.NFC_PAYMENT_FOREGROUND, foreground ? 1 : 0, UserHandle.myUserId());
+        UserManager um = mContext.createContextAsUser(
+                UserHandle.of(UserHandle.myUserId()), /*flags=*/0)
+                .getSystemService(UserManager.class);
+        List<UserHandle> userHandles = um.getEnabledProfiles();
+        for (UserHandle uh : userHandles) {
+            Settings.Secure.putIntForUser(mContext.getContentResolver(),
+                    Settings.Secure.NFC_PAYMENT_FOREGROUND, foreground ? 1 : 0, uh.getIdentifier());
+        }
     }
 
-    ComponentName getDefaultPaymentApp() {
+    PaymentInfo getDefaultPaymentApp() {
+        UserManager um = mContext.createContextAsUser(
+                UserHandle.of(ActivityManager.getCurrentUser()), /*flags=*/0)
+                .getSystemService(UserManager.class);
+        List<UserHandle> userHandles = um.getEnabledProfiles();
+        for (UserHandle uh : userHandles) {
+            ComponentName defaultApp = getDefaultPaymentApp(uh.getIdentifier());
+            if (defaultApp != null) {
+                PaymentInfo appInfo = new PaymentInfo();
+                appInfo.userId = uh.getIdentifier();
+                appInfo.componentName = defaultApp;
+                return appInfo;
+            }
+        }
+        return null;
+    }
+
+    ComponentName getDefaultPaymentApp(int userId) {
         String componentString = Settings.Secure.getStringForUser(mContext.getContentResolver(),
-                Settings.Secure.NFC_PAYMENT_DEFAULT_COMPONENT, UserHandle.myUserId());
+                Settings.Secure.NFC_PAYMENT_DEFAULT_COMPONENT, userId);
         if (componentString != null) {
             return ComponentName.unflattenFromString(componentString);
         } else {
@@ -165,9 +211,29 @@
     }
 
     public void setDefaultPaymentApp(ComponentName app) {
-        Settings.Secure.putStringForUser(mContext.getContentResolver(),
-                Settings.Secure.NFC_PAYMENT_DEFAULT_COMPONENT,
-                app != null ? app.flattenToString() : null, UserHandle.myUserId());
+        setDefaultPaymentApp(app, UserHandle.myUserId());
+    }
+
+    /**
+     *  Set Nfc default payment application
+     */
+    public void setDefaultPaymentApp(ComponentName app, int userId) {
+        UserManager um = mContext.createContextAsUser(
+                UserHandle.of(ActivityManager.getCurrentUser()), /*flags=*/0)
+                .getSystemService(UserManager.class);
+        List<UserHandle> userHandles = um.getEnabledProfiles();
+
+        for (UserHandle uh : userHandles) {
+            if (uh.getIdentifier() == userId) {
+                Settings.Secure.putStringForUser(mContext.getContentResolver(),
+                        Settings.Secure.NFC_PAYMENT_DEFAULT_COMPONENT,
+                        app != null ? app.flattenToString() : null, uh.getIdentifier());
+            } else {
+                Settings.Secure.putStringForUser(mContext.getContentResolver(),
+                        Settings.Secure.NFC_PAYMENT_DEFAULT_COMPONENT,
+                        null, uh.getIdentifier());
+            }
+        }
         refresh();
     }
 
diff --git a/src/com/android/settings/nfc/PaymentDefaultDialog.java b/src/com/android/settings/nfc/PaymentDefaultDialog.java
index 1aa8dca..df6d86f 100644
--- a/src/com/android/settings/nfc/PaymentDefaultDialog.java
+++ b/src/com/android/settings/nfc/PaymentDefaultDialog.java
@@ -21,12 +21,14 @@
 import android.content.Intent;
 import android.nfc.cardemulation.CardEmulation;
 import android.os.Bundle;
+import android.os.UserHandle;
 import android.util.Log;
 
 import com.android.internal.app.AlertActivity;
 import com.android.internal.app.AlertController;
 import com.android.settings.R;
 import com.android.settings.nfc.PaymentBackend.PaymentAppInfo;
+import com.android.settings.nfc.PaymentBackend.PaymentInfo;
 
 import java.util.List;
 
@@ -37,7 +39,7 @@
     private static final int PAYMENT_APP_MAX_CAPTION_LENGTH = 40;
 
     private PaymentBackend mBackend;
-    private ComponentName mNewDefault;
+    private PaymentInfo mNewDefault;
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
@@ -51,9 +53,10 @@
         ComponentName component = intent.getParcelableExtra(
                 CardEmulation.EXTRA_SERVICE_COMPONENT);
         String category = intent.getStringExtra(CardEmulation.EXTRA_CATEGORY);
+        int userId = intent.getIntExtra(CardEmulation.EXTRA_USERID, UserHandle.myUserId());
 
         setResult(RESULT_CANCELED);
-        if (!buildDialog(component, category)) {
+        if (!buildDialog(component, category, userId)) {
             finish();
         }
 
@@ -63,7 +66,7 @@
     public void onClick(DialogInterface dialog, int which) {
         switch (which) {
             case BUTTON_POSITIVE:
-                mBackend.setDefaultPaymentApp(mNewDefault);
+                mBackend.setDefaultPaymentApp(mNewDefault.componentName, mNewDefault.userId);
                 setResult(RESULT_OK);
                 break;
             case BUTTON_NEGATIVE:
@@ -71,7 +74,7 @@
         }
     }
 
-    private boolean buildDialog(ComponentName component, String category) {
+    private boolean buildDialog(ComponentName component, String category, int userId) {
         if (component == null || category == null) {
             Log.e(TAG, "Component or category are null");
             return false;
@@ -88,10 +91,12 @@
 
         List<PaymentAppInfo> services = mBackend.getPaymentAppInfos();
         for (PaymentAppInfo service : services) {
-            if (component.equals(service.componentName)) {
+            // check if userId matches
+            if (component.equals(service.componentName)
+                    && service.userHandle.getIdentifier() == userId) {
                 requestedPaymentApp = service;
             }
-            if (service.isDefault) {
+            if (service.isDefault && service.userHandle.getIdentifier() == userId) {
                 defaultPaymentApp = service;
             }
         }
@@ -102,13 +107,17 @@
         }
 
         // Get current mode and default component
-        ComponentName defaultComponent = mBackend.getDefaultPaymentApp();
-        if (defaultComponent != null && defaultComponent.equals(component)) {
+        PaymentInfo defaultComponent = mBackend.getDefaultPaymentApp();
+        if (defaultComponent != null && defaultComponent.componentName.equals(component)
+                && defaultComponent.userId == userId) {
             Log.e(TAG, "Component " + component + " is already default.");
             return false;
         }
 
-        mNewDefault = component;
+        mNewDefault = new PaymentInfo();
+        mNewDefault.componentName = component;
+        mNewDefault.userId = userId;
+
         // Compose dialog; get
         final AlertController.AlertParams p = mAlertParams;
         if (defaultPaymentApp == null) {
diff --git a/tests/robotests/src/com/android/settings/bluetooth/AvailableMediaBluetoothDeviceUpdaterTest.java b/tests/robotests/src/com/android/settings/bluetooth/AvailableMediaBluetoothDeviceUpdaterTest.java
index 924e246..3cdff6e 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/AvailableMediaBluetoothDeviceUpdaterTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/AvailableMediaBluetoothDeviceUpdaterTest.java
@@ -235,6 +235,32 @@
     }
 
     @Test
+    public void onProfileConnectionStateChanged_leAudioDeviceConnected_notInCall_addsPreference() {
+        mAudioManager.setMode(AudioManager.MODE_NORMAL);
+        when(mBluetoothDeviceUpdater
+                .isDeviceConnected(any(CachedBluetoothDevice.class))).thenReturn(true);
+        when(mCachedBluetoothDevice.isConnectedLeAudioDevice()).thenReturn(true);
+
+        mBluetoothDeviceUpdater.onProfileConnectionStateChanged(mCachedBluetoothDevice,
+                BluetoothProfile.STATE_CONNECTED, BluetoothProfile.LE_AUDIO);
+
+        verify(mBluetoothDeviceUpdater).addPreference(mCachedBluetoothDevice);
+    }
+
+    @Test
+    public void onProfileConnectionStateChanged_leAudioDeviceConnected_inCall_addsPreference() {
+        mAudioManager.setMode(AudioManager.MODE_IN_CALL);
+        when(mBluetoothDeviceUpdater
+                .isDeviceConnected(any(CachedBluetoothDevice.class))).thenReturn(true);
+        when(mCachedBluetoothDevice.isConnectedLeAudioDevice()).thenReturn(true);
+
+        mBluetoothDeviceUpdater.onProfileConnectionStateChanged(mCachedBluetoothDevice,
+                BluetoothProfile.STATE_CONNECTED, BluetoothProfile.LE_AUDIO);
+
+        verify(mBluetoothDeviceUpdater).addPreference(mCachedBluetoothDevice);
+    }
+
+    @Test
     public void onProfileConnectionStateChanged_deviceDisconnected_removePreference() {
         mBluetoothDeviceUpdater.onProfileConnectionStateChanged(mCachedBluetoothDevice,
                 BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.A2DP);
diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothPairingDialogTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothPairingDialogTest.java
index be733ec..a53e693 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothPairingDialogTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothPairingDialogTest.java
@@ -427,6 +427,34 @@
         userEntryDialogExistingTextTest("test");
     }
 
+    @Test
+    public void groupPairing_setMemberDevice_showsMessageHint() {
+        // set the correct dialog type
+        when(controller.getDialogType()).thenReturn(BluetoothPairingController.CONFIRMATION_DIALOG);
+        when(controller.isCoordinatedSetMemberDevice()).thenReturn(true);
+
+        // build the fragment
+        BluetoothPairingDialogFragment frag = makeFragment();
+
+        // verify message is what we expect it to be and is visible
+        TextView message = frag.getmDialog().findViewById(R.id.pairing_group_message);
+        assertThat(message.getVisibility()).isEqualTo(View.VISIBLE);
+    }
+
+    @Test
+    public void groupPairing_nonSetMemberDevice_hidesMessageHint() {
+        // set the correct dialog type
+        when(controller.getDialogType()).thenReturn(BluetoothPairingController.CONFIRMATION_DIALOG);
+        when(controller.isCoordinatedSetMemberDevice()).thenReturn(false);
+
+        // build the fragment
+        BluetoothPairingDialogFragment frag = makeFragment();
+
+        // verify message is what we expect it to be and is visible
+        TextView message = frag.getmDialog().findViewById(R.id.pairing_group_message);
+        assertThat(message.getVisibility()).isEqualTo(View.GONE);
+    }
+
     // Runs a test simulating the user entry dialog type in a situation like device rotation, where
     // the dialog fragment gets created and we already have some existing text entered into the
     // pin field.
diff --git a/tests/robotests/src/com/android/settings/bluetooth/ConnectedBluetoothDeviceUpdaterTest.java b/tests/robotests/src/com/android/settings/bluetooth/ConnectedBluetoothDeviceUpdaterTest.java
index ea91fed..98f1fe3 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/ConnectedBluetoothDeviceUpdaterTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/ConnectedBluetoothDeviceUpdaterTest.java
@@ -235,6 +235,33 @@
     }
 
     @Test
+    public void onProfileConnectionStateChanged_leAudioDeviceConnected_inCall_removesPreference() {
+        mAudioManager.setMode(AudioManager.MODE_IN_CALL);
+        when(mBluetoothDeviceUpdater
+                .isDeviceConnected(any(CachedBluetoothDevice.class))).thenReturn(true);
+        when(mCachedBluetoothDevice.isConnectedLeAudioDevice()).thenReturn(true);
+
+        mBluetoothDeviceUpdater.onProfileConnectionStateChanged(mCachedBluetoothDevice,
+                BluetoothProfile.STATE_CONNECTED, BluetoothProfile.LE_AUDIO);
+
+        verify(mBluetoothDeviceUpdater).removePreference(mCachedBluetoothDevice);
+    }
+
+    @Test
+    public void onProfileConnectionStateChanged_leAudioDeviceConnected_notInCall_removesPreference()
+    {
+        mAudioManager.setMode(AudioManager.MODE_NORMAL);
+        when(mBluetoothDeviceUpdater
+                .isDeviceConnected(any(CachedBluetoothDevice.class))).thenReturn(true);
+        when(mCachedBluetoothDevice.isConnectedLeAudioDevice()).thenReturn(true);
+
+        mBluetoothDeviceUpdater.onProfileConnectionStateChanged(mCachedBluetoothDevice,
+                BluetoothProfile.STATE_CONNECTED, BluetoothProfile.LE_AUDIO);
+
+        verify(mBluetoothDeviceUpdater).removePreference(mCachedBluetoothDevice);
+    }
+
+    @Test
     public void onProfileConnectionStateChanged_deviceDisconnected_removePreference() {
         mBluetoothDeviceUpdater.onProfileConnectionStateChanged(mCachedBluetoothDevice,
                 BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.A2DP);