diff --git a/res/layout/edit_user_info_dialog_content.xml b/res/layout/edit_user_info_dialog_content.xml
index 62c711b789e..895cef63fb9 100644
--- a/res/layout/edit_user_info_dialog_content.xml
+++ b/res/layout/edit_user_info_dialog_content.xml
@@ -42,7 +42,6 @@
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textAlignment="viewStart"
- android:labelFor="@id/user_photo"
android:inputType="text|textCapWords"
android:selectAllOnFocus="true"
android:hint="@string/user_nickname"
diff --git a/res/layout/notification_history_log_row.xml b/res/layout/notification_history_log_row.xml
index 4f45fecd0ae..04438e33f61 100644
--- a/res/layout/notification_history_log_row.xml
+++ b/res/layout/notification_history_log_row.xml
@@ -76,7 +76,7 @@
android:layout_height="wrap_content"
android:layout_gravity="left|center_vertical"
android:ellipsize="end"
- android:singleLine="true"
+ android:maxLines="3"
android:paddingTop="3dp"
android:textAppearance="@style/TextAppearance.NotificationHistory.Text"
android:textAlignment="viewStart" />
diff --git a/res/layout/notification_sbn_log_row.xml b/res/layout/notification_sbn_log_row.xml
index a5b8dd0fde7..7a3e6d7d817 100644
--- a/res/layout/notification_sbn_log_row.xml
+++ b/res/layout/notification_sbn_log_row.xml
@@ -125,7 +125,7 @@
android:layout_height="wrap_content"
android:layout_gravity="left|center_vertical"
android:ellipsize="end"
- android:singleLine="true"
+ android:maxLines="3"
android:textAppearance="@style/TextAppearance.NotificationHistory.Text"
android:textAlignment="viewStart"
/>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 812ff86e20e..5ba2b7a2c79 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -7323,7 +7323,7 @@
Send & receive when mobile data is off
- com.android.cellbroadcastreceiver
+ com.android.cellbroadcastreceiver.module
+
-
-
diff --git a/res/xml/notification_access_permission_details.xml b/res/xml/notification_access_permission_details.xml
index 8cc5993904f..d956ce911ac 100644
--- a/res/xml/notification_access_permission_details.xml
+++ b/res/xml/notification_access_permission_details.xml
@@ -20,7 +20,7 @@
android:key="notification_access_permission_detail_settings"
android:title="@string/manage_notification_access_title">
-
diff --git a/res/xml/picture_in_picture_permissions_details.xml b/res/xml/picture_in_picture_permissions_details.xml
index c215c9d9cf7..5f2a45ae55c 100644
--- a/res/xml/picture_in_picture_permissions_details.xml
+++ b/res/xml/picture_in_picture_permissions_details.xml
@@ -18,7 +18,7 @@
android:key="picture_in_picture_permission_detail_settings"
android:title="@string/picture_in_picture_app_detail_title">
-
diff --git a/res/xml/write_system_settings_permissions_details.xml b/res/xml/write_system_settings_permissions_details.xml
index 82a6931592c..21ea7065e1b 100644
--- a/res/xml/write_system_settings_permissions_details.xml
+++ b/res/xml/write_system_settings_permissions_details.xml
@@ -18,7 +18,7 @@
android:key="write_system_settings_permission_detail_settings"
android:title="@string/write_settings">
-
diff --git a/res/xml/zen_access_permission_details.xml b/res/xml/zen_access_permission_details.xml
index afa8d80a17c..de014d1c6bd 100644
--- a/res/xml/zen_access_permission_details.xml
+++ b/res/xml/zen_access_permission_details.xml
@@ -20,7 +20,7 @@
android:key="zen_access_permission_detail_settings"
android:title="@string/manage_zen_access_title">
-
diff --git a/src/com/android/settings/applications/manageapplications/ManageApplications.java b/src/com/android/settings/applications/manageapplications/ManageApplications.java
index 69f65a47316..5ef12329a54 100644
--- a/src/com/android/settings/applications/manageapplications/ManageApplications.java
+++ b/src/com/android/settings/applications/manageapplications/ManageApplications.java
@@ -119,7 +119,6 @@ import com.android.settings.widget.LoadingViewController;
import com.android.settings.wifi.AppStateChangeWifiStateBridge;
import com.android.settings.wifi.ChangeWifiStateDetails;
import com.android.settingslib.HelpUtils;
-import com.android.settingslib.applications.AppUtils;
import com.android.settingslib.applications.ApplicationsState;
import com.android.settingslib.applications.ApplicationsState.AppEntry;
import com.android.settingslib.applications.ApplicationsState.AppFilter;
@@ -1462,12 +1461,10 @@ public class ManageApplications extends InstrumentedFragment
ApplicationsState.AppEntry entry = mEntries.get(position);
synchronized (entry) {
holder.setTitle(entry.label);
- holder.itemView.setContentDescription(
- AppUtils.getAppContentDescription(
- mContext,
- entry.info.packageName,
- UserHandle.getUserId(entry.info.uid)));
- holder.setIcon(Utils.getBadgedIcon(mContext, entry.info));
+ mState.ensureLabelDescription(entry);
+ holder.itemView.setContentDescription(entry.labelDescription);
+ mState.ensureIcon(entry);
+ holder.setIcon(entry.icon);
updateSummary(holder, entry);
updateSwitch(holder, entry);
holder.updateDisableView(entry.info);
diff --git a/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminListPreferenceController.java b/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminListPreferenceController.java
index d8ec8489cd4..e25bb1e4fc0 100644
--- a/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminListPreferenceController.java
+++ b/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminListPreferenceController.java
@@ -43,10 +43,10 @@ import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference;
import androidx.preference.PreferenceGroup;
import androidx.preference.PreferenceScreen;
-import androidx.preference.SwitchPreference;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.overlay.FeatureFactory;
+import com.android.settings.widget.FilterTouchesSwitchPreference;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnStart;
@@ -168,32 +168,32 @@ public class DeviceAdminListPreferenceController extends BasePreferenceControlle
if (mFooterPreference != null) {
mFooterPreference.setVisible(mAdmins.isEmpty());
}
- final Map preferenceCache = new ArrayMap<>();
+ final Map preferenceCache = new ArrayMap<>();
final Context prefContext = mPreferenceGroup.getContext();
final int childrenCount = mPreferenceGroup.getPreferenceCount();
for (int i = 0; i < childrenCount; i++) {
final Preference pref = mPreferenceGroup.getPreference(i);
- if (!(pref instanceof SwitchPreference)) {
+ if (!(pref instanceof FilterTouchesSwitchPreference)) {
continue;
}
- final SwitchPreference appSwitch = (SwitchPreference) pref;
+ final FilterTouchesSwitchPreference appSwitch = (FilterTouchesSwitchPreference) pref;
preferenceCache.put(appSwitch.getKey(), appSwitch);
}
for (DeviceAdminListItem item : mAdmins) {
final String key = item.getKey();
- SwitchPreference pref = preferenceCache.remove(key);
+ FilterTouchesSwitchPreference pref = preferenceCache.remove(key);
if (pref == null) {
- pref = new SwitchPreference(prefContext);
+ pref = new FilterTouchesSwitchPreference(prefContext);
mPreferenceGroup.addPreference(pref);
}
bindPreference(item, pref);
}
- for (SwitchPreference unusedCacheItem : preferenceCache.values()) {
+ for (FilterTouchesSwitchPreference unusedCacheItem : preferenceCache.values()) {
mPreferenceGroup.removePreference(unusedCacheItem);
}
}
- private void bindPreference(DeviceAdminListItem item, SwitchPreference pref) {
+ private void bindPreference(DeviceAdminListItem item, FilterTouchesSwitchPreference pref) {
pref.setKey(item.getKey());
pref.setTitle(item.getName());
pref.setIcon(item.getIcon());
diff --git a/src/com/android/settings/aware/AwareFeatureProvider.java b/src/com/android/settings/aware/AwareFeatureProvider.java
index bda27c7143c..a4e9c0cd31d 100644
--- a/src/com/android/settings/aware/AwareFeatureProvider.java
+++ b/src/com/android/settings/aware/AwareFeatureProvider.java
@@ -29,4 +29,8 @@ public interface AwareFeatureProvider {
/** Show information dialog. */
void showRestrictionDialog(Fragment parent);
+
+ /** Return Quick Gestures Summary. */
+ CharSequence getGestureSummary(Context context, boolean sensorSupported,
+ boolean assistGestureEnabled, boolean assistGestureSilenceEnabled);
}
diff --git a/src/com/android/settings/aware/AwareFeatureProviderImpl.java b/src/com/android/settings/aware/AwareFeatureProviderImpl.java
index 5d160313869..6f80d8a7ae5 100644
--- a/src/com/android/settings/aware/AwareFeatureProviderImpl.java
+++ b/src/com/android/settings/aware/AwareFeatureProviderImpl.java
@@ -34,4 +34,10 @@ public class AwareFeatureProviderImpl implements AwareFeatureProvider {
@Override
public void showRestrictionDialog(Fragment parent) {
}
+
+ @Override
+ public CharSequence getGestureSummary(Context context, boolean sensorSupported,
+ boolean assistGestureEnabled, boolean assistGestureSilenceEnabled) {
+ return null;
+ }
}
diff --git a/src/com/android/settings/dashboard/DashboardFragmentRegistry.java b/src/com/android/settings/dashboard/DashboardFragmentRegistry.java
index f71949455d1..f8a4f39ef77 100644
--- a/src/com/android/settings/dashboard/DashboardFragmentRegistry.java
+++ b/src/com/android/settings/dashboard/DashboardFragmentRegistry.java
@@ -125,5 +125,9 @@ public class DashboardFragmentRegistry {
for (Map.Entry parentToKey : PARENT_TO_CATEGORY_KEY_MAP.entrySet()) {
CATEGORY_KEY_TO_PARENT_MAP.put(parentToKey.getValue(), parentToKey.getKey());
}
+
+ // For injection index, redirect CATEGORY_ACCOUNT_DETAIL to AccountDashboardFragment.
+ CATEGORY_KEY_TO_PARENT_MAP.put(CategoryKey.CATEGORY_ACCOUNT_DETAIL,
+ AccountDashboardFragment.class.getName());
}
}
diff --git a/src/com/android/settings/gestures/GesturesSettingPreferenceController.java b/src/com/android/settings/gestures/GesturesSettingPreferenceController.java
index 98eddffb8fa..9d4d538f426 100644
--- a/src/com/android/settings/gestures/GesturesSettingPreferenceController.java
+++ b/src/com/android/settings/gestures/GesturesSettingPreferenceController.java
@@ -20,10 +20,12 @@ import android.content.ContentResolver;
import android.content.Context;
import android.hardware.display.AmbientDisplayConfiguration;
import android.provider.Settings;
+import android.text.TextUtils;
import androidx.annotation.NonNull;
import com.android.settings.R;
+import com.android.settings.aware.AwareFeatureProvider;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.core.AbstractPreferenceController;
@@ -33,6 +35,7 @@ import java.util.List;
public class GesturesSettingPreferenceController extends BasePreferenceController {
private final AssistGestureFeatureProvider mFeatureProvider;
+ private final AwareFeatureProvider mAwareFeatureProvider;
private List mGestureControllers;
private static final String KEY_GESTURES_SETTINGS = "gesture_settings";
@@ -41,6 +44,7 @@ public class GesturesSettingPreferenceController extends BasePreferenceControlle
public GesturesSettingPreferenceController(Context context) {
super(context, KEY_GESTURES_SETTINGS);
mFeatureProvider = FeatureFactory.getFactory(context).getAssistGestureFeatureProvider();
+ mAwareFeatureProvider = FeatureFactory.getFactory(context).getAwareFeatureProvider();
}
@Override
@@ -90,8 +94,15 @@ public class GesturesSettingPreferenceController extends BasePreferenceControlle
contentResolver, Settings.Secure.ASSIST_GESTURE_ENABLED, 1) != 0;
final boolean assistGestureSilenceEnabled = Settings.Secure.getInt(
contentResolver, Settings.Secure.ASSIST_GESTURE_SILENCE_ALERTS_ENABLED, 1) != 0;
+ final boolean sensorSupported = mFeatureProvider.isSupported(mContext);
- if (mFeatureProvider.isSupported(mContext) && assistGestureEnabled) {
+ final CharSequence awareSummary = mAwareFeatureProvider.getGestureSummary(mContext,
+ sensorSupported, assistGestureEnabled, assistGestureSilenceEnabled);
+ if (!TextUtils.isEmpty(awareSummary)) {
+ return awareSummary;
+ }
+
+ if (sensorSupported && assistGestureEnabled) {
return mContext.getText(
R.string.language_input_gesture_summary_on_with_assist);
}
diff --git a/src/com/android/settings/media/MediaDeviceUpdateWorker.java b/src/com/android/settings/media/MediaDeviceUpdateWorker.java
index 719d2d5641d..1288cf51c0b 100644
--- a/src/com/android/settings/media/MediaDeviceUpdateWorker.java
+++ b/src/com/android/settings/media/MediaDeviceUpdateWorker.java
@@ -176,9 +176,13 @@ public class MediaDeviceUpdateWorker extends SliceBackgroundWorker
return mLocalMediaManager.getSelectedMediaDevice();
}
- boolean isSelectedMediaDevice(MediaDevice device) {
- for (MediaDevice selectedMediaDevice : getSelectedMediaDevice()) {
- if (TextUtils.equals(selectedMediaDevice.getId(), device.getId())) {
+ List getDeselectableMediaDevice() {
+ return mLocalMediaManager.getDeselectableMediaDevice();
+ }
+
+ boolean isDeviceIncluded(Collection deviceCollection, MediaDevice targetDevice) {
+ for (MediaDevice device : deviceCollection) {
+ if (TextUtils.equals(device.getId(), targetDevice.getId())) {
return true;
}
}
diff --git a/src/com/android/settings/media/MediaOutputGroupSlice.java b/src/com/android/settings/media/MediaOutputGroupSlice.java
index ba29ab73c87..d33ca45a812 100644
--- a/src/com/android/settings/media/MediaOutputGroupSlice.java
+++ b/src/com/android/settings/media/MediaOutputGroupSlice.java
@@ -43,6 +43,7 @@ import com.android.settings.slices.SliceBackgroundWorker;
import com.android.settings.slices.SliceBroadcastReceiver;
import com.android.settingslib.media.MediaDevice;
+import java.util.ArrayList;
import java.util.List;
/**
@@ -122,6 +123,10 @@ public class MediaOutputGroupSlice implements CustomSliceable {
private void addRow(ListBuilder listBuilder, List mediaDevices, boolean selected) {
final boolean adjustVolumeUserRestriction = getWorker().hasAdjustVolumeUserRestriction();
+ List deselectableMediaDevices = new ArrayList<>();
+ if (selected) {
+ deselectableMediaDevices = getWorker().getDeselectableMediaDevice();
+ }
for (MediaDevice device : mediaDevices) {
final int maxVolume = device.getMaxVolume();
final IconCompat titleIcon = Utils.createIconWithDrawable(device.getIcon());
@@ -147,7 +152,8 @@ public class MediaOutputGroupSlice implements CustomSliceable {
.setMax(device.getMaxVolume())
.setValue(device.getCurrentVolume());
// Add endItem with different icons
- if (mediaDevices.size() == 1 && selected) {
+ if (selected && (!getWorker().isDeviceIncluded(deselectableMediaDevices, device)
+ || mediaDevices.size() == 1)) {
builder.addEndItem(disabledIconSliceAction);
} else {
builder.addEndItem(enabledIconSliceAction);
@@ -158,7 +164,8 @@ public class MediaOutputGroupSlice implements CustomSliceable {
.setTitleItem(titleIcon, ListBuilder.ICON_IMAGE)
.setTitle(title);
// Add endItem with different icons
- if (mediaDevices.size() == 1 && selected) {
+ if (selected && (!getWorker().isDeviceIncluded(deselectableMediaDevices, device)
+ || mediaDevices.size() == 1)) {
rowBuilder.addEndItem(disabledIconSliceAction);
} else {
rowBuilder.addEndItem(enabledIconSliceAction);
@@ -209,7 +216,8 @@ public class MediaOutputGroupSlice implements CustomSliceable {
Log.e(TAG, "Unable to handle notification. The device is unavailable");
return;
}
- final MediaDevice device = getWorker().getMediaDeviceById(id);
+ final MediaDeviceUpdateWorker worker = getWorker();
+ final MediaDevice device = worker.getMediaDeviceById(id);
switch (intent.getIntExtra(CUSTOMIZED_ACTION, ERROR)) {
case ACTION_VOLUME_ADJUSTMENT:
final int newPosition = intent.getIntExtra(EXTRA_RANGE_VALUE, ERROR);
@@ -219,7 +227,7 @@ public class MediaOutputGroupSlice implements CustomSliceable {
}
// Group volume adjustment
if (TextUtils.equals(id, GROUP_DEVICES)) {
- getWorker().adjustSessionVolume(newPosition);
+ worker.adjustSessionVolume(newPosition);
} else {
if (device == null) {
Log.e(TAG, "Unable to adjust volume. The device(" + id
@@ -227,7 +235,7 @@ public class MediaOutputGroupSlice implements CustomSliceable {
return;
}
// Single device volume adjustment
- getWorker().adjustVolume(device, newPosition);
+ worker.adjustVolume(device, newPosition);
}
break;
case ACTION_MEDIA_SESSION_OPERATION:
@@ -236,10 +244,13 @@ public class MediaOutputGroupSlice implements CustomSliceable {
+ ") is unavailable");
return;
}
- if (getWorker().isSelectedMediaDevice(device)) {
- getWorker().removeDeviceFromPlayMedia(device);
+ if (worker.isDeviceIncluded(worker.getSelectableMediaDevice(), device)) {
+ worker.addDeviceToPlayMedia(device);
+ } else if (worker.isDeviceIncluded(worker.getDeselectableMediaDevice(), device)) {
+ worker.removeDeviceFromPlayMedia(device);
} else {
- getWorker().addDeviceToPlayMedia(device);
+ // Do nothing
+ Log.d(TAG, device.getName() + " is not selectable nor deselectable");
}
break;
}
diff --git a/src/com/android/settings/network/telephony/MobileNetworkSwitchController.java b/src/com/android/settings/network/telephony/MobileNetworkSwitchController.java
index a498d474f83..46c5234e4a5 100644
--- a/src/com/android/settings/network/telephony/MobileNetworkSwitchController.java
+++ b/src/com/android/settings/network/telephony/MobileNetworkSwitchController.java
@@ -75,13 +75,14 @@ public class MobileNetworkSwitchController extends BasePreferenceController impl
mSwitchBar.setSwitchBarText(R.string.mobile_network_use_sim_on,
R.string.mobile_network_use_sim_off);
- mSwitchBar.addOnSwitchChangeListener((switchView, isChecked) -> {
+ mSwitchBar.getSwitch().setOnBeforeCheckedChangeListener((toggleSwitch, isChecked) -> {
// TODO b/135222940: re-evaluate whether to use
// mSubscriptionManager#isSubscriptionEnabled
if (mSubscriptionManager.isActiveSubscriptionId(mSubId) != isChecked
&& (!mSubscriptionManager.setSubscriptionEnabled(mSubId, isChecked))) {
- mSwitchBar.setChecked(!isChecked);
+ return true;
}
+ return false;
});
update();
}
@@ -106,7 +107,7 @@ public class MobileNetworkSwitchController extends BasePreferenceController impl
mSwitchBar.hide();
} else {
mSwitchBar.show();
- mSwitchBar.setChecked(mSubscriptionManager.isActiveSubscriptionId(mSubId));
+ mSwitchBar.setCheckedInternal(mSubscriptionManager.isActiveSubscriptionId(mSubId));
}
}
diff --git a/src/com/android/settings/notification/history/NotificationHistoryActivity.java b/src/com/android/settings/notification/history/NotificationHistoryActivity.java
index 1e5e21e4919..525ac84e3c4 100644
--- a/src/com/android/settings/notification/history/NotificationHistoryActivity.java
+++ b/src/com/android/settings/notification/history/NotificationHistoryActivity.java
@@ -140,7 +140,15 @@ public class NotificationHistoryActivity extends Activity {
final NotificationHistoryRecyclerView rv =
viewForPackage.findViewById(R.id.notification_list);
- rv.setAdapter(new NotificationHistoryAdapter(mNm, rv));
+ rv.setAdapter(new NotificationHistoryAdapter(mNm, rv,
+ newCount -> {
+ count.setText(getResources().getQuantityString(
+ R.plurals.notification_history_count,
+ newCount, newCount));
+ if (newCount == 0) {
+ viewForPackage.setVisibility(View.GONE);
+ }
+ }));
((NotificationHistoryAdapter) rv.getAdapter()).onRebuildComplete(
new ArrayList<>(nhp.notifications));
diff --git a/src/com/android/settings/notification/history/NotificationHistoryAdapter.java b/src/com/android/settings/notification/history/NotificationHistoryAdapter.java
index 4a5c627eb28..70eee21e985 100644
--- a/src/com/android/settings/notification/history/NotificationHistoryAdapter.java
+++ b/src/com/android/settings/notification/history/NotificationHistoryAdapter.java
@@ -49,13 +49,16 @@ public class NotificationHistoryAdapter extends
private INotificationManager mNm;
private List mValues;
+ private OnItemDeletedListener mListener;
public NotificationHistoryAdapter(INotificationManager nm,
- NotificationHistoryRecyclerView listView) {
+ NotificationHistoryRecyclerView listView,
+ OnItemDeletedListener listener) {
mValues = new ArrayList<>();
setHasStableIds(true);
listView.setOnItemSwipeDeleteListener(this);
mNm = nm;
+ mListener = listener;
}
@Override
@@ -134,6 +137,11 @@ public class NotificationHistoryAdapter extends
Slog.e(TAG, "Failed to delete item", e);
}
}
+ mListener.onItemDeleted(mValues.size());
notifyItemRemoved(position);
}
+
+ interface OnItemDeletedListener {
+ void onItemDeleted(int newCount);
+ }
}
diff --git a/src/com/android/settings/notification/history/NotificationSbnAdapter.java b/src/com/android/settings/notification/history/NotificationSbnAdapter.java
index 27ecabdd92e..def98de6b9c 100644
--- a/src/com/android/settings/notification/history/NotificationSbnAdapter.java
+++ b/src/com/android/settings/notification/history/NotificationSbnAdapter.java
@@ -20,12 +20,16 @@ import static android.app.Notification.COLOR_DEFAULT;
import static android.content.pm.PackageManager.MATCH_ANY_USER;
import static android.content.pm.PackageManager.NameNotFoundException;
import static android.os.UserHandle.USER_ALL;
+import static android.provider.Settings.EXTRA_APP_PACKAGE;
+import static android.provider.Settings.EXTRA_CHANNEL_ID;
+import static android.provider.Settings.EXTRA_CONVERSATION_ID;
import android.annotation.ColorInt;
import android.annotation.UserIdInt;
import android.app.ActivityManager;
import android.app.Notification;
import android.content.Context;
+import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
@@ -33,6 +37,7 @@ import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.os.UserHandle;
import android.os.UserManager;
+import android.provider.Settings;
import android.service.notification.StatusBarNotification;
import android.text.TextUtils;
import android.util.Log;
@@ -113,6 +118,15 @@ public class NotificationSbnAdapter extends
holder.setProfileBadge(mUserBadgeCache.get(userId));
holder.addOnClick(sbn.getPackageName(), sbn.getUserId(),
sbn.getNotification().contentIntent);
+ holder.itemView.setOnLongClickListener(v -> {
+ Intent intent = new Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS)
+ .putExtra(EXTRA_APP_PACKAGE, sbn.getPackageName())
+ .putExtra(EXTRA_CHANNEL_ID, sbn.getNotification().getChannelId())
+ .putExtra(EXTRA_CONVERSATION_ID, sbn.getNotification().getShortcutId());
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ holder.itemView.getContext().startActivityAsUser(intent, UserHandle.of(userId));
+ return true;
+ });
} else {
Slog.w(TAG, "null entry in list at position " + position);
}
diff --git a/src/com/android/settings/password/ConfirmDeviceCredentialActivity.java b/src/com/android/settings/password/ConfirmDeviceCredentialActivity.java
index 3c81eb8e0c3..64812fdd627 100644
--- a/src/com/android/settings/password/ConfirmDeviceCredentialActivity.java
+++ b/src/com/android/settings/password/ConfirmDeviceCredentialActivity.java
@@ -107,6 +107,7 @@ public class ConfirmDeviceCredentialActivity extends FragmentActivity {
private int mUserId;
private int mCredentialMode;
private boolean mGoingToBackground;
+ private boolean mWaitingForBiometricCallback;
private Executor mExecutor = (runnable -> {
mHandler.post(runnable);
@@ -116,6 +117,7 @@ public class ConfirmDeviceCredentialActivity extends FragmentActivity {
@Override
public void onAuthenticationError(int errorCode, @NonNull CharSequence errString) {
if (!mGoingToBackground) {
+ mWaitingForBiometricCallback = false;
if (errorCode == BiometricPrompt.BIOMETRIC_ERROR_USER_CANCELED
|| errorCode == BiometricPrompt.BIOMETRIC_ERROR_CANCELED) {
finish();
@@ -123,11 +125,15 @@ public class ConfirmDeviceCredentialActivity extends FragmentActivity {
// All other errors go to some version of CC
showConfirmCredentials();
}
+ } else if (mWaitingForBiometricCallback) { // mGoingToBackground is true
+ mWaitingForBiometricCallback = false;
+ finish();
}
}
@Override
public void onAuthenticationSucceeded(BiometricPrompt.AuthenticationResult result) {
+ mWaitingForBiometricCallback = false;
mTrustManager.setDeviceLockedForUser(mUserId, false);
final boolean isStrongAuth = result.getAuthenticationType()
== BiometricPrompt.AUTHENTICATION_RESULT_TYPE_DEVICE_CREDENTIAL;
@@ -142,6 +148,7 @@ public class ConfirmDeviceCredentialActivity extends FragmentActivity {
@Override
public void onAuthenticationFailed() {
+ mWaitingForBiometricCallback = false;
mDevicePolicyManager.reportFailedBiometricAttempt(mUserId);
}
@@ -262,6 +269,7 @@ public class ConfirmDeviceCredentialActivity extends FragmentActivity {
finish();
} else if (launchedBiometric) {
// Keep this activity alive until BiometricPrompt goes away
+ mWaitingForBiometricCallback = true;
} else {
Log.d(TAG, "No pattern, password or PIN set.");
setResult(Activity.RESULT_OK);
@@ -320,7 +328,9 @@ public class ConfirmDeviceCredentialActivity extends FragmentActivity {
super.onPause();
if (!isChangingConfigurations()) {
mGoingToBackground = true;
- finish();
+ if (!mWaitingForBiometricCallback) {
+ finish();
+ }
} else {
mGoingToBackground = false;
}
diff --git a/src/com/android/settings/users/MultiUserSwitchBarController.java b/src/com/android/settings/users/MultiUserSwitchBarController.java
index a5fdf9b3279..58de14963fa 100644
--- a/src/com/android/settings/users/MultiUserSwitchBarController.java
+++ b/src/com/android/settings/users/MultiUserSwitchBarController.java
@@ -52,8 +52,6 @@ public class MultiUserSwitchBarController implements SwitchWidgetController.OnSw
mListener = listener;
mUserCapabilities = UserCapabilities.create(context);
mSwitchBar.setChecked(mUserCapabilities.mUserSwitcherEnabled);
- Settings.Global.putInt(mContext.getContentResolver(),
- Settings.Global.USER_SWITCHER_ENABLED, mSwitchBar.isChecked() ? 1 : 0);
if (mUserCapabilities.mDisallowSwitchUser) {
mSwitchBar.setDisabledByAdmin(RestrictedLockUtilsInternal
diff --git a/src/com/android/settings/vpn2/ConfigDialog.java b/src/com/android/settings/vpn2/ConfigDialog.java
index 4e6cc893b8e..12d91ec2042 100644
--- a/src/com/android/settings/vpn2/ConfigDialog.java
+++ b/src/com/android/settings/vpn2/ConfigDialog.java
@@ -20,6 +20,7 @@ import static com.android.internal.net.VpnProfile.isLegacyType;
import android.content.Context;
import android.content.DialogInterface;
+import android.content.pm.PackageManager;
import android.net.Proxy;
import android.net.ProxyInfo;
import android.os.Bundle;
@@ -43,6 +44,9 @@ import com.android.internal.net.VpnProfile;
import com.android.settings.R;
import java.net.InetAddress;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
/**
* Dialog showing information about a VPN configuration. The dialog
@@ -129,6 +133,7 @@ class ConfigDialog extends AlertDialog implements TextWatcher,
// Second, copy values from the profile.
mName.setText(mProfile.name);
+ setTypesByFeature(mType);
mType.setSelection(mProfile.type);
mServer.setText(mProfile.server);
if (mProfile.saveLogin) {
@@ -487,6 +492,25 @@ class ConfigDialog extends AlertDialog implements TextWatcher,
return true;
}
+ private void setTypesByFeature(Spinner typeSpinner) {
+ String[] types = getContext().getResources().getStringArray(R.array.vpn_types);
+ if (!getContext().getPackageManager().hasSystemFeature(
+ PackageManager.FEATURE_IPSEC_TUNNELS)) {
+ final List typesList = new ArrayList<>(Arrays.asList(types));
+
+ // This must be removed from back to front in order to ensure index consistency
+ typesList.remove(VpnProfile.TYPE_IKEV2_IPSEC_RSA);
+ typesList.remove(VpnProfile.TYPE_IKEV2_IPSEC_PSK);
+ typesList.remove(VpnProfile.TYPE_IKEV2_IPSEC_USER_PASS);
+
+ types = typesList.toArray(new String[0]);
+ }
+ final ArrayAdapter adapter = new ArrayAdapter(
+ getContext(), android.R.layout.simple_spinner_item, types);
+ adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+ typeSpinner.setAdapter(adapter);
+ }
+
private void loadCertificates(Spinner spinner, String prefix, int firstId, String selected) {
Context context = getContext();
String first = (firstId == 0) ? "" : context.getString(firstId);
diff --git a/src/com/android/settings/widget/AppSwitchPreference.java b/src/com/android/settings/widget/AppSwitchPreference.java
index 506ab7642ae..90f1dbd0782 100644
--- a/src/com/android/settings/widget/AppSwitchPreference.java
+++ b/src/com/android/settings/widget/AppSwitchPreference.java
@@ -17,7 +17,9 @@
package com.android.settings.widget;
import android.content.Context;
+import android.view.View;
+import androidx.preference.PreferenceViewHolder;
import androidx.preference.SwitchPreference;
import com.android.settings.R;
@@ -28,4 +30,13 @@ public class AppSwitchPreference extends SwitchPreference {
super(context);
setLayoutResource(R.layout.preference_app);
}
+
+ @Override
+ public void onBindViewHolder(PreferenceViewHolder holder) {
+ super.onBindViewHolder(holder);
+ final View switchView = holder.findViewById(android.R.id.switch_widget);
+ if (switchView != null) {
+ switchView.setFilterTouchesWhenObscured(true);
+ }
+ }
}
diff --git a/src/com/android/settings/widget/FilterTouchesRestrictedSwitchPreference.java b/src/com/android/settings/widget/FilterTouchesRestrictedSwitchPreference.java
new file mode 100644
index 00000000000..c5e0217dd0f
--- /dev/null
+++ b/src/com/android/settings/widget/FilterTouchesRestrictedSwitchPreference.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.settings.widget;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.View;
+
+import androidx.preference.PreferenceViewHolder;
+
+import com.android.settingslib.RestrictedSwitchPreference;
+
+/**
+ * This widget with enabled filterTouchesWhenObscured attribute use to replace
+ * the {@link RestrictedSwitchPreference} in the Special access app pages for
+ * security.
+ */
+public class FilterTouchesRestrictedSwitchPreference extends RestrictedSwitchPreference {
+ public FilterTouchesRestrictedSwitchPreference(Context context, AttributeSet attrs,
+ int defStyleAttr, int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ }
+
+ public FilterTouchesRestrictedSwitchPreference(Context context, AttributeSet attrs,
+ int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ }
+
+ public FilterTouchesRestrictedSwitchPreference(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public FilterTouchesRestrictedSwitchPreference(Context context) {
+ super(context);
+ }
+
+ @Override
+ public void onBindViewHolder(PreferenceViewHolder holder) {
+ super.onBindViewHolder(holder);
+ final View switchView = holder.findViewById(android.R.id.switch_widget);
+ if (switchView != null) {
+ switchView.setFilterTouchesWhenObscured(true);
+ }
+ }
+}
diff --git a/src/com/android/settings/widget/FilterTouchesSwitchPreference.java b/src/com/android/settings/widget/FilterTouchesSwitchPreference.java
new file mode 100644
index 00000000000..a4e3c6e76da
--- /dev/null
+++ b/src/com/android/settings/widget/FilterTouchesSwitchPreference.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.settings.widget;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.View;
+
+import androidx.preference.PreferenceViewHolder;
+import androidx.preference.SwitchPreference;
+
+/**
+ * This widget with enabled filterTouchesWhenObscured attribute use to replace
+ * the {@link SwitchPreference} in the Special access app pages for security.
+ */
+public class FilterTouchesSwitchPreference extends SwitchPreference {
+
+ public FilterTouchesSwitchPreference(Context context, AttributeSet attrs, int defStyleAttr,
+ int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ }
+
+ public FilterTouchesSwitchPreference(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ }
+
+ public FilterTouchesSwitchPreference(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public FilterTouchesSwitchPreference(Context context) {
+ super(context);
+ }
+
+ @Override
+ public void onBindViewHolder(PreferenceViewHolder holder) {
+ super.onBindViewHolder(holder);
+ final View switchView = holder.findViewById(android.R.id.switch_widget);
+ if (switchView != null) {
+ switchView.setFilterTouchesWhenObscured(true);
+ }
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentRegistryTest.java b/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentRegistryTest.java
index c6b24658dbd..10aaad8b2f0 100644
--- a/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentRegistryTest.java
+++ b/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentRegistryTest.java
@@ -18,6 +18,9 @@ package com.android.settings.dashboard;
import static com.google.common.truth.Truth.assertThat;
+import com.android.settings.accounts.AccountDashboardFragment;
+import com.android.settingslib.drawer.CategoryKey;
+
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
@@ -29,4 +32,12 @@ public class DashboardFragmentRegistryTest {
assertThat(DashboardFragmentRegistry.CATEGORY_KEY_TO_PARENT_MAP.size())
.isEqualTo(DashboardFragmentRegistry.PARENT_TO_CATEGORY_KEY_MAP.size());
}
+
+ @Test
+ public void accountDetailCategoryShouldRedirectToAccountDashboardFragment() {
+ final String fragment = DashboardFragmentRegistry.CATEGORY_KEY_TO_PARENT_MAP.get(
+ CategoryKey.CATEGORY_ACCOUNT_DETAIL);
+
+ assertThat(fragment).isEqualTo(AccountDashboardFragment.class.getName());
+ }
}
diff --git a/tests/robotests/src/com/android/settings/media/MediaOutputGroupSliceTest.java b/tests/robotests/src/com/android/settings/media/MediaOutputGroupSliceTest.java
index 9da18d50cde..bb0478cc8b7 100644
--- a/tests/robotests/src/com/android/settings/media/MediaOutputGroupSliceTest.java
+++ b/tests/robotests/src/com/android/settings/media/MediaOutputGroupSliceTest.java
@@ -90,6 +90,7 @@ public class MediaOutputGroupSliceTest {
private final List mSelectableDevices = new ArrayList<>();
private final List mSelectedDevices = new ArrayList<>();
+ private final List mDeselectableDevices = new ArrayList<>();
private Context mContext;
private MediaOutputGroupSlice mMediaOutputGroupSlice;
@@ -227,14 +228,19 @@ public class MediaOutputGroupSliceTest {
verify(sMediaDeviceUpdateWorker).addDeviceToPlayMedia(mDevice2);
}
+
@Test
- public void onNotifyChange_sendSelectedDevice_verifyRemoveSession() {
+ public void onNotifyChange_sendDeselectableDevice_verifyRemoveSession() {
mSelectedDevices.add(mDevice1);
mSelectedDevices.add(mDevice2);
+ mDeselectableDevices.add(mDevice1);
+ mDeselectableDevices.add(mDevice2);
when(mLocalMediaManager.getMediaDeviceById(mSelectedDevices, TEST_DEVICE_2_ID))
.thenReturn(mDevice2);
sMediaDeviceUpdateWorker.onDeviceListUpdate(mSelectedDevices);
when(sMediaDeviceUpdateWorker.getSelectedMediaDevice()).thenReturn(mSelectedDevices);
+ when(sMediaDeviceUpdateWorker.getDeselectableMediaDevice()).thenReturn(
+ mDeselectableDevices);
final Intent intent = new Intent();
intent.putExtra(MEDIA_DEVICE_ID, TEST_DEVICE_2_ID);
intent.putExtra(CUSTOMIZED_ACTION, ACTION_MEDIA_SESSION_OPERATION);
@@ -244,6 +250,26 @@ public class MediaOutputGroupSliceTest {
verify(sMediaDeviceUpdateWorker).removeDeviceFromPlayMedia(mDevice2);
}
+ @Test
+ public void onNotifyChange_sendNonDeselectableDevice_notRemoveSession() {
+ mSelectedDevices.add(mDevice1);
+ mSelectedDevices.add(mDevice2);
+ mDeselectableDevices.add(mDevice1);
+ when(mLocalMediaManager.getMediaDeviceById(mSelectedDevices, TEST_DEVICE_2_ID))
+ .thenReturn(mDevice2);
+ sMediaDeviceUpdateWorker.onDeviceListUpdate(mSelectedDevices);
+ when(sMediaDeviceUpdateWorker.getSelectedMediaDevice()).thenReturn(mSelectedDevices);
+ when(sMediaDeviceUpdateWorker.getDeselectableMediaDevice()).thenReturn(
+ mDeselectableDevices);
+ final Intent intent = new Intent();
+ intent.putExtra(MEDIA_DEVICE_ID, TEST_DEVICE_2_ID);
+ intent.putExtra(CUSTOMIZED_ACTION, ACTION_MEDIA_SESSION_OPERATION);
+
+ mMediaOutputGroupSlice.onNotifyChange(intent);
+
+ verify(sMediaDeviceUpdateWorker, never()).removeDeviceFromPlayMedia(mDevice2);
+ }
+
@Test
public void onNotifyChange_noId_doNothing() {
mSelectableDevices.add(mDevice1);