Loading aconfig/settings_flag_declarations.aconfig +7 −0 Original line number Diff line number Diff line Loading @@ -104,3 +104,10 @@ flag { description: "Use action corners to trigger a chosen action" bug: "412558312" } flag { name: "homepage_tile_alert" namespace: "android_settings" description: "Enables alert indicator on homepage tiles" bug: "403326850" } res/layout/homepage_preference_expressive.xml +46 −0 Original line number Diff line number Diff line Loading @@ -83,4 +83,50 @@ android:lineBreakWordStyle="phrase" style="@style/PreferenceSummaryTextStyle"/> </RelativeLayout> <FrameLayout android:id="@+id/alert_frame" android:layout_width="40dp" android:layout_height="40dp" android:visibility="gone" android:layout_gravity="center|end" android:layout_marginEnd="16dp"> <ImageView android:id="@+id/alert_unnumbered" android:layout_width="16dp" android:layout_height="16dp" android:scaleType="fitCenter" android:layout_gravity="center" android:src="@drawable/circle" android:contentDescription="@null" android:tint="@color/settingslib_materialColorPrimaryContainer"/> <FrameLayout android:id="@+id/alert_numbered_frame" android:layout_width="24dp" android:layout_height="24dp" android:layout_gravity="center"> <!-- TODO(b/403326850): color and sizing adjustments --> <ImageView android:id="@+id/alert_number_bg" android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="fitCenter" android:layout_gravity="center" android:src="@drawable/circle" android:contentDescription="@null" android:tint="@color/settingslib_materialColorSecondaryContainer"/> <TextView android:id="@+id/alert_number_fg" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:textColor="@color/settingslib_materialColorOnSecondaryContainer" style="@style/TextAppearance.SettingsLib.TitleMedium" /> </FrameLayout> </FrameLayout> </LinearLayout> src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java +38 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,8 @@ package com.android.settings.dashboard; import static android.content.Intent.EXTRA_USER; import static com.android.settingslib.drawer.EntriesProvider.EXTRA_ALERT_VALUE; import static com.android.settingslib.drawer.EntriesProvider.METHOD_GET_ALERT; import static com.android.settingslib.drawer.SwitchesProvider.EXTRA_SWITCH_CHECKED_STATE; import static com.android.settingslib.drawer.SwitchesProvider.EXTRA_SWITCH_SET_CHECKED_ERROR; import static com.android.settingslib.drawer.SwitchesProvider.EXTRA_SWITCH_SET_CHECKED_ERROR_MESSAGE; Loading @@ -26,6 +28,7 @@ import static com.android.settingslib.drawer.SwitchesProvider.METHOD_GET_DYNAMIC import static com.android.settingslib.drawer.SwitchesProvider.METHOD_GET_PROVIDER_ICON; import static com.android.settingslib.drawer.SwitchesProvider.METHOD_IS_CHECKED; import static com.android.settingslib.drawer.SwitchesProvider.METHOD_ON_CHECKED_CHANGED; import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_ALERT_URI; import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_ICON_URI; import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_SUMMARY; import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_SUMMARY_URI; Loading Loading @@ -70,6 +73,7 @@ import com.android.settings.flags.Flags; import com.android.settings.homepage.TopLevelHighlightMixin; import com.android.settings.homepage.TopLevelSettings; import com.android.settings.overlay.FeatureFactory; import com.android.settings.widget.HomepagePreference; import com.android.settingslib.PrimarySwitchPreference; import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import com.android.settingslib.drawer.ActivityTile; Loading Loading @@ -193,6 +197,10 @@ public class DashboardFeatureProviderImpl implements DashboardFeatureProvider { if (observer != null) { outObservers.add(observer); } observer = bindAlertAndGetObserver(pref, tile); if (observer != null) { outObservers.add(observer); } bindIcon(pref, tile, forceRoundedIcon); if (tile.hasPendingIntent()) { Loading Loading @@ -296,6 +304,9 @@ public class DashboardFeatureProviderImpl implements DashboardFeatureProvider { case METHOD_IS_CHECKED: refreshSwitch(uri, pref, this); break; case METHOD_GET_ALERT: refreshAlert(uri, pref, this); break; } } }; Loading Loading @@ -363,6 +374,33 @@ public class DashboardFeatureProviderImpl implements DashboardFeatureProvider { }); } @Nullable private DynamicDataObserver bindAlertAndGetObserver(Preference preference, Tile tile) { if (!Flags.homepageTileAlert() || !(preference instanceof HomepagePreference)) { return null; } if (tile.getMetaData() != null && tile.getMetaData().containsKey(META_DATA_PREFERENCE_ALERT_URI)) { final Uri uri = TileUtils.getCompleteUri(tile, META_DATA_PREFERENCE_ALERT_URI, METHOD_GET_ALERT); return createDynamicDataObserver(METHOD_GET_ALERT, uri, preference); } return null; } private void refreshAlert(Uri uri, Preference preference, DynamicDataObserver observer) { if (!Flags.homepageTileAlert() || !(preference instanceof HomepagePreference)) { return; } var unused = ThreadUtils.postOnBackgroundThread(() -> { Map<String, IContentProvider> providerMap = new ArrayMap<>(); int valueFromUri = TileUtils.getIntFromUri(mContext, uri, providerMap, EXTRA_ALERT_VALUE); observer.post(() -> ((HomepagePreference) preference).setAlert(valueFromUri)); }); } private DynamicDataObserver bindSwitchAndGetObserver(Preference preference, Tile tile) { if (!tile.hasSwitch()) { return null; Loading src/com/android/settings/widget/HomepagePreference.java +18 −0 Original line number Diff line number Diff line Loading @@ -17,11 +17,15 @@ package com.android.settings.widget; import android.content.Context; import android.os.Bundle; import android.util.AttributeSet; import androidx.preference.Preference; import androidx.preference.PreferenceViewHolder; import com.android.settings.flags.Flags; import com.android.settingslib.drawer.EntriesProvider; /** A customized layout for homepage preference. */ public class HomepagePreference extends Preference implements HomepagePreferenceLayoutHelper.HomepagePreferenceLayout { Loading Loading @@ -59,4 +63,18 @@ public class HomepagePreference extends Preference implements public HomepagePreferenceLayoutHelper getHelper() { return mHelper; } /** * Set the alert count to show for this Preference. */ public void setAlert(int value) { if (Flags.homepageTileAlert()) { Bundle extras = getExtras(); int alertValue = extras.getInt(EntriesProvider.EXTRA_ALERT_VALUE, 0); if (value != alertValue) { mHelper.setAlert(value); extras.putInt(EntriesProvider.EXTRA_ALERT_VALUE, value); } } } } src/com/android/settings/widget/HomepagePreferenceLayoutHelper.java +32 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.settings.widget; import android.view.View; import android.widget.TextView; import androidx.preference.Preference; import androidx.preference.PreferenceViewHolder; Loading @@ -30,9 +31,14 @@ public class HomepagePreferenceLayoutHelper { private View mIcon; private View mText; private View mAlertFrame; private View mAlertUnnumbered; private View mAlertNumberedFrame; private TextView mAlertNumberText; private boolean mIconVisible = true; private int mIconPaddingStart = -1; private int mTextPaddingStart = -1; private int mAlertValue = -1; /** The interface for managing preference layouts on homepage */ public interface HomepagePreferenceLayout { Loading Loading @@ -75,11 +81,37 @@ public class HomepagePreferenceLayoutHelper { } } /** Sets the alert value and view */ public void setAlert(int value) { if (Flags.homepageTileAlert()) { mAlertValue = value; if (mAlertFrame != null && mAlertUnnumbered != null && mAlertNumberedFrame != null && mAlertNumberText != null) { mAlertFrame.setVisibility((value > 0) ? View.VISIBLE : View.GONE); // only display number if it's single digit, more than 1 if (value == 1 || value > 9) { mAlertNumberedFrame.setVisibility(View.GONE); mAlertUnnumbered.setVisibility(View.VISIBLE); } else if (value > 1) { mAlertUnnumbered.setVisibility(View.GONE); mAlertNumberedFrame.setVisibility(View.VISIBLE); mAlertNumberText.setVisibility(View.VISIBLE); mAlertNumberText.setText(String.valueOf(value)); } } } } void onBindViewHolder(PreferenceViewHolder holder) { mIcon = holder.findViewById(R.id.icon_frame); mText = holder.findViewById(R.id.text_frame); mAlertFrame = holder.findViewById(R.id.alert_frame); mAlertUnnumbered = holder.findViewById(R.id.alert_unnumbered); mAlertNumberedFrame = holder.findViewById(R.id.alert_numbered_frame); mAlertNumberText = (TextView) holder.findViewById(R.id.alert_number_fg); setIconVisible(mIconVisible); setIconPaddingStart(mIconPaddingStart); setTextPaddingStart(mTextPaddingStart); setAlert(mAlertValue); } } Loading
aconfig/settings_flag_declarations.aconfig +7 −0 Original line number Diff line number Diff line Loading @@ -104,3 +104,10 @@ flag { description: "Use action corners to trigger a chosen action" bug: "412558312" } flag { name: "homepage_tile_alert" namespace: "android_settings" description: "Enables alert indicator on homepage tiles" bug: "403326850" }
res/layout/homepage_preference_expressive.xml +46 −0 Original line number Diff line number Diff line Loading @@ -83,4 +83,50 @@ android:lineBreakWordStyle="phrase" style="@style/PreferenceSummaryTextStyle"/> </RelativeLayout> <FrameLayout android:id="@+id/alert_frame" android:layout_width="40dp" android:layout_height="40dp" android:visibility="gone" android:layout_gravity="center|end" android:layout_marginEnd="16dp"> <ImageView android:id="@+id/alert_unnumbered" android:layout_width="16dp" android:layout_height="16dp" android:scaleType="fitCenter" android:layout_gravity="center" android:src="@drawable/circle" android:contentDescription="@null" android:tint="@color/settingslib_materialColorPrimaryContainer"/> <FrameLayout android:id="@+id/alert_numbered_frame" android:layout_width="24dp" android:layout_height="24dp" android:layout_gravity="center"> <!-- TODO(b/403326850): color and sizing adjustments --> <ImageView android:id="@+id/alert_number_bg" android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="fitCenter" android:layout_gravity="center" android:src="@drawable/circle" android:contentDescription="@null" android:tint="@color/settingslib_materialColorSecondaryContainer"/> <TextView android:id="@+id/alert_number_fg" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:textColor="@color/settingslib_materialColorOnSecondaryContainer" style="@style/TextAppearance.SettingsLib.TitleMedium" /> </FrameLayout> </FrameLayout> </LinearLayout>
src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java +38 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,8 @@ package com.android.settings.dashboard; import static android.content.Intent.EXTRA_USER; import static com.android.settingslib.drawer.EntriesProvider.EXTRA_ALERT_VALUE; import static com.android.settingslib.drawer.EntriesProvider.METHOD_GET_ALERT; import static com.android.settingslib.drawer.SwitchesProvider.EXTRA_SWITCH_CHECKED_STATE; import static com.android.settingslib.drawer.SwitchesProvider.EXTRA_SWITCH_SET_CHECKED_ERROR; import static com.android.settingslib.drawer.SwitchesProvider.EXTRA_SWITCH_SET_CHECKED_ERROR_MESSAGE; Loading @@ -26,6 +28,7 @@ import static com.android.settingslib.drawer.SwitchesProvider.METHOD_GET_DYNAMIC import static com.android.settingslib.drawer.SwitchesProvider.METHOD_GET_PROVIDER_ICON; import static com.android.settingslib.drawer.SwitchesProvider.METHOD_IS_CHECKED; import static com.android.settingslib.drawer.SwitchesProvider.METHOD_ON_CHECKED_CHANGED; import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_ALERT_URI; import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_ICON_URI; import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_SUMMARY; import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_SUMMARY_URI; Loading Loading @@ -70,6 +73,7 @@ import com.android.settings.flags.Flags; import com.android.settings.homepage.TopLevelHighlightMixin; import com.android.settings.homepage.TopLevelSettings; import com.android.settings.overlay.FeatureFactory; import com.android.settings.widget.HomepagePreference; import com.android.settingslib.PrimarySwitchPreference; import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import com.android.settingslib.drawer.ActivityTile; Loading Loading @@ -193,6 +197,10 @@ public class DashboardFeatureProviderImpl implements DashboardFeatureProvider { if (observer != null) { outObservers.add(observer); } observer = bindAlertAndGetObserver(pref, tile); if (observer != null) { outObservers.add(observer); } bindIcon(pref, tile, forceRoundedIcon); if (tile.hasPendingIntent()) { Loading Loading @@ -296,6 +304,9 @@ public class DashboardFeatureProviderImpl implements DashboardFeatureProvider { case METHOD_IS_CHECKED: refreshSwitch(uri, pref, this); break; case METHOD_GET_ALERT: refreshAlert(uri, pref, this); break; } } }; Loading Loading @@ -363,6 +374,33 @@ public class DashboardFeatureProviderImpl implements DashboardFeatureProvider { }); } @Nullable private DynamicDataObserver bindAlertAndGetObserver(Preference preference, Tile tile) { if (!Flags.homepageTileAlert() || !(preference instanceof HomepagePreference)) { return null; } if (tile.getMetaData() != null && tile.getMetaData().containsKey(META_DATA_PREFERENCE_ALERT_URI)) { final Uri uri = TileUtils.getCompleteUri(tile, META_DATA_PREFERENCE_ALERT_URI, METHOD_GET_ALERT); return createDynamicDataObserver(METHOD_GET_ALERT, uri, preference); } return null; } private void refreshAlert(Uri uri, Preference preference, DynamicDataObserver observer) { if (!Flags.homepageTileAlert() || !(preference instanceof HomepagePreference)) { return; } var unused = ThreadUtils.postOnBackgroundThread(() -> { Map<String, IContentProvider> providerMap = new ArrayMap<>(); int valueFromUri = TileUtils.getIntFromUri(mContext, uri, providerMap, EXTRA_ALERT_VALUE); observer.post(() -> ((HomepagePreference) preference).setAlert(valueFromUri)); }); } private DynamicDataObserver bindSwitchAndGetObserver(Preference preference, Tile tile) { if (!tile.hasSwitch()) { return null; Loading
src/com/android/settings/widget/HomepagePreference.java +18 −0 Original line number Diff line number Diff line Loading @@ -17,11 +17,15 @@ package com.android.settings.widget; import android.content.Context; import android.os.Bundle; import android.util.AttributeSet; import androidx.preference.Preference; import androidx.preference.PreferenceViewHolder; import com.android.settings.flags.Flags; import com.android.settingslib.drawer.EntriesProvider; /** A customized layout for homepage preference. */ public class HomepagePreference extends Preference implements HomepagePreferenceLayoutHelper.HomepagePreferenceLayout { Loading Loading @@ -59,4 +63,18 @@ public class HomepagePreference extends Preference implements public HomepagePreferenceLayoutHelper getHelper() { return mHelper; } /** * Set the alert count to show for this Preference. */ public void setAlert(int value) { if (Flags.homepageTileAlert()) { Bundle extras = getExtras(); int alertValue = extras.getInt(EntriesProvider.EXTRA_ALERT_VALUE, 0); if (value != alertValue) { mHelper.setAlert(value); extras.putInt(EntriesProvider.EXTRA_ALERT_VALUE, value); } } } }
src/com/android/settings/widget/HomepagePreferenceLayoutHelper.java +32 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.settings.widget; import android.view.View; import android.widget.TextView; import androidx.preference.Preference; import androidx.preference.PreferenceViewHolder; Loading @@ -30,9 +31,14 @@ public class HomepagePreferenceLayoutHelper { private View mIcon; private View mText; private View mAlertFrame; private View mAlertUnnumbered; private View mAlertNumberedFrame; private TextView mAlertNumberText; private boolean mIconVisible = true; private int mIconPaddingStart = -1; private int mTextPaddingStart = -1; private int mAlertValue = -1; /** The interface for managing preference layouts on homepage */ public interface HomepagePreferenceLayout { Loading Loading @@ -75,11 +81,37 @@ public class HomepagePreferenceLayoutHelper { } } /** Sets the alert value and view */ public void setAlert(int value) { if (Flags.homepageTileAlert()) { mAlertValue = value; if (mAlertFrame != null && mAlertUnnumbered != null && mAlertNumberedFrame != null && mAlertNumberText != null) { mAlertFrame.setVisibility((value > 0) ? View.VISIBLE : View.GONE); // only display number if it's single digit, more than 1 if (value == 1 || value > 9) { mAlertNumberedFrame.setVisibility(View.GONE); mAlertUnnumbered.setVisibility(View.VISIBLE); } else if (value > 1) { mAlertUnnumbered.setVisibility(View.GONE); mAlertNumberedFrame.setVisibility(View.VISIBLE); mAlertNumberText.setVisibility(View.VISIBLE); mAlertNumberText.setText(String.valueOf(value)); } } } } void onBindViewHolder(PreferenceViewHolder holder) { mIcon = holder.findViewById(R.id.icon_frame); mText = holder.findViewById(R.id.text_frame); mAlertFrame = holder.findViewById(R.id.alert_frame); mAlertUnnumbered = holder.findViewById(R.id.alert_unnumbered); mAlertNumberedFrame = holder.findViewById(R.id.alert_numbered_frame); mAlertNumberText = (TextView) holder.findViewById(R.id.alert_number_fg); setIconVisible(mIconVisible); setIconPaddingStart(mIconPaddingStart); setTextPaddingStart(mTextPaddingStart); setAlert(mAlertValue); } }