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:<br><b><xliff:g id="device_name">%1$s</xliff:g></b><br><br>Make sure it is showing this passkey:<br><b><xliff:g id="passkey">%2$s</xliff:g></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:<br><b><xliff:g id="device_name">%1$s</xliff:g></b><br><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);