diff --git a/res/xml/storage_dashboard_fragment.xml b/res/xml/storage_dashboard_fragment.xml index 51d49353fdb..91634fcc2cc 100644 --- a/res/xml/storage_dashboard_fragment.xml +++ b/res/xml/storage_dashboard_fragment.xml @@ -20,7 +20,7 @@ android:title="@string/storage_settings" android:orderingFromXml="false"> diff --git a/src/com/android/settings/biometrics/BiometricStatusPreferenceController.java b/src/com/android/settings/biometrics/BiometricStatusPreferenceController.java index 62dc1cf1fae..2a3bfb25947 100644 --- a/src/com/android/settings/biometrics/BiometricStatusPreferenceController.java +++ b/src/com/android/settings/biometrics/BiometricStatusPreferenceController.java @@ -23,6 +23,7 @@ import android.content.Context; import android.content.Intent; import android.os.UserHandle; import android.os.UserManager; +import android.text.TextUtils; import androidx.preference.Preference; @@ -100,29 +101,31 @@ public abstract class BiometricStatusPreferenceController extends BasePreference } else { preference.setVisible(true); } - final int userId = getUserId(); - final String clazz; - if (hasEnrolledBiometrics()) { - preference.setSummary(getSummaryTextEnrolled()); - clazz = getSettingsClassName(); - } else { - preference.setSummary(getSummaryTextNoneEnrolled()); - clazz = getEnrollClassName(); + preference.setSummary(hasEnrolledBiometrics() ? getSummaryTextEnrolled() + : getSummaryTextNoneEnrolled()); + } + + @Override + public boolean handlePreferenceTreeClick(Preference preference) { + if (!TextUtils.equals(preference.getKey(), getPreferenceKey())) { + return super.handlePreferenceTreeClick(preference); } - preference.setOnPreferenceClickListener(target -> { - final Context context = target.getContext(); - final UserManager userManager = UserManager.get(context); - if (Utils.startQuietModeDialogIfNecessary(context, userManager, - userId)) { - return false; - } - Intent intent = new Intent(); - intent.setClassName(SETTINGS_PACKAGE_NAME, clazz); - intent.putExtra(Intent.EXTRA_USER_ID, userId); - intent.putExtra(EXTRA_FROM_SETTINGS_SUMMARY, true); - context.startActivity(intent); - return true; - }); + + final Context context = preference.getContext(); + final UserManager userManager = UserManager.get(context); + final int userId = getUserId(); + if (Utils.startQuietModeDialogIfNecessary(context, userManager, userId)) { + return false; + } + + final Intent intent = new Intent(); + final String clazz = hasEnrolledBiometrics() ? getSettingsClassName() + : getEnrollClassName(); + intent.setClassName(SETTINGS_PACKAGE_NAME, clazz); + intent.putExtra(Intent.EXTRA_USER_ID, userId); + intent.putExtra(EXTRA_FROM_SETTINGS_SUMMARY, true); + context.startActivity(intent); + return true; } protected int getUserId() { diff --git a/src/com/android/settings/biometrics/face/FaceSettingsRemoveButtonPreferenceController.java b/src/com/android/settings/biometrics/face/FaceSettingsRemoveButtonPreferenceController.java index 1c1b81df6c8..a4da7597929 100644 --- a/src/com/android/settings/biometrics/face/FaceSettingsRemoveButtonPreferenceController.java +++ b/src/com/android/settings/biometrics/face/FaceSettingsRemoveButtonPreferenceController.java @@ -35,6 +35,8 @@ import com.android.settings.R; import com.android.settings.SettingsActivity; import com.android.settings.core.BasePreferenceController; import com.android.settings.core.instrumentation.InstrumentedDialogFragment; +import com.android.settings.overlay.FeatureFactory; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import com.android.settingslib.widget.LayoutPreference; import java.util.List; @@ -80,12 +82,14 @@ public class FaceSettingsRemoveButtonPreferenceController extends BasePreference void onRemoved(); } + private Preference mPreference; private Button mButton; private Listener mListener; private SettingsActivity mActivity; private int mUserId; private boolean mRemoving; + private final MetricsFeatureProvider mMetricsFeatureProvider; private final Context mContext; private final FaceManager mFaceManager; private final FaceManager.RemovalCallback mRemovalCallback = new FaceManager.RemovalCallback() { @@ -141,6 +145,7 @@ public class FaceSettingsRemoveButtonPreferenceController extends BasePreference super(context, preferenceKey); mContext = context; mFaceManager = context.getSystemService(FaceManager.class); + mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider(); } public FaceSettingsRemoveButtonPreferenceController(Context context) { @@ -155,6 +160,7 @@ public class FaceSettingsRemoveButtonPreferenceController extends BasePreference public void updateState(Preference preference) { super.updateState(preference); + mPreference = preference; mButton = ((LayoutPreference) preference) .findViewById(R.id.security_settings_face_settings_remove_button); mButton.setOnClickListener(this); @@ -179,6 +185,7 @@ public class FaceSettingsRemoveButtonPreferenceController extends BasePreference @Override public void onClick(View v) { if (v == mButton) { + mMetricsFeatureProvider.logClickedPreference(mPreference, getMetricsCategory()); mRemoving = true; ConfirmRemoveDialog dialog = new ConfirmRemoveDialog(); dialog.setOnClickListener(mOnClickListener); diff --git a/src/com/android/settings/deviceinfo/StorageDashboardFragment.java b/src/com/android/settings/deviceinfo/StorageDashboardFragment.java index bbd87ab632f..10c3a43fe8e 100644 --- a/src/com/android/settings/deviceinfo/StorageDashboardFragment.java +++ b/src/com/android/settings/deviceinfo/StorageDashboardFragment.java @@ -63,7 +63,7 @@ public class StorageDashboardFragment extends DashboardFragment implements LoaderManager.LoaderCallbacks> { private static final String TAG = "StorageDashboardFrag"; - private static final String SUMMARY_PREF_KEY = "pref_summary"; + private static final String SUMMARY_PREF_KEY = "storage_summary"; private static final int STORAGE_JOB_ID = 0; private static final int ICON_JOB_ID = 1; private static final int VOLUME_SIZE_JOB_ID = 2; diff --git a/src/com/android/settings/deviceinfo/storage/StorageSummaryDonutPreference.java b/src/com/android/settings/deviceinfo/storage/StorageSummaryDonutPreference.java index cf505960260..caf5b4e1f79 100644 --- a/src/com/android/settings/deviceinfo/storage/StorageSummaryDonutPreference.java +++ b/src/com/android/settings/deviceinfo/storage/StorageSummaryDonutPreference.java @@ -19,10 +19,7 @@ package com.android.settings.deviceinfo.storage; import android.app.settings.SettingsEnums; import android.content.Context; import android.content.Intent; -import android.graphics.Typeface; import android.os.storage.StorageManager; -import android.text.TextPaint; -import android.text.style.StyleSpan; import android.util.AttributeSet; import android.view.View; import android.widget.Button; @@ -31,8 +28,10 @@ import androidx.preference.Preference; import androidx.preference.PreferenceViewHolder; import com.android.settings.R; +import com.android.settings.dashboard.DashboardFragment; import com.android.settings.overlay.FeatureFactory; import com.android.settings.widget.DonutView; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; /** * StorageSummaryDonutPreference is a preference which summarizes the used and remaining storage left @@ -79,23 +78,14 @@ public class StorageSummaryDonutPreference extends Preference implements View.On @Override public void onClick(View v) { if (v != null && R.id.deletion_helper_button == v.getId()) { - Context context = getContext(); - FeatureFactory.getFactory(context).getMetricsFeatureProvider().action( - context, SettingsEnums.STORAGE_FREE_UP_SPACE_NOW); - Intent intent = new Intent(StorageManager.ACTION_MANAGE_STORAGE); - getContext().startActivity(intent); - } - } - - private static class BoldLinkSpan extends StyleSpan { - public BoldLinkSpan() { - super(Typeface.BOLD); - } - - @Override - public void updateDrawState(TextPaint ds) { - super.updateDrawState(ds); - ds.setColor(ds.linkColor); + final Context context = getContext(); + final MetricsFeatureProvider metricsFeatureProvider = + FeatureFactory.getFactory(context).getMetricsFeatureProvider(); + metricsFeatureProvider.logClickedPreference(this, + getExtras().getInt(DashboardFragment.CATEGORY)); + metricsFeatureProvider.action(context, SettingsEnums.STORAGE_FREE_UP_SPACE_NOW); + final Intent intent = new Intent(StorageManager.ACTION_MANAGE_STORAGE); + context.startActivity(intent); } } } diff --git a/src/com/android/settings/display/NightDisplayAutoModePreferenceController.java b/src/com/android/settings/display/NightDisplayAutoModePreferenceController.java index fb2dbc3b903..ef11e00cebb 100644 --- a/src/com/android/settings/display/NightDisplayAutoModePreferenceController.java +++ b/src/com/android/settings/display/NightDisplayAutoModePreferenceController.java @@ -74,7 +74,7 @@ public class NightDisplayAutoModePreferenceController extends BasePreferenceCont if (String.valueOf(ColorDisplayManager.AUTO_MODE_TWILIGHT).equals(newValue) && !mLocationManager.isLocationEnabled()) { TwilightLocationDialog.show(mContext); - return false; + return true; } return mColorDisplayManager.setNightDisplayAutoMode(Integer.parseInt((String) newValue)); } diff --git a/src/com/android/settings/display/darkmode/DarkModeScheduleSelectorController.java b/src/com/android/settings/display/darkmode/DarkModeScheduleSelectorController.java index 6acaf8292a4..2ac9a9f8638 100644 --- a/src/com/android/settings/display/darkmode/DarkModeScheduleSelectorController.java +++ b/src/com/android/settings/display/darkmode/DarkModeScheduleSelectorController.java @@ -33,7 +33,7 @@ import com.android.settings.display.TwilightLocationDialog; */ public class DarkModeScheduleSelectorController extends BasePreferenceController implements Preference.OnPreferenceChangeListener { - + private static final String TAG = DarkModeScheduleSelectorController.class.getSimpleName(); private final UiModeManager mUiModeManager; private PowerManager mPowerManager; private DropDownPreference mPreference; @@ -51,7 +51,6 @@ public class DarkModeScheduleSelectorController extends BasePreferenceController public void displayPreference(PreferenceScreen screen) { super.displayPreference(screen); mPreference = screen.findPreference(getPreferenceKey()); - init(); } @Override @@ -59,7 +58,8 @@ public class DarkModeScheduleSelectorController extends BasePreferenceController return BasePreferenceController.AVAILABLE; } - private void init() { + @Override + public final void updateState(Preference preference) { final boolean batterySaver = mPowerManager.isPowerSaveMode(); mPreference.setEnabled(!batterySaver); mCurrentMode = getCurrentMode(); @@ -87,25 +87,25 @@ public class DarkModeScheduleSelectorController extends BasePreferenceController if (newMode == mCurrentMode) { return false; } - mCurrentMode = newMode; - if (mCurrentMode == mPreference.findIndexOfValue( + if (newMode == mPreference.findIndexOfValue( mContext.getString(R.string.dark_ui_auto_mode_never))) { boolean active = (mContext.getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_YES) != 0; int mode = active ? UiModeManager.MODE_NIGHT_YES : UiModeManager.MODE_NIGHT_NO; mUiModeManager.setNightMode(mode); - } else if (mCurrentMode == mPreference.findIndexOfValue( + } else if (newMode == mPreference.findIndexOfValue( mContext.getString(R.string.dark_ui_auto_mode_auto))) { if (!mLocationManager.isLocationEnabled()) { TwilightLocationDialog.show(mContext); - return false; + return true; } mUiModeManager.setNightMode(UiModeManager.MODE_NIGHT_AUTO); - } else if (mCurrentMode == mPreference.findIndexOfValue( + } else if (newMode == mPreference.findIndexOfValue( mContext.getString(R.string.dark_ui_auto_mode_custom))) { mUiModeManager.setNightMode(UiModeManager.MODE_NIGHT_CUSTOM); } + mCurrentMode = newMode; return true; } } diff --git a/src/com/android/settings/homepage/contextualcards/EligibleCardChecker.java b/src/com/android/settings/homepage/contextualcards/EligibleCardChecker.java index 0fcde265696..7fd8a2fd5e6 100644 --- a/src/com/android/settings/homepage/contextualcards/EligibleCardChecker.java +++ b/src/com/android/settings/homepage/contextualcards/EligibleCardChecker.java @@ -18,6 +18,8 @@ package com.android.settings.homepage.contextualcards; import static android.app.slice.Slice.HINT_ERROR; +import static com.android.settings.intelligence.ContextualCardProto.ContextualCard.Category.STICKY_VALUE; + import android.app.settings.SettingsEnums; import android.content.ContentResolver; import android.content.Context; @@ -94,6 +96,11 @@ public class EligibleCardChecker implements Callable { return false; } + if (card.getCategory() == STICKY_VALUE) { + Log.d(TAG, "Sticky card, skip checking. Uri = " + card.getSliceUri()); + return true; + } + final Slice slice = bindSlice(uri); if (isSliceToggleable(slice)) { diff --git a/src/com/android/settings/media/MediaOutputIndicatorSlice.java b/src/com/android/settings/media/MediaOutputIndicatorSlice.java index 7ec0d3aa411..17c8ef8a9fa 100644 --- a/src/com/android/settings/media/MediaOutputIndicatorSlice.java +++ b/src/com/android/settings/media/MediaOutputIndicatorSlice.java @@ -16,6 +16,8 @@ package com.android.settings.media; +import static android.app.PendingIntent.FLAG_UPDATE_CURRENT; + import static com.android.settings.slices.CustomSliceRegistry.MEDIA_OUTPUT_INDICATOR_SLICE_URI; import android.annotation.ColorInt; @@ -61,7 +63,7 @@ public class MediaOutputIndicatorSlice implements CustomSliceable { final CharSequence title = mContext.getString(R.string.media_output_label_title, Utils.getApplicationLabel(mContext, getWorker().getPackageName())); final PendingIntent primaryActionIntent = PendingIntent.getActivity(mContext, - 0 /* requestCode */, getMediaOutputSliceIntent(), 0 /* flags */); + 0 /* requestCode */, getMediaOutputSliceIntent(), FLAG_UPDATE_CURRENT); final SliceAction primarySliceAction = SliceAction.createDeeplink( primaryActionIntent, icon, ListBuilder.ICON_IMAGE, title); @ColorInt final int color = Utils.getColorAccentDefaultColor(mContext); diff --git a/src/com/android/settings/panel/PanelSlicesAdapter.java b/src/com/android/settings/panel/PanelSlicesAdapter.java index 2f2932c8883..f0a7745acef 100644 --- a/src/com/android/settings/panel/PanelSlicesAdapter.java +++ b/src/com/android/settings/panel/PanelSlicesAdapter.java @@ -140,11 +140,10 @@ public class PanelSlicesAdapter final Slice slice = sliceLiveData.getValue(); if (slice == null || slice.getUri().equals(MEDIA_OUTPUT_INDICATOR_SLICE_URI)) { mDividerAllowedAbove = false; - } - - // Customize output switcher slice top padding - if (position == 0 && (slice.getUri().equals(MEDIA_OUTPUT_SLICE_URI) + } else if (position == 0 && (slice.getUri().equals(MEDIA_OUTPUT_SLICE_URI) || slice.getUri().equals(MEDIA_OUTPUT_GROUP_SLICE_URI))) { + sliceView.setClickable(false); + // Customize output switcher slice top padding final int paddingTop = mPanelFragment.getResources().getDimensionPixelSize( R.dimen.output_switcher_slice_padding_top); mSliceSliderLayout.setPadding(mSliceSliderLayout.getPaddingLeft(), paddingTop, diff --git a/src/com/android/settings/widget/MasterSwitchController.java b/src/com/android/settings/widget/MasterSwitchController.java index 91595848bdc..92e38847987 100644 --- a/src/com/android/settings/widget/MasterSwitchController.java +++ b/src/com/android/settings/widget/MasterSwitchController.java @@ -18,7 +18,10 @@ package com.android.settings.widget; import androidx.preference.Preference; +import com.android.settings.dashboard.DashboardFragment; +import com.android.settings.overlay.FeatureFactory; import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; /* * The switch controller that is used to update the switch widget in the MasterSwitchPreference @@ -28,9 +31,12 @@ public class MasterSwitchController extends SwitchWidgetController implements Preference.OnPreferenceChangeListener { private final MasterSwitchPreference mPreference; + private final MetricsFeatureProvider mMetricsFeatureProvider; public MasterSwitchController(MasterSwitchPreference preference) { mPreference = preference; + mMetricsFeatureProvider = FeatureFactory.getFactory(preference.getContext()) + .getMetricsFeatureProvider(); } @Override @@ -65,7 +71,12 @@ public class MasterSwitchController extends SwitchWidgetController implements @Override public boolean onPreferenceChange(Preference preference, Object newValue) { if (mListener != null) { - return mListener.onSwitchToggled((Boolean) newValue); + final boolean result = mListener.onSwitchToggled((Boolean) newValue); + if (result) { + mMetricsFeatureProvider.logClickedPreference(preference, + preference.getExtras().getInt(DashboardFragment.CATEGORY)); + } + return result; } return false; } diff --git a/tests/robotests/src/com/android/settings/biometrics/face/FaceStatusPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/biometrics/face/FaceStatusPreferenceControllerTest.java index ec924e54295..2dfc3472523 100644 --- a/tests/robotests/src/com/android/settings/biometrics/face/FaceStatusPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/biometrics/face/FaceStatusPreferenceControllerTest.java @@ -113,7 +113,6 @@ public class FaceStatusPreferenceControllerTest { assertThat(mPreference.getSummary()).isEqualTo( mContext.getString(R.string.security_settings_face_preference_summary_none)); assertThat(mPreference.isVisible()).isTrue(); - assertThat(mPreference.getOnPreferenceClickListener()).isNotNull(); } @Test @@ -129,6 +128,5 @@ public class FaceStatusPreferenceControllerTest { assertThat(mPreference.getSummary()).isEqualTo(mContext.getResources() .getString(R.string.security_settings_face_preference_summary)); assertThat(mPreference.isVisible()).isTrue(); - assertThat(mPreference.getOnPreferenceClickListener()).isNotNull(); } } diff --git a/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintStatusPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintStatusPreferenceControllerTest.java index 18a05fd5a88..14ca1f8d636 100644 --- a/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintStatusPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintStatusPreferenceControllerTest.java @@ -115,7 +115,6 @@ public class FingerprintStatusPreferenceControllerTest { assertThat(mPreference.getSummary()).isEqualTo( mContext.getString(R.string.security_settings_fingerprint_preference_summary_none)); assertThat(mPreference.isVisible()).isTrue(); - assertThat(mPreference.getOnPreferenceClickListener()).isNotNull(); } @Test @@ -130,6 +129,5 @@ public class FingerprintStatusPreferenceControllerTest { assertThat(mPreference.getSummary()).isEqualTo(mContext.getResources().getQuantityString( R.plurals.security_settings_fingerprint_preference_summary, 1, 1)); assertThat(mPreference.isVisible()).isTrue(); - assertThat(mPreference.getOnPreferenceClickListener()).isNotNull(); } } diff --git a/tests/robotests/src/com/android/settings/display/darkmode/DarkModeScheduleSelectorControllerTest.java b/tests/robotests/src/com/android/settings/display/darkmode/DarkModeScheduleSelectorControllerTest.java index 1bbbe7d21ed..141177c0235 100644 --- a/tests/robotests/src/com/android/settings/display/darkmode/DarkModeScheduleSelectorControllerTest.java +++ b/tests/robotests/src/com/android/settings/display/darkmode/DarkModeScheduleSelectorControllerTest.java @@ -98,6 +98,7 @@ public class DarkModeScheduleSelectorControllerTest { public void nightMode_updateStateNone_dropDownValueChangedToNone() { when(mUiService.getNightMode()).thenReturn(UiModeManager.MODE_NIGHT_YES); mController.displayPreference(mScreen); + mController.updateState(mScreen); verify(mPreference).setValueIndex(0); } @@ -105,6 +106,7 @@ public class DarkModeScheduleSelectorControllerTest { public void nightMode_updateStateNone_dropDownValueChangedToAuto() { when(mUiService.getNightMode()).thenReturn(UiModeManager.MODE_NIGHT_AUTO); mController.displayPreference(mScreen); + mController.updateState(mScreen); verify(mPreference).setValueIndex(1); } @@ -112,6 +114,7 @@ public class DarkModeScheduleSelectorControllerTest { public void batterySaver_dropDown_disabledSelector() { when(mPM.isPowerSaveMode()).thenReturn(true); mController.displayPreference(mScreen); + mController.updateState(mScreen); verify(mPreference).setEnabled(eq(false)); } } diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/EligibleCardCheckerTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/EligibleCardCheckerTest.java index 23ae2f3a75c..e2369195308 100644 --- a/tests/robotests/src/com/android/settings/homepage/contextualcards/EligibleCardCheckerTest.java +++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/EligibleCardCheckerTest.java @@ -18,11 +18,15 @@ package com.android.settings.homepage.contextualcards; import static android.app.slice.Slice.HINT_ERROR; +import static com.android.settings.intelligence.ContextualCardProto.ContextualCard.Category.STICKY_VALUE; + import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; import android.content.Context; import android.net.Uri; @@ -64,6 +68,32 @@ public class EligibleCardCheckerTest { assertThat(mEligibleCardChecker.isSliceToggleable(slice)).isTrue(); } + @Test + public void isCardEligibleToDisplay_stickyCard_returnTrue() { + final ContextualCard card = new ContextualCard.Builder() + .setName("test_card") + .setCardType(ContextualCard.CardType.SLICE) + .setCategory(STICKY_VALUE) + .setSliceUri(CustomSliceRegistry.FLASHLIGHT_SLICE_URI) + .build(); + + assertThat(mEligibleCardChecker.isCardEligibleToDisplay(card)).isTrue(); + } + + @Test + public void isCardEligibleToDisplay_stickyCard_shouldNotPrebind() { + final ContextualCard card = new ContextualCard.Builder() + .setName("test_card") + .setCardType(ContextualCard.CardType.SLICE) + .setCategory(STICKY_VALUE) + .setSliceUri(CustomSliceRegistry.FLASHLIGHT_SLICE_URI) + .build(); + + mEligibleCardChecker.isCardEligibleToDisplay(card); + + verify(mEligibleCardChecker, never()).bindSlice(CustomSliceRegistry.FLASHLIGHT_SLICE_URI); + } + @Test public void isCardEligibleToDisplay_toggleSlice_hasInlineActionShouldBeTrue() { final ContextualWifiSlice wifiSlice = new ContextualWifiSlice(mContext);