Merge "Fix "Free up space" not clickable issue" into main
diff --git a/res/xml/power_usage_summary.xml b/res/xml/power_usage_summary.xml
index 1af8a8c..77c6b73 100644
--- a/res/xml/power_usage_summary.xml
+++ b/res/xml/power_usage_summary.xml
@@ -33,7 +33,7 @@
         android:selectable="false"
         settings:searchable="false" />
 
-    <com.android.settings.widget.CardPreference
+    <com.android.settings.widget.TipCardPreference
         android:key="battery_tip"
         android:title="@string/summary_placeholder"
         settings:controller="com.android.settings.fuelgauge.batterytip.BatteryTipPreferenceController" />
diff --git a/src/com/android/settings/fuelgauge/batterytip/BatteryTipPreferenceController.java b/src/com/android/settings/fuelgauge/batterytip/BatteryTipPreferenceController.java
index 31cec6a..e6f622c 100644
--- a/src/com/android/settings/fuelgauge/batterytip/BatteryTipPreferenceController.java
+++ b/src/com/android/settings/fuelgauge/batterytip/BatteryTipPreferenceController.java
@@ -33,7 +33,7 @@
 import com.android.settings.fuelgauge.batterytip.actions.BatteryTipAction;
 import com.android.settings.fuelgauge.batterytip.tips.BatteryTip;
 import com.android.settings.overlay.FeatureFactory;
-import com.android.settings.widget.CardPreference;
+import com.android.settings.widget.TipCardPreference;
 import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 import java.util.List;
@@ -55,7 +55,7 @@
     private SettingsActivity mSettingsActivity;
     private MetricsFeatureProvider mMetricsFeatureProvider;
     private boolean mNeedUpdate;
-    @VisibleForTesting CardPreference mCardPreference;
+    @VisibleForTesting TipCardPreference mCardPreference;
     @VisibleForTesting Context mPrefContext;
     InstrumentedPreferenceFragment mFragment;
 
diff --git a/src/com/android/settings/fuelgauge/batterytip/tips/BatteryDefenderTip.java b/src/com/android/settings/fuelgauge/batterytip/tips/BatteryDefenderTip.java
index 3716244..dbe2722 100644
--- a/src/com/android/settings/fuelgauge/batterytip/tips/BatteryDefenderTip.java
+++ b/src/com/android/settings/fuelgauge/batterytip/tips/BatteryDefenderTip.java
@@ -28,7 +28,6 @@
 
 import com.android.settings.R;
 import com.android.settings.overlay.FeatureFactory;
-import com.android.settings.widget.CardPreference;
 import com.android.settingslib.HelpUtils;
 import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
@@ -80,9 +79,9 @@
         super.updatePreference(preference);
         final Context context = preference.getContext();
 
-        CardPreference cardPreference = castToCardPreferenceSafely(preference);
+        var cardPreference = castToTipCardPreferenceSafely(preference);
         if (cardPreference == null) {
-            Log.e(TAG, "cast Preference to CardPreference failed");
+            Log.e(TAG, "cast Preference to TipCardPreference failed");
             return;
         }
 
diff --git a/src/com/android/settings/fuelgauge/batterytip/tips/BatteryTip.java b/src/com/android/settings/fuelgauge/batterytip/tips/BatteryTip.java
index 1345032..1f5374d 100644
--- a/src/com/android/settings/fuelgauge/batterytip/tips/BatteryTip.java
+++ b/src/com/android/settings/fuelgauge/batterytip/tips/BatteryTip.java
@@ -23,10 +23,11 @@
 
 import androidx.annotation.DrawableRes;
 import androidx.annotation.IntDef;
+import androidx.annotation.Nullable;
 import androidx.annotation.VisibleForTesting;
 import androidx.preference.Preference;
 
-import com.android.settings.widget.CardPreference;
+import com.android.settings.widget.TipCardPreference;
 import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 import java.lang.annotation.Retention;
@@ -165,7 +166,7 @@
         preference.setTitle(getTitle(context));
         preference.setSummary(getSummary(context));
         preference.setIcon(getIconId());
-        final CardPreference cardPreference = castToCardPreferenceSafely(preference);
+        final TipCardPreference cardPreference = castToTipCardPreferenceSafely(preference);
         if (cardPreference != null) {
             cardPreference.resetLayoutState();
         }
@@ -206,7 +207,9 @@
         return "type=" + mType + " state=" + mState;
     }
 
-    public CardPreference castToCardPreferenceSafely(Preference preference) {
-        return preference instanceof CardPreference ? (CardPreference) preference : null;
+    /** Returns the converted {@link TipCardPreference} if it is valid. */
+    @Nullable
+    public TipCardPreference castToTipCardPreferenceSafely(Preference preference) {
+        return preference instanceof TipCardPreference ? (TipCardPreference) preference : null;
     }
 }
diff --git a/src/com/android/settings/fuelgauge/batterytip/tips/IncompatibleChargerTip.java b/src/com/android/settings/fuelgauge/batterytip/tips/IncompatibleChargerTip.java
index 72c710c..7453ded 100644
--- a/src/com/android/settings/fuelgauge/batterytip/tips/IncompatibleChargerTip.java
+++ b/src/com/android/settings/fuelgauge/batterytip/tips/IncompatibleChargerTip.java
@@ -26,7 +26,6 @@
 import androidx.preference.Preference;
 
 import com.android.settings.R;
-import com.android.settings.widget.CardPreference;
 import com.android.settingslib.HelpUtils;
 import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
@@ -74,7 +73,7 @@
     public void updatePreference(Preference preference) {
         super.updatePreference(preference);
         final Context context = preference.getContext();
-        final CardPreference cardPreference = castToCardPreferenceSafely(preference);
+        final var cardPreference = castToTipCardPreferenceSafely(preference);
         if (cardPreference == null) {
             Log.e(TAG, "cast Preference to CardPreference failed");
             return;
diff --git a/src/com/android/settings/widget/CardPreference.java b/src/com/android/settings/widget/CardPreference.java
new file mode 100644
index 0000000..db6827e
--- /dev/null
+++ b/src/com/android/settings/widget/CardPreference.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2019 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 android.widget.Button;
+
+import androidx.annotation.Nullable;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceViewHolder;
+
+import com.android.settings.R;
+
+import com.google.android.material.card.MaterialCardView;
+
+import java.util.Optional;
+
+/** Preference that wrapped by {@link MaterialCardView} */
+public class CardPreference extends Preference {
+    @Nullable private View.OnClickListener mPrimaryBtnClickListener = null;
+    @Nullable private View.OnClickListener mSecondaryBtnClickListener = null;
+    @Nullable private String mPrimaryButtonText = null;
+    @Nullable private String mSecondaryButtonText = null;
+    private Optional<Button> mPrimaryButton = Optional.empty();
+    private Optional<Button> mSecondaryButton = Optional.empty();
+    private Optional<View> mButtonsGroup = Optional.empty();
+    private boolean mPrimaryButtonVisible = false;
+    private boolean mSecondaryButtonVisible = false;
+
+    public CardPreference(Context context) {
+        this(context, null /* attrs */);
+    }
+
+    public CardPreference(Context context, @Nullable AttributeSet attrs) {
+        super(context, attrs, R.attr.cardPreferenceStyle);
+    }
+
+    @Override
+    public void onBindViewHolder(PreferenceViewHolder holder) {
+        super.onBindViewHolder(holder);
+        initButtonsAndLayout(holder);
+    }
+
+    private void initButtonsAndLayout(PreferenceViewHolder holder) {
+        mPrimaryButton = Optional.ofNullable((Button) holder.findViewById(android.R.id.button1));
+        mSecondaryButton = Optional.ofNullable((Button) holder.findViewById(android.R.id.button2));
+        mButtonsGroup = Optional.ofNullable(holder.findViewById(R.id.card_preference_buttons));
+        setPrimaryButtonText(mPrimaryButtonText);
+        setPrimaryButtonClickListener(mPrimaryBtnClickListener);
+        setPrimaryButtonVisible(mPrimaryButtonVisible);
+        setSecondaryButtonText(mSecondaryButtonText);
+        setSecondaryButtonClickListener(mSecondaryBtnClickListener);
+        setSecondaryButtonVisible(mSecondaryButtonVisible);
+    }
+
+    /** Clear layout state if needed */
+    public void resetLayoutState() {
+        setPrimaryButtonVisible(false);
+        setSecondaryButtonVisible(false);
+    }
+
+    /**
+     * Register a callback to be invoked when the primary button is clicked.
+     *
+     * @param l the callback that will run
+     */
+    public void setPrimaryButtonClickListener(View.OnClickListener l) {
+        mPrimaryButton.ifPresent(button -> button.setOnClickListener(l));
+        mPrimaryBtnClickListener = l;
+    }
+
+    /**
+     * Register a callback to be invoked when the secondary button is clicked.
+     *
+     * @param l the callback that will run
+     */
+    public void setSecondaryButtonClickListener(View.OnClickListener l) {
+        mSecondaryButton.ifPresent(button -> button.setOnClickListener(l));
+        mSecondaryBtnClickListener = l;
+    }
+
+    /**
+     * Sets the text to be displayed on primary button.
+     *
+     * @param text text to be displayed
+     */
+    public void setPrimaryButtonText(String text) {
+        mPrimaryButton.ifPresent(button -> button.setText(text));
+        mPrimaryButtonText = text;
+    }
+
+    /**
+     * Sets the text to be displayed on secondary button.
+     *
+     * @param text text to be displayed
+     */
+    public void setSecondaryButtonText(String text) {
+        mSecondaryButton.ifPresent(button -> button.setText(text));
+        mSecondaryButtonText = text;
+    }
+
+    /**
+     * Set the visible on the primary button.
+     *
+     * @param visible {@code true} for visible
+     */
+    public void setPrimaryButtonVisible(boolean visible) {
+        mPrimaryButton.ifPresent(
+                button -> button.setVisibility(visible ? View.VISIBLE : View.GONE));
+        mPrimaryButtonVisible = visible;
+        updateButtonGroupsVisibility();
+    }
+
+    /**
+     * Set the visible on the secondary button.
+     *
+     * @param visible {@code true} for visible
+     */
+    public void setSecondaryButtonVisible(boolean visible) {
+        mSecondaryButton.ifPresent(
+                button -> button.setVisibility(visible ? View.VISIBLE : View.GONE));
+        mSecondaryButtonVisible = visible;
+        updateButtonGroupsVisibility();
+    }
+
+    /**
+     * Sets the text of content description on primary button.
+     *
+     * @param text text for the content description
+     */
+    public void setPrimaryButtonContentDescription(String text) {
+        mPrimaryButton.ifPresent(button -> button.setContentDescription(text));
+    }
+
+    /**
+     * Sets the text of content description on secondary button.
+     *
+     * @param text text for the content description
+     */
+    public void setSecondaryButtonContentDescription(String text) {
+        mSecondaryButton.ifPresent(button -> button.setContentDescription(text));
+    }
+
+    private void updateButtonGroupsVisibility() {
+        int visibility =
+                (mPrimaryButtonVisible || mSecondaryButtonVisible) ? View.VISIBLE : View.GONE;
+        mButtonsGroup.ifPresent(group -> group.setVisibility(visibility));
+    }
+}
diff --git a/src/com/android/settings/widget/CardPreference.kt b/src/com/android/settings/widget/TipCardPreference.kt
similarity index 99%
rename from src/com/android/settings/widget/CardPreference.kt
rename to src/com/android/settings/widget/TipCardPreference.kt
index 010d7de..0ae7d2a 100644
--- a/src/com/android/settings/widget/CardPreference.kt
+++ b/src/com/android/settings/widget/TipCardPreference.kt
@@ -27,7 +27,7 @@
 import com.android.settingslib.spa.widget.card.SettingsCard
 
 /** A preference for settings banner tips card. */
-class CardPreference
+class TipCardPreference
 @JvmOverloads
 constructor(
     context: Context,
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipPreferenceControllerTest.java
index c05d9ed..4bb6695 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipPreferenceControllerTest.java
@@ -33,7 +33,7 @@
 import com.android.settings.core.BasePreferenceController;
 import com.android.settings.core.InstrumentedPreferenceFragment;
 import com.android.settings.fuelgauge.batterytip.tips.BatteryTip;
-import com.android.settings.widget.CardPreference;
+import com.android.settings.widget.TipCardPreference;
 
 import org.junit.Before;
 import org.junit.Rule;
@@ -61,7 +61,7 @@
     @Mock private InstrumentedPreferenceFragment mFragment;
 
     private Context mContext;
-    private CardPreference mCardPreference;
+    private TipCardPreference mCardPreference;
     private BatteryTipPreferenceController mBatteryTipPreferenceController;
     private List<BatteryTip> mNewBatteryTips;
 
@@ -69,7 +69,7 @@
     public void setUp() {
         mContext = ApplicationProvider.getApplicationContext();
 
-        mCardPreference = new CardPreference(mContext);
+        mCardPreference = new TipCardPreference(mContext);
         when(mPreferenceScreen.getContext()).thenReturn(mContext);
         doReturn(mCardPreference).when(mPreferenceScreen).findPreference(KEY_PREF);
 
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/tips/BatteryDefenderTipTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/tips/BatteryDefenderTipTest.java
index a605ee3..c0edb87 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/tips/BatteryDefenderTipTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/tips/BatteryDefenderTipTest.java
@@ -29,7 +29,7 @@
 
 import com.android.settings.R;
 import com.android.settings.testutils.FakeFeatureFactory;
-import com.android.settings.widget.CardPreference;
+import com.android.settings.widget.TipCardPreference;
 import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 import org.junit.Before;
@@ -49,7 +49,7 @@
     private FakeFeatureFactory mFeatureFactory;
     private BatteryDefenderTip mBatteryDefenderTip;
     private MetricsFeatureProvider mMetricsFeatureProvider;
-    private CardPreference mCardPreference;
+    private TipCardPreference mCardPreference;
 
     @Rule public MockitoRule mMockitoRule = MockitoJUnit.rule();
     @Mock private BatteryTip mBatteryTip;
@@ -62,7 +62,7 @@
         mMetricsFeatureProvider = mFeatureFactory.metricsFeatureProvider;
         mBatteryDefenderTip =
                 new BatteryDefenderTip(BatteryTip.StateType.NEW, /* isPluggedIn= */ false);
-        mCardPreference = new CardPreference(mContext);
+        mCardPreference = new TipCardPreference(mContext);
 
         when(mPreference.getContext()).thenReturn(mContext);
     }
@@ -98,7 +98,7 @@
     public void updatePreference_castFail_logErrorMessage() {
         mBatteryDefenderTip.updatePreference(mPreference);
 
-        assertThat(getLastErrorLog()).isEqualTo("cast Preference to CardPreference failed");
+        assertThat(getLastErrorLog()).isEqualTo("cast Preference to TipCardPreference failed");
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/tips/BatteryTipTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/tips/BatteryTipTest.java
index 097f484..77249fe 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/tips/BatteryTipTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/tips/BatteryTipTest.java
@@ -26,7 +26,7 @@
 import androidx.test.core.app.ApplicationProvider;
 
 import com.android.settings.R;
-import com.android.settings.widget.CardPreference;
+import com.android.settings.widget.TipCardPreference;
 import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 import com.android.settingslib.testutils.DrawableTestHelper;
 
@@ -87,7 +87,7 @@
 
     @Test
     public void updatePreference_resetLayoutState() {
-        CardPreference cardPreference = new CardPreference(mContext);
+        var cardPreference = new TipCardPreference(mContext);
         cardPreference.setPrimaryButtonVisibility(true);
         cardPreference.setSecondaryButtonVisibility(true);
 
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/tips/IncompatibleChargerTipTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/tips/IncompatibleChargerTipTest.java
index 7a23332..9b4d179 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/tips/IncompatibleChargerTipTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/tips/IncompatibleChargerTipTest.java
@@ -29,7 +29,7 @@
 
 import com.android.settings.R;
 import com.android.settings.testutils.FakeFeatureFactory;
-import com.android.settings.widget.CardPreference;
+import com.android.settings.widget.TipCardPreference;
 import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 import org.junit.Before;
@@ -49,7 +49,7 @@
     private FakeFeatureFactory mFeatureFactory;
     private IncompatibleChargerTip mIncompatibleChargerTip;
     private MetricsFeatureProvider mMetricsFeatureProvider;
-    private CardPreference mCardPreference;
+    private TipCardPreference mCardPreference;
 
     @Rule public MockitoRule mMockitoRule = MockitoJUnit.rule();
     @Mock private BatteryTip mBatteryTip;
@@ -61,7 +61,7 @@
         mMetricsFeatureProvider = mFeatureFactory.metricsFeatureProvider;
         mContext = ApplicationProvider.getApplicationContext();
         mIncompatibleChargerTip = new IncompatibleChargerTip(BatteryTip.StateType.NEW);
-        mCardPreference = new CardPreference(mContext);
+        mCardPreference = new TipCardPreference(mContext);
 
         when(mPreference.getContext()).thenReturn(mContext);
     }
diff --git a/tests/robotests/src/com/android/settings/widget/CardPreferenceTest.java b/tests/robotests/src/com/android/settings/widget/CardPreferenceTest.java
new file mode 100644
index 0000000..76892e2
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/widget/CardPreferenceTest.java
@@ -0,0 +1,293 @@
+/*
+ * Copyright (C) 2019 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
+ *Visibility_setGoneForPrimaryButton_buttonGroupIsGone
+ * 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 static android.view.View.GONE;
+import static android.view.View.VISIBLE;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import android.content.Context;
+import android.view.View;
+import android.widget.Button;
+
+import androidx.preference.PreferenceViewHolder;
+import androidx.test.core.app.ApplicationProvider;
+
+import com.android.settings.R;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+
+@RunWith(RobolectricTestRunner.class)
+public class CardPreferenceTest {
+    private CardPreference mCardPreference;
+    private PreferenceViewHolder mHolder;
+
+    @Before
+    public void setUp() {
+        Context context = ApplicationProvider.getApplicationContext();
+        context.setTheme(R.style.Theme_Settings);
+        mCardPreference = new CardPreference(context);
+        mHolder =
+                PreferenceViewHolder.createInstanceForTests(
+                        View.inflate(context, R.layout.card_preference_layout, /* parent= */ null));
+    }
+
+    @Test
+    public void newACardPreference_layoutResourceShouldBeCardPreferenceLayout() {
+        Context context = ApplicationProvider.getApplicationContext();
+        context.setTheme(R.style.SettingsPreferenceTheme);
+        CardPreference cardPreference = new CardPreference(context);
+        assertThat(cardPreference.getLayoutResource()).isEqualTo(R.layout.card_preference_layout);
+    }
+
+    @Test
+    public void onBindViewHolder_noButtonVisible_buttonsLayoutIsGone() {
+        mCardPreference.onBindViewHolder(mHolder);
+        assertThat(getCardPreferenceButtonsView().getVisibility()).isEqualTo(GONE);
+    }
+
+    @Test
+    public void onBindViewHolder_setPrimaryButtonVisibility_buttonsLayoutIsVisible() {
+        mCardPreference.setPrimaryButtonVisible(true);
+        mCardPreference.onBindViewHolder(mHolder);
+        assertThat(getCardPreferenceButtonsView().getVisibility()).isEqualTo(VISIBLE);
+    }
+
+    @Test
+    public void onBindViewHolder_setPrimaryButtonVisibilityToVisible() {
+        mCardPreference.setPrimaryButtonVisible(true);
+        mCardPreference.onBindViewHolder(mHolder);
+        assertThat(getPrimaryButton().getVisibility()).isEqualTo(VISIBLE);
+    }
+
+    @Test
+    public void onBindViewHolder_setSecondaryButtonVisibility_buttonsLayoutIsVisible() {
+        mCardPreference.setSecondaryButtonVisible(true);
+        mCardPreference.onBindViewHolder(mHolder);
+        assertThat(getCardPreferenceButtonsView().getVisibility()).isEqualTo(VISIBLE);
+    }
+
+    @Test
+    public void onBindViewHolder_setSecondaryButtonVisibilityToVisible() {
+        mCardPreference.setSecondaryButtonVisible(true);
+        mCardPreference.onBindViewHolder(mHolder);
+        assertThat(getSecondaryButton().getVisibility()).isEqualTo(VISIBLE);
+    }
+
+    @Test
+    public void onBindViewHolder_setPrimaryButtonTextToExpectedText() {
+        String expectedText = "primary-button";
+        mCardPreference.setPrimaryButtonText(expectedText);
+        mCardPreference.onBindViewHolder(mHolder);
+        assertThat(getPrimaryButton().getText().toString()).isEqualTo(expectedText);
+    }
+
+    @Test
+    public void onBindViewHolder_setSecondaryButtonTextToExpectedText() {
+        String expectedText = "secondary-button";
+        mCardPreference.setSecondaryButtonText(expectedText);
+        mCardPreference.onBindViewHolder(mHolder);
+        assertThat(getSecondaryButton().getText().toString()).isEqualTo(expectedText);
+    }
+
+    @Test
+    public void onBindViewHolder_initialTextForPrimaryButtonShouldBeEmpty() {
+        mCardPreference.onBindViewHolder(mHolder);
+        assertThat(getPrimaryButton().getText().toString()).isEqualTo("");
+    }
+
+    @Test
+    public void onBindViewHolder_initialTextForSecondaryButtonShouldBeEmpty() {
+        mCardPreference.onBindViewHolder(mHolder);
+        assertThat(getSecondaryButton().getText().toString()).isEqualTo("");
+    }
+
+    @Test
+    public void performClickOnPrimaryButton_callClickListener() {
+        final boolean[] hasCalled = {false};
+        View.OnClickListener clickListener = v -> hasCalled[0] = true;
+        mCardPreference.setPrimaryButtonClickListener(clickListener);
+        mCardPreference.onBindViewHolder(mHolder);
+        getPrimaryButton().performClick();
+        assertThat(hasCalled[0]).isTrue();
+    }
+
+    @Test
+    public void performClickOnSecondaryButton_callClickListener() {
+        final boolean[] hasCalled = {false};
+        View.OnClickListener clickListener = v -> hasCalled[0] = true;
+        mCardPreference.setSecondaryButtonClickListener(clickListener);
+        mCardPreference.onBindViewHolder(mHolder);
+        getSecondaryButton().performClick();
+        assertThat(hasCalled[0]).isTrue();
+    }
+
+    @Test
+    public void onBindViewHolder_primaryButtonDefaultIsGone() {
+        mCardPreference.onBindViewHolder(mHolder);
+        assertThat(getPrimaryButton().getVisibility()).isEqualTo(GONE);
+    }
+
+    @Test
+    public void onBindViewHolder_secondaryButtonDefaultIsGone() {
+        mCardPreference.onBindViewHolder(mHolder);
+        assertThat(getSecondaryButton().getVisibility()).isEqualTo(GONE);
+    }
+
+    @Test
+    public void setPrimaryButtonVisibility_setTrueAfterBindViewHolder_isVisible() {
+        mCardPreference.setPrimaryButtonVisible(false);
+        mCardPreference.onBindViewHolder(mHolder);
+        mCardPreference.setPrimaryButtonVisible(true);
+        assertThat(getPrimaryButton().getVisibility()).isEqualTo(VISIBLE);
+    }
+
+    @Test
+    public void setPrimaryButtonText_setAfterBindViewHolder_setOnUi() {
+        String expectedText = "123456";
+        mCardPreference.onBindViewHolder(mHolder);
+        mCardPreference.setPrimaryButtonText(expectedText);
+        assertThat(getPrimaryButton().getText().toString()).isEqualTo(expectedText);
+    }
+
+    @Test
+    public void setPrimaryButtonText_setNull_isEmptyText() {
+        final String emptyString = "";
+        mCardPreference.setPrimaryButtonText("1234");
+        mCardPreference.onBindViewHolder(mHolder);
+        mCardPreference.setPrimaryButtonText(null);
+        assertThat(getPrimaryButton().getText().toString()).isEqualTo(emptyString);
+    }
+
+    @Test
+    public void setPrimaryButtonClickListener_setAfterOnBindViewHolder() {
+        final String[] hasCalled = {""};
+        String expectedClickedResult = "was called";
+        View.OnClickListener clickListener = v -> hasCalled[0] = expectedClickedResult;
+        mCardPreference.onBindViewHolder(mHolder);
+        mCardPreference.setPrimaryButtonClickListener(clickListener);
+        getPrimaryButton().performClick();
+        assertThat(hasCalled[0]).isEqualTo(expectedClickedResult);
+    }
+
+    @Test
+    public void setPrimaryButtonClickListener_setNull_clearTheOnClickListener() {
+        final String[] hasCalled = {"not called"};
+        View.OnClickListener clickListener = v -> hasCalled[0] = "called once";
+        mCardPreference.setPrimaryButtonClickListener(clickListener);
+        mCardPreference.onBindViewHolder(mHolder);
+        mCardPreference.setPrimaryButtonClickListener(null);
+        getPrimaryButton().performClick();
+        assertThat(hasCalled[0]).isEqualTo("not called");
+    }
+
+    @Test
+    public void setSecondaryButtonVisibility_setTrueAfterBindViewHolder_isVisible() {
+        mCardPreference.setSecondaryButtonVisible(false);
+        mCardPreference.onBindViewHolder(mHolder);
+        mCardPreference.setSecondaryButtonVisible(true);
+        assertThat(getSecondaryButton().getVisibility()).isEqualTo(VISIBLE);
+    }
+
+    @Test
+    public void setSecondaryButtonText_setAfterBindViewHolder_setOnUi() {
+        String expectedText = "10101010";
+        mCardPreference.onBindViewHolder(mHolder);
+        mCardPreference.setSecondaryButtonText(expectedText);
+        assertThat(getSecondaryButton().getText().toString()).isEqualTo(expectedText);
+    }
+
+    @Test
+    public void setSecondaryButtonText_setNull_isEmptyText() {
+        String emptyString = "";
+        mCardPreference.setSecondaryButtonText("1234");
+        mCardPreference.onBindViewHolder(mHolder);
+        mCardPreference.setSecondaryButtonText(null);
+        assertThat(getSecondaryButton().getText().toString()).isEqualTo(emptyString);
+    }
+
+    @Test
+    public void setSecondaryButtonClickListener_setAfterOnBindViewHolder() {
+        final String[] hasCalled = {""};
+        String expectedClickedResult = "2nd was called";
+        View.OnClickListener clickListener = v -> hasCalled[0] = expectedClickedResult;
+        mCardPreference.onBindViewHolder(mHolder);
+        mCardPreference.setSecondaryButtonClickListener(clickListener);
+        getSecondaryButton().performClick();
+        assertThat(hasCalled[0]).isEqualTo(expectedClickedResult);
+    }
+
+    @Test
+    public void setSecondaryButtonClickListener_setNull_clearTheOnClickListener() {
+        final String[] hasCalled = {"not called"};
+        View.OnClickListener clickListener = v -> hasCalled[0] = "called once";
+        mCardPreference.setSecondaryButtonClickListener(clickListener);
+        mCardPreference.onBindViewHolder(mHolder);
+        mCardPreference.setSecondaryButtonClickListener(null);
+        getSecondaryButton().performClick();
+        assertThat(hasCalled[0]).isEqualTo("not called");
+    }
+
+    @Test
+    public void setPrimaryButtonVisibility_setGoneForSecondaryButton_buttonGroupIsGone() {
+        mCardPreference.setPrimaryButtonVisible(true);
+        mCardPreference.setSecondaryButtonVisible(false);
+        mCardPreference.onBindViewHolder(mHolder);
+        assertWithMessage("PreCondition: buttonsView should be Visible")
+                .that(getCardPreferenceButtonsView().getVisibility())
+                .isEqualTo(VISIBLE);
+        mCardPreference.setPrimaryButtonVisible(false);
+        assertThat(getCardPreferenceButtonsView().getVisibility()).isEqualTo(GONE);
+    }
+
+    @Test
+    public void setSecondaryButtonVisibility_setGoneForPrimaryButton_buttonGroupIsGone() {
+        mCardPreference.setPrimaryButtonVisible(false);
+        mCardPreference.setSecondaryButtonVisible(true);
+        mCardPreference.onBindViewHolder(mHolder);
+        assertWithMessage("PreCondition: buttonsView should be Visible")
+                .that(getCardPreferenceButtonsView().getVisibility())
+                .isEqualTo(VISIBLE);
+        mCardPreference.setSecondaryButtonVisible(false);
+        assertThat(getCardPreferenceButtonsView().getVisibility()).isEqualTo(GONE);
+    }
+
+    @Test
+    public void resetLayoutState_buttonGroupIsGone() {
+        mCardPreference.setPrimaryButtonVisible(true);
+        mCardPreference.setSecondaryButtonVisible(true);
+        mCardPreference.onBindViewHolder(mHolder);
+        mCardPreference.resetLayoutState();
+        assertThat(getCardPreferenceButtonsView().getVisibility()).isEqualTo(GONE);
+    }
+
+    private View getCardPreferenceButtonsView() {
+        return mHolder.findViewById(R.id.card_preference_buttons);
+    }
+
+    private Button getPrimaryButton() {
+        return (Button) mHolder.findViewById(android.R.id.button1);
+    }
+
+    private Button getSecondaryButton() {
+        return (Button) mHolder.findViewById(android.R.id.button2);
+    }
+}
diff --git a/tests/spa_unit/src/com/android/settings/widget/CardPreferenceTest.kt b/tests/spa_unit/src/com/android/settings/widget/TipCardPreferenceTest.kt
similarity index 98%
rename from tests/spa_unit/src/com/android/settings/widget/CardPreferenceTest.kt
rename to tests/spa_unit/src/com/android/settings/widget/TipCardPreferenceTest.kt
index 0483e36..aeea69f 100644
--- a/tests/spa_unit/src/com/android/settings/widget/CardPreferenceTest.kt
+++ b/tests/spa_unit/src/com/android/settings/widget/TipCardPreferenceTest.kt
@@ -35,7 +35,7 @@
 import org.junit.runner.RunWith
 
 @RunWith(AndroidJUnit4::class)
-class CardPreferenceTest {
+class TipCardPreferenceTest {
 
     @get:Rule val composeTestRule = createComposeRule()
     private lateinit var context: Context
@@ -179,7 +179,7 @@
     fun resetLayoutState_shouldRemoveThePrimaryButton() {
         val buttonText = "9527"
         val cardPreference =
-            CardPreference(context)
+            TipCardPreference(context)
                 .apply {
                     primaryButtonText = buttonText
                     primaryButtonVisibility = true
@@ -196,7 +196,7 @@
     fun resetLayoutState_shouldRemoveTheSecondaryButton() {
         val buttonText = "4567"
         val cardPreference =
-            CardPreference(context)
+            TipCardPreference(context)
                 .apply {
                     secondaryButtonText = buttonText
                     secondaryButtonVisibility = true
@@ -222,7 +222,7 @@
         secondaryButtonVisibility: Boolean = false,
         enableDismiss: Boolean = true,
     ) =
-        CardPreference(context)
+        TipCardPreference(context)
             .apply {
                 this.iconResId = iconResId
                 this.primaryButtonText = primaryButtonText