Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 388c5261 authored by Chris Antol's avatar Chris Antol
Browse files

Support Alert UX for Homepage tiles

Bug: 403326850
Test: local debug code
Flag: com.android.settings.flags.homepage_tile_alert
Change-Id: I0c66e6f79f7396f3dd6fb8300f97348b9b5c7848
parent f3e65f1e
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -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"
}
+46 −0
Original line number Diff line number Diff line
@@ -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>
+38 −0
Original line number Diff line number Diff line
@@ -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;
@@ -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;
@@ -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;
@@ -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()) {
@@ -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;
                }
            }
        };
@@ -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;
+18 −0
Original line number Diff line number Diff line
@@ -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 {
@@ -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);
            }
        }
    }
}
+32 −0
Original line number Diff line number Diff line
@@ -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;
@@ -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 {
@@ -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);
    }
}