Clean up ConditionalCards

Use ConditionalContextualCard directly.

Change-Id: If2e51cdd2cbed27b0094bbb9be06ee9a67f328ec
Fixes: 114307767
Test: robotests
diff --git a/src/com/android/settings/homepage/contextualcards/conditional/AirplaneModeConditionCard.java b/src/com/android/settings/homepage/contextualcards/conditional/AirplaneModeConditionCard.java
deleted file mode 100644
index d4fc275..0000000
--- a/src/com/android/settings/homepage/contextualcards/conditional/AirplaneModeConditionCard.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2018 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.homepage.contextualcards.conditional;
-
-import android.content.Context;
-import android.graphics.drawable.Drawable;
-
-import com.android.internal.logging.nano.MetricsProto;
-import com.android.settings.R;
-
-public class AirplaneModeConditionCard implements ConditionalCard {
-
-    private final Context mAppContext;
-
-    public AirplaneModeConditionCard(Context appContext) {
-        mAppContext = appContext;
-    }
-
-    @Override
-    public long getId() {
-        return AirplaneModeConditionController.ID;
-    }
-
-    @Override
-    public CharSequence getActionText() {
-        return mAppContext.getText(R.string.condition_turn_off);
-    }
-
-    @Override
-    public int getMetricsConstant() {
-        return MetricsProto.MetricsEvent.SETTINGS_CONDITION_AIRPLANE_MODE;
-    }
-
-    @Override
-    public Drawable getIcon() {
-        return mAppContext.getDrawable(R.drawable.ic_airplanemode_active);
-    }
-
-    @Override
-    public CharSequence getTitle() {
-        return mAppContext.getText(R.string.condition_airplane_title);
-    }
-
-    @Override
-    public CharSequence getSummary() {
-        return mAppContext.getText(R.string.condition_airplane_summary);
-    }
-}
diff --git a/src/com/android/settings/homepage/contextualcards/conditional/AirplaneModeConditionController.java b/src/com/android/settings/homepage/contextualcards/conditional/AirplaneModeConditionController.java
index 7599566..b6bb05a 100644
--- a/src/com/android/settings/homepage/contextualcards/conditional/AirplaneModeConditionController.java
+++ b/src/com/android/settings/homepage/contextualcards/conditional/AirplaneModeConditionController.java
@@ -23,6 +23,9 @@
 import android.net.ConnectivityManager;
 import android.provider.Settings;
 
+import com.android.internal.logging.nano.MetricsProto;
+import com.android.settings.R;
+import com.android.settings.homepage.contextualcards.ContextualCard;
 import com.android.settingslib.WirelessUtils;
 
 import java.util.Objects;
@@ -66,6 +69,20 @@
     }
 
     @Override
+    public ContextualCard buildContextualCard() {
+        return new ConditionalContextualCard.Builder()
+                .setConditionId(ID)
+                .setMetricsConstant(MetricsProto.MetricsEvent.SETTINGS_CONDITION_AIRPLANE_MODE)
+                .setActionText(mAppContext.getText(R.string.condition_turn_off))
+                .setName(mAppContext.getPackageName() + "/"
+                        + mAppContext.getText(R.string.condition_airplane_title))
+                .setTitleText(mAppContext.getText(R.string.condition_airplane_title).toString())
+                .setSummaryText(mAppContext.getText(R.string.condition_airplane_summary).toString())
+                .setIconDrawable(mAppContext.getDrawable(R.drawable.ic_airplanemode_active))
+                .build();
+    }
+
+    @Override
     public void startMonitoringStateChange() {
         mAppContext.registerReceiver(mReceiver, AIRPLANE_MODE_FILTER);
     }
diff --git a/src/com/android/settings/homepage/contextualcards/conditional/BackgroundDataConditionCard.java b/src/com/android/settings/homepage/contextualcards/conditional/BackgroundDataConditionCard.java
deleted file mode 100644
index e3de2d6..0000000
--- a/src/com/android/settings/homepage/contextualcards/conditional/BackgroundDataConditionCard.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2018 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.homepage.contextualcards.conditional;
-
-import android.content.Context;
-import android.graphics.drawable.Drawable;
-
-import com.android.internal.logging.nano.MetricsProto;
-import com.android.settings.R;
-
-public class BackgroundDataConditionCard implements ConditionalCard {
-
-    private final Context mAppContext;
-
-    public BackgroundDataConditionCard(Context appContext) {
-        mAppContext = appContext;
-    }
-
-    @Override
-    public long getId() {
-        return BackgroundDataConditionController.ID;
-    }
-
-    @Override
-    public CharSequence getActionText() {
-        return mAppContext.getText(R.string.condition_turn_off);
-    }
-
-    @Override
-    public int getMetricsConstant() {
-        return MetricsProto.MetricsEvent.SETTINGS_CONDITION_BACKGROUND_DATA;
-    }
-
-    @Override
-    public Drawable getIcon() {
-        return mAppContext.getDrawable(R.drawable.ic_data_saver);
-    }
-
-    @Override
-    public CharSequence getTitle() {
-        return mAppContext.getText(R.string.condition_bg_data_title);
-    }
-
-    @Override
-    public CharSequence getSummary() {
-        return mAppContext.getText(R.string.condition_bg_data_summary);
-    }
-}
diff --git a/src/com/android/settings/homepage/contextualcards/conditional/BackgroundDataConditionController.java b/src/com/android/settings/homepage/contextualcards/conditional/BackgroundDataConditionController.java
index fa40cf3..8b0ee42 100644
--- a/src/com/android/settings/homepage/contextualcards/conditional/BackgroundDataConditionController.java
+++ b/src/com/android/settings/homepage/contextualcards/conditional/BackgroundDataConditionController.java
@@ -20,7 +20,10 @@
 import android.content.Intent;
 import android.net.NetworkPolicyManager;
 
+import com.android.internal.logging.nano.MetricsProto;
+import com.android.settings.R;
 import com.android.settings.Settings;
+import com.android.settings.homepage.contextualcards.ContextualCard;
 
 import java.util.Objects;
 
@@ -60,6 +63,20 @@
     }
 
     @Override
+    public ContextualCard buildContextualCard() {
+        return new ConditionalContextualCard.Builder()
+                .setConditionId(ID)
+                .setMetricsConstant(MetricsProto.MetricsEvent.SETTINGS_CONDITION_BACKGROUND_DATA)
+                .setActionText(mAppContext.getText(R.string.condition_turn_off))
+                .setName(mAppContext.getPackageName() + "/"
+                        + mAppContext.getText(R.string.condition_bg_data_title))
+                .setTitleText(mAppContext.getText(R.string.condition_bg_data_title).toString())
+                .setSummaryText(mAppContext.getText(R.string.condition_bg_data_summary).toString())
+                .setIconDrawable(mAppContext.getDrawable(R.drawable.ic_data_saver))
+                .build();
+    }
+
+    @Override
     public void startMonitoringStateChange() {
 
     }
diff --git a/src/com/android/settings/homepage/contextualcards/conditional/BatterySaverConditionCard.java b/src/com/android/settings/homepage/contextualcards/conditional/BatterySaverConditionCard.java
deleted file mode 100644
index 4423592..0000000
--- a/src/com/android/settings/homepage/contextualcards/conditional/BatterySaverConditionCard.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2018 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.homepage.contextualcards.conditional;
-
-import android.content.Context;
-import android.graphics.drawable.Drawable;
-
-import com.android.internal.logging.nano.MetricsProto;
-import com.android.settings.R;
-
-public class BatterySaverConditionCard implements ConditionalCard {
-
-    private final Context mAppContext;
-
-    public BatterySaverConditionCard(Context appContext) {
-        mAppContext = appContext;
-    }
-
-    @Override
-    public long getId() {
-        return BatterySaverConditionController.ID;
-    }
-
-    @Override
-    public CharSequence getActionText() {
-        return mAppContext.getText(R.string.condition_turn_off);
-    }
-
-    @Override
-    public int getMetricsConstant() {
-        return MetricsProto.MetricsEvent.SETTINGS_CONDITION_BATTERY_SAVER;
-    }
-
-    @Override
-    public Drawable getIcon() {
-        return mAppContext.getDrawable(R.drawable.ic_battery_saver_accent_24dp);
-    }
-
-    @Override
-    public CharSequence getTitle() {
-        return mAppContext.getText(R.string.condition_battery_title);
-    }
-
-    @Override
-    public CharSequence getSummary() {
-        return mAppContext.getText(R.string.condition_battery_summary);
-    }
-}
diff --git a/src/com/android/settings/homepage/contextualcards/conditional/BatterySaverConditionController.java b/src/com/android/settings/homepage/contextualcards/conditional/BatterySaverConditionController.java
index 8887c7d..66901f3 100644
--- a/src/com/android/settings/homepage/contextualcards/conditional/BatterySaverConditionController.java
+++ b/src/com/android/settings/homepage/contextualcards/conditional/BatterySaverConditionController.java
@@ -24,6 +24,7 @@
 import com.android.settings.core.SubSettingLauncher;
 import com.android.settings.fuelgauge.BatterySaverReceiver;
 import com.android.settings.fuelgauge.batterysaver.BatterySaverSettings;
+import com.android.settings.homepage.contextualcards.ContextualCard;
 import com.android.settingslib.fuelgauge.BatterySaverUtils;
 
 import java.util.Objects;
@@ -71,6 +72,20 @@
     }
 
     @Override
+    public ContextualCard buildContextualCard() {
+        return new ConditionalContextualCard.Builder()
+                .setConditionId(ID)
+                .setMetricsConstant(MetricsProto.MetricsEvent.SETTINGS_CONDITION_BATTERY_SAVER)
+                .setActionText(mAppContext.getText(R.string.condition_turn_off))
+                .setName(mAppContext.getPackageName() + "/"
+                        + mAppContext.getText(R.string.condition_battery_title))
+                .setTitleText(mAppContext.getText(R.string.condition_battery_title).toString())
+                .setSummaryText(mAppContext.getText(R.string.condition_battery_summary).toString())
+                .setIconDrawable(mAppContext.getDrawable(R.drawable.ic_battery_saver_accent_24dp))
+                .build();
+    }
+
+    @Override
     public void startMonitoringStateChange() {
         mReceiver.setListening(true);
     }
diff --git a/src/com/android/settings/homepage/contextualcards/conditional/CellularDataConditionCard.java b/src/com/android/settings/homepage/contextualcards/conditional/CellularDataConditionCard.java
deleted file mode 100644
index e401de0..0000000
--- a/src/com/android/settings/homepage/contextualcards/conditional/CellularDataConditionCard.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2018 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.homepage.contextualcards.conditional;
-
-import android.content.Context;
-import android.graphics.drawable.Drawable;
-
-import com.android.internal.logging.nano.MetricsProto;
-import com.android.settings.R;
-
-public class CellularDataConditionCard implements ConditionalCard {
-
-    private final Context mAppContext;
-
-    public CellularDataConditionCard(Context appContext) {
-        mAppContext = appContext;
-    }
-
-    @Override
-    public long getId() {
-        return CellularDataConditionController.ID;
-    }
-
-    @Override
-    public CharSequence getActionText() {
-        return mAppContext.getText(R.string.condition_turn_on);
-    }
-
-    @Override
-    public int getMetricsConstant() {
-        return MetricsProto.MetricsEvent.SETTINGS_CONDITION_CELLULAR_DATA;
-    }
-
-    @Override
-    public Drawable getIcon() {
-        return mAppContext.getDrawable(R.drawable.ic_cellular_off);
-    }
-
-    @Override
-    public CharSequence getTitle() {
-        return mAppContext.getText(R.string.condition_cellular_title);
-    }
-
-    @Override
-    public CharSequence getSummary() {
-        return mAppContext.getText(R.string.condition_cellular_summary);
-    }
-}
diff --git a/src/com/android/settings/homepage/contextualcards/conditional/CellularDataConditionController.java b/src/com/android/settings/homepage/contextualcards/conditional/CellularDataConditionController.java
index 5709bf6..b2fbbcb 100644
--- a/src/com/android/settings/homepage/contextualcards/conditional/CellularDataConditionController.java
+++ b/src/com/android/settings/homepage/contextualcards/conditional/CellularDataConditionController.java
@@ -23,8 +23,11 @@
 import android.net.ConnectivityManager;
 import android.telephony.TelephonyManager;
 
+import com.android.internal.logging.nano.MetricsProto;
 import com.android.internal.telephony.TelephonyIntents;
+import com.android.settings.R;
 import com.android.settings.Settings;
+import com.android.settings.homepage.contextualcards.ContextualCard;
 
 import java.util.Objects;
 
@@ -76,6 +79,20 @@
     }
 
     @Override
+    public ContextualCard buildContextualCard() {
+        return new ConditionalContextualCard.Builder()
+                .setConditionId(ID)
+                .setMetricsConstant(MetricsProto.MetricsEvent.SETTINGS_CONDITION_CELLULAR_DATA)
+                .setActionText(mAppContext.getText(R.string.condition_turn_on))
+                .setName(mAppContext.getPackageName() + "/"
+                        + mAppContext.getText(R.string.condition_cellular_title))
+                .setTitleText(mAppContext.getText(R.string.condition_cellular_title).toString())
+                .setSummaryText(mAppContext.getText(R.string.condition_cellular_summary).toString())
+                .setIconDrawable(mAppContext.getDrawable(R.drawable.ic_cellular_off))
+                .build();
+    }
+
+    @Override
     public void startMonitoringStateChange() {
         mAppContext.registerReceiver(mReceiver, DATA_CONNECTION_FILTER);
     }
diff --git a/src/com/android/settings/homepage/contextualcards/conditional/ConditionContextualCardController.java b/src/com/android/settings/homepage/contextualcards/conditional/ConditionContextualCardController.java
index 1f1f757..eb65819 100644
--- a/src/com/android/settings/homepage/contextualcards/conditional/ConditionContextualCardController.java
+++ b/src/com/android/settings/homepage/contextualcards/conditional/ConditionContextualCardController.java
@@ -26,7 +26,6 @@
 import com.android.settingslib.core.lifecycle.events.OnStart;
 import com.android.settingslib.core.lifecycle.events.OnStop;
 
-import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 
@@ -84,24 +83,7 @@
 
     @Override
     public void onConditionsChanged() {
-        final List<ContextualCard> conditionCards = new ArrayList<>();
-        final List<ConditionalCard> conditionList = mConditionManager.getDisplayableCards();
-
-        for (ConditionalCard condition : conditionList) {
-            final ContextualCard conditionCard =
-                    new ConditionalContextualCard.Builder()
-                            .setConditionId(condition.getId())
-                            .setMetricsConstant(condition.getMetricsConstant())
-                            .setActionText(condition.getActionText())
-                            .setName(mContext.getPackageName() + "/"
-                                    + condition.getTitle().toString())
-                            .setTitleText(condition.getTitle().toString())
-                            .setSummaryText(condition.getSummary().toString())
-                            .setIconDrawable(condition.getIcon())
-                            .build();
-
-            conditionCards.add(conditionCard);
-        }
+        final List<ContextualCard> conditionCards = mConditionManager.getDisplayableCards();
 
         if (mListener != null) {
             final Map<Integer, List<ContextualCard>> conditionalCards = new ArrayMap<>();
diff --git a/src/com/android/settings/homepage/contextualcards/conditional/ConditionManager.java b/src/com/android/settings/homepage/contextualcards/conditional/ConditionManager.java
index d910b90..c741b98 100644
--- a/src/com/android/settings/homepage/contextualcards/conditional/ConditionManager.java
+++ b/src/com/android/settings/homepage/contextualcards/conditional/ConditionManager.java
@@ -22,6 +22,8 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.VisibleForTesting;
 
+import com.android.settings.homepage.contextualcards.ContextualCard;
+
 import java.util.ArrayList;
 import java.util.List;
 import java.util.concurrent.Callable;
@@ -36,8 +38,6 @@
     private static final String TAG = "ConditionManager";
 
     @VisibleForTesting
-    final List<ConditionalCard> mCandidates;
-    @VisibleForTesting
     final List<ConditionalCardController> mCardControllers;
 
     private static final long DISPLAYABLE_CHECKER_TIMEOUT_MS = 20;
@@ -51,29 +51,27 @@
     public ConditionManager(Context context, ConditionListener listener) {
         mAppContext = context.getApplicationContext();
         mExecutorService = Executors.newCachedThreadPool();
-        mCandidates = new ArrayList<>();
         mCardControllers = new ArrayList<>();
         mListener = listener;
         initCandidates();
     }
 
     /**
-     * Returns a list of {@link ConditionalCard}s eligible for display.
+     * Returns a list of {@link ContextualCard}s eligible for display.
      */
-    public List<ConditionalCard> getDisplayableCards() {
-        final List<ConditionalCard> cards = new ArrayList<>();
-        final List<Future<ConditionalCard>> displayableCards = new ArrayList<>();
+    public List<ContextualCard> getDisplayableCards() {
+        final List<ContextualCard> cards = new ArrayList<>();
+        final List<Future<ContextualCard>> displayableCards = new ArrayList<>();
         // Check displayable future
-        for (ConditionalCard card : mCandidates) {
-            final DisplayableChecker future = new DisplayableChecker(
-                    card, getController(card.getId()));
+        for (ConditionalCardController card : mCardControllers) {
+            final DisplayableChecker future = new DisplayableChecker(getController(card.getId()));
             displayableCards.add(mExecutorService.submit(future));
         }
         // Collect future and add displayable cards
-        for (Future<ConditionalCard> cardFuture : displayableCards) {
+        for (Future<ContextualCard> cardFuture : displayableCards) {
             try {
-                final ConditionalCard card = cardFuture.get(DISPLAYABLE_CHECKER_TIMEOUT_MS,
-                        TimeUnit.MILLISECONDS);
+                final ContextualCard card = cardFuture.get(
+                        DISPLAYABLE_CHECKER_TIMEOUT_MS, TimeUnit.MILLISECONDS);
                 if (card != null) {
                     cards.add(card);
                 }
@@ -142,7 +140,7 @@
     }
 
     @NonNull
-    <T extends ConditionalCardController> T getController(long id) {
+    private <T extends ConditionalCardController> T getController(long id) {
         for (ConditionalCardController controller : mCardControllers) {
             if (controller.getId() == id) {
                 return (T) controller;
@@ -164,36 +162,22 @@
         mCardControllers.add(new RingerVibrateConditionController(mAppContext, this /* manager */));
         mCardControllers.add(new RingerMutedConditionController(mAppContext, this /* manager */));
         mCardControllers.add(new WorkModeConditionController(mAppContext, this /* manager */));
-
-        // Initialize ui model later. UI model depends on controller.
-        mCandidates.add(new AirplaneModeConditionCard(mAppContext));
-        mCandidates.add(new BackgroundDataConditionCard(mAppContext));
-        mCandidates.add(new BatterySaverConditionCard(mAppContext));
-        mCandidates.add(new CellularDataConditionCard(mAppContext));
-        mCandidates.add(new DndConditionCard(mAppContext, this /* manager */));
-        mCandidates.add(new HotspotConditionCard(mAppContext, this /* manager */));
-        mCandidates.add(new NightDisplayConditionCard(mAppContext));
-        mCandidates.add(new RingerMutedConditionCard(mAppContext));
-        mCandidates.add(new RingerVibrateConditionCard(mAppContext));
-        mCandidates.add(new WorkModeConditionCard(mAppContext));
     }
 
     /**
      * Returns card if controller says it's displayable. Otherwise returns null.
      */
-    public static class DisplayableChecker implements Callable<ConditionalCard> {
+    public static class DisplayableChecker implements Callable<ContextualCard> {
 
-        private final ConditionalCard mCard;
         private final ConditionalCardController mController;
 
-        private DisplayableChecker(ConditionalCard card, ConditionalCardController controller) {
-            mCard = card;
+        private DisplayableChecker(ConditionalCardController controller) {
             mController = controller;
         }
 
         @Override
-        public ConditionalCard call() throws Exception {
-            return mController.isDisplayable() ? mCard : null;
+        public ContextualCard call() throws Exception {
+            return mController.isDisplayable() ? mController.buildContextualCard() : null;
         }
     }
 }
diff --git a/src/com/android/settings/homepage/contextualcards/conditional/ConditionalCard.java b/src/com/android/settings/homepage/contextualcards/conditional/ConditionalCard.java
deleted file mode 100644
index 4d80a73..0000000
--- a/src/com/android/settings/homepage/contextualcards/conditional/ConditionalCard.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2018 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.homepage.contextualcards.conditional;
-
-import android.graphics.drawable.Drawable;
-
-/**
- * UI Model for a conditional card displayed on homepage.
- */
-public interface ConditionalCard {
-
-    /**
-     * A stable ID for this card.
-     *
-     * @see {@link ConditionalCardController#getId()}
-     */
-    long getId();
-
-    /**
-     * The text display on the card for click action.
-     */
-    CharSequence getActionText();
-
-    /**
-     * Metrics constant used for logging user interaction.
-     */
-    int getMetricsConstant();
-
-    Drawable getIcon();
-
-    CharSequence getTitle();
-
-    CharSequence getSummary();
-}
diff --git a/src/com/android/settings/homepage/contextualcards/conditional/ConditionalCardController.java b/src/com/android/settings/homepage/contextualcards/conditional/ConditionalCardController.java
index 0447b11..bc68cce 100644
--- a/src/com/android/settings/homepage/contextualcards/conditional/ConditionalCardController.java
+++ b/src/com/android/settings/homepage/contextualcards/conditional/ConditionalCardController.java
@@ -18,15 +18,15 @@
 
 import android.content.Context;
 
+import com.android.settings.homepage.contextualcards.ContextualCard;
+
 /**
- * Data controller for a {@link ConditionalCard}.
+ * Data controller for a {@link ConditionalContextualCard}.
  */
 public interface ConditionalCardController {
 
     /**
      * A stable ID for this card.
-     *
-     * @see {@link ConditionalCard#getId()}
      */
     long getId();
 
@@ -45,6 +45,11 @@
      */
     void onActionClick();
 
+    /**
+     * Creates a UI model suitable for display, controlled by this controller.
+     */
+    ContextualCard buildContextualCard();
+
     void startMonitoringStateChange();
 
     void stopMonitoringStateChange();
diff --git a/src/com/android/settings/homepage/contextualcards/conditional/ConditionalContextualCard.java b/src/com/android/settings/homepage/contextualcards/conditional/ConditionalContextualCard.java
index 5537dd5..81219c3 100644
--- a/src/com/android/settings/homepage/contextualcards/conditional/ConditionalContextualCard.java
+++ b/src/com/android/settings/homepage/contextualcards/conditional/ConditionalContextualCard.java
@@ -22,7 +22,7 @@
  * Data class representing a conditional {@link ContextualCard}.
  *
  * Use this class to store additional attributes on top of {@link ContextualCard} for
- * {@link ConditionalCard}.
+ * {@link ConditionalCardController}.
  */
 public class ConditionalContextualCard extends ContextualCard {
 
diff --git a/src/com/android/settings/homepage/contextualcards/conditional/DndConditionCard.java b/src/com/android/settings/homepage/contextualcards/conditional/DndConditionCard.java
deleted file mode 100644
index c4adaa4..0000000
--- a/src/com/android/settings/homepage/contextualcards/conditional/DndConditionCard.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2018 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.homepage.contextualcards.conditional;
-
-import android.content.Context;
-import android.graphics.drawable.Drawable;
-
-import com.android.internal.logging.nano.MetricsProto;
-import com.android.settings.R;
-
-public class DndConditionCard implements ConditionalCard {
-
-    private final Context mAppContext;
-    private final DndConditionCardController mController;
-
-    public DndConditionCard(Context appContext, ConditionManager manager) {
-        mAppContext = appContext;
-        mController = manager.getController(getId());
-    }
-
-    @Override
-    public long getId() {
-        return DndConditionCardController.ID;
-    }
-
-    @Override
-    public Drawable getIcon() {
-        return mAppContext.getDrawable(R.drawable.ic_do_not_disturb_on_24dp);
-    }
-
-    @Override
-    public CharSequence getTitle() {
-        return mAppContext.getText(R.string.condition_zen_title);
-    }
-
-    @Override
-    public CharSequence getSummary() {
-        return mController.getSummary();
-    }
-
-    @Override
-    public CharSequence getActionText() {
-        return mAppContext.getText(R.string.condition_turn_off);
-    }
-
-    @Override
-    public int getMetricsConstant() {
-        return MetricsProto.MetricsEvent.SETTINGS_CONDITION_DND;
-    }
-}
diff --git a/src/com/android/settings/homepage/contextualcards/conditional/DndConditionCardController.java b/src/com/android/settings/homepage/contextualcards/conditional/DndConditionCardController.java
index 2903428..21cb6c0 100644
--- a/src/com/android/settings/homepage/contextualcards/conditional/DndConditionCardController.java
+++ b/src/com/android/settings/homepage/contextualcards/conditional/DndConditionCardController.java
@@ -29,6 +29,7 @@
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.settings.R;
 import com.android.settings.core.SubSettingLauncher;
+import com.android.settings.homepage.contextualcards.ContextualCard;
 import com.android.settings.notification.ZenModeSettings;
 
 import java.util.Objects;
@@ -88,6 +89,20 @@
         mNotificationManager.setZenMode(Settings.Global.ZEN_MODE_OFF, null, TAG);
     }
 
+    @Override
+    public ContextualCard buildContextualCard() {
+        return new ConditionalContextualCard.Builder()
+                .setConditionId(ID)
+                .setMetricsConstant(MetricsProto.MetricsEvent.SETTINGS_CONDITION_DND)
+                .setActionText(mAppContext.getText(R.string.condition_turn_off))
+                .setName(mAppContext.getPackageName() + "/"
+                        + mAppContext.getText(R.string.condition_zen_title))
+                .setTitleText(mAppContext.getText(R.string.condition_zen_title).toString())
+                .setSummaryText(getSummary().toString())
+                .setIconDrawable(mAppContext.getDrawable(R.drawable.ic_do_not_disturb_on_24dp))
+                .build();
+    }
+
     public CharSequence getSummary() {
         final int zen = mNotificationManager.getZenMode();
         final ZenModeConfig config;
diff --git a/src/com/android/settings/homepage/contextualcards/conditional/HotspotConditionCard.java b/src/com/android/settings/homepage/contextualcards/conditional/HotspotConditionCard.java
deleted file mode 100644
index 35c9251..0000000
--- a/src/com/android/settings/homepage/contextualcards/conditional/HotspotConditionCard.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2018 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.homepage.contextualcards.conditional;
-
-import android.content.Context;
-import android.graphics.drawable.Drawable;
-import android.os.UserHandle;
-import android.os.UserManager;
-
-import com.android.internal.logging.nano.MetricsProto;
-import com.android.settings.R;
-import com.android.settingslib.RestrictedLockUtilsInternal;
-
-public class HotspotConditionCard implements ConditionalCard {
-
-    private final Context mAppContext;
-    private final ConditionManager mConditionManager;
-
-    public HotspotConditionCard(Context appContext, ConditionManager manager) {
-        mAppContext = appContext;
-        mConditionManager = manager;
-    }
-
-    @Override
-    public long getId() {
-        return HotspotConditionController.ID;
-    }
-
-    @Override
-    public CharSequence getActionText() {
-        if (RestrictedLockUtilsInternal.hasBaseUserRestriction(mAppContext,
-                UserManager.DISALLOW_CONFIG_TETHERING, UserHandle.myUserId())) {
-            return null;
-        }
-        return mAppContext.getText(R.string.condition_turn_off);
-    }
-
-    @Override
-    public int getMetricsConstant() {
-        return MetricsProto.MetricsEvent.SETTINGS_CONDITION_HOTSPOT;
-    }
-
-    @Override
-    public Drawable getIcon() {
-        return mAppContext.getDrawable(R.drawable.ic_hotspot);
-    }
-
-    @Override
-    public CharSequence getTitle() {
-        return mAppContext.getText(R.string.condition_hotspot_title);
-    }
-
-    @Override
-    public CharSequence getSummary() {
-        final HotspotConditionController controller = mConditionManager.getController(getId());
-        return controller.getSummary();
-    }
-}
diff --git a/src/com/android/settings/homepage/contextualcards/conditional/HotspotConditionController.java b/src/com/android/settings/homepage/contextualcards/conditional/HotspotConditionController.java
index 1a6aa0c..eec7e4a 100644
--- a/src/com/android/settings/homepage/contextualcards/conditional/HotspotConditionController.java
+++ b/src/com/android/settings/homepage/contextualcards/conditional/HotspotConditionController.java
@@ -30,6 +30,7 @@
 import com.android.settings.R;
 import com.android.settings.TetherSettings;
 import com.android.settings.core.SubSettingLauncher;
+import com.android.settings.homepage.contextualcards.ContextualCard;
 import com.android.settingslib.RestrictedLockUtils;
 import com.android.settingslib.RestrictedLockUtilsInternal;
 
@@ -88,6 +89,20 @@
     }
 
     @Override
+    public ContextualCard buildContextualCard() {
+        return new ConditionalContextualCard.Builder()
+                .setConditionId(ID)
+                .setMetricsConstant(MetricsProto.MetricsEvent.SETTINGS_CONDITION_HOTSPOT)
+                .setActionText(mAppContext.getText(R.string.condition_turn_off))
+                .setName(mAppContext.getPackageName() + "/"
+                        + mAppContext.getText(R.string.condition_hotspot_title))
+                .setTitleText(mAppContext.getText(R.string.condition_hotspot_title).toString())
+                .setSummaryText(getSummary().toString())
+                .setIconDrawable(mAppContext.getDrawable(R.drawable.ic_hotspot))
+                .build();
+    }
+
+    @Override
     public void startMonitoringStateChange() {
         mAppContext.registerReceiver(mReceiver, WIFI_AP_STATE_FILTER);
     }
diff --git a/src/com/android/settings/homepage/contextualcards/conditional/NightDisplayConditionCard.java b/src/com/android/settings/homepage/contextualcards/conditional/NightDisplayConditionCard.java
deleted file mode 100644
index eadb6b2..0000000
--- a/src/com/android/settings/homepage/contextualcards/conditional/NightDisplayConditionCard.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2018 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.homepage.contextualcards.conditional;
-
-import android.content.Context;
-import android.graphics.drawable.Drawable;
-
-import com.android.internal.logging.nano.MetricsProto;
-import com.android.settings.R;
-
-public class NightDisplayConditionCard implements ConditionalCard {
-
-    private final Context mAppContext;
-
-    public NightDisplayConditionCard(Context appContext) {
-        mAppContext = appContext;
-    }
-
-    @Override
-    public long getId() {
-        return NightDisplayConditionController.ID;
-    }
-
-    @Override
-    public CharSequence getActionText() {
-        return mAppContext.getText(R.string.condition_turn_off);
-    }
-
-    @Override
-    public int getMetricsConstant() {
-        return MetricsProto.MetricsEvent.SETTINGS_CONDITION_NIGHT_DISPLAY;
-    }
-
-    @Override
-    public Drawable getIcon() {
-        return mAppContext.getDrawable(R.drawable.ic_settings_night_display);
-    }
-
-    @Override
-    public CharSequence getTitle() {
-        return mAppContext.getText(R.string.condition_night_display_title);
-    }
-
-    @Override
-    public CharSequence getSummary() {
-        return mAppContext.getText(R.string.condition_night_display_summary);
-    }
-}
diff --git a/src/com/android/settings/homepage/contextualcards/conditional/NightDisplayConditionController.java b/src/com/android/settings/homepage/contextualcards/conditional/NightDisplayConditionController.java
index 6b00565..d8d5f79 100644
--- a/src/com/android/settings/homepage/contextualcards/conditional/NightDisplayConditionController.java
+++ b/src/com/android/settings/homepage/contextualcards/conditional/NightDisplayConditionController.java
@@ -23,6 +23,7 @@
 import com.android.settings.R;
 import com.android.settings.core.SubSettingLauncher;
 import com.android.settings.display.NightDisplaySettings;
+import com.android.settings.homepage.contextualcards.ContextualCard;
 
 import java.util.Objects;
 
@@ -30,11 +31,13 @@
         ColorDisplayController.Callback {
     static final int ID = Objects.hash("NightDisplayConditionController");
 
+    private final Context mAppContext;
     private final ConditionManager mConditionManager;
     private final ColorDisplayController mController;
 
     public NightDisplayConditionController(Context appContext, ConditionManager manager) {
         mController = new ColorDisplayController(appContext);
+        mAppContext = appContext;
         mConditionManager = manager;
     }
 
@@ -63,6 +66,22 @@
     }
 
     @Override
+    public ContextualCard buildContextualCard() {
+        return new ConditionalContextualCard.Builder()
+                .setConditionId(ID)
+                .setMetricsConstant(MetricsProto.MetricsEvent.SETTINGS_CONDITION_NIGHT_DISPLAY)
+                .setActionText(mAppContext.getText(R.string.condition_turn_off))
+                .setName(mAppContext.getPackageName() + "/"
+                        + mAppContext.getText(R.string.condition_night_display_title))
+                .setTitleText(mAppContext.getText(
+                        R.string.condition_night_display_title).toString())
+                .setSummaryText(
+                        mAppContext.getText(R.string.condition_night_display_summary).toString())
+                .setIconDrawable(mAppContext.getDrawable(R.drawable.ic_settings_night_display))
+                .build();
+    }
+
+    @Override
     public void startMonitoringStateChange() {
         mController.setListener(this);
     }
diff --git a/src/com/android/settings/homepage/contextualcards/conditional/RingerMutedConditionCard.java b/src/com/android/settings/homepage/contextualcards/conditional/RingerMutedConditionCard.java
deleted file mode 100644
index d7009f6..0000000
--- a/src/com/android/settings/homepage/contextualcards/conditional/RingerMutedConditionCard.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2018 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.homepage.contextualcards.conditional;
-
-import android.content.Context;
-import android.graphics.drawable.Drawable;
-
-import com.android.internal.logging.nano.MetricsProto;
-import com.android.settings.R;
-
-public class RingerMutedConditionCard implements ConditionalCard {
-
-    private final Context mAppContext;
-
-    public RingerMutedConditionCard(Context appContext) {
-        mAppContext = appContext;
-    }
-
-    @Override
-    public long getId() {
-        return RingerMutedConditionController.ID;
-    }
-
-    @Override
-    public CharSequence getActionText() {
-        return mAppContext.getText(R.string.condition_device_muted_action_turn_on_sound);
-    }
-
-    @Override
-    public int getMetricsConstant() {
-        return MetricsProto.MetricsEvent.SETTINGS_CONDITION_DEVICE_MUTED;
-    }
-
-    @Override
-    public Drawable getIcon() {
-        return mAppContext.getDrawable(R.drawable.ic_notifications_off_24dp);
-    }
-
-    @Override
-    public CharSequence getTitle() {
-        return mAppContext.getText(R.string.condition_device_muted_title);
-    }
-
-    @Override
-    public CharSequence getSummary() {
-        return mAppContext.getText(R.string.condition_device_muted_summary);
-    }
-}
diff --git a/src/com/android/settings/homepage/contextualcards/conditional/RingerMutedConditionController.java b/src/com/android/settings/homepage/contextualcards/conditional/RingerMutedConditionController.java
index cbab1bb..75a72fd 100644
--- a/src/com/android/settings/homepage/contextualcards/conditional/RingerMutedConditionController.java
+++ b/src/com/android/settings/homepage/contextualcards/conditional/RingerMutedConditionController.java
@@ -23,15 +23,21 @@
 import android.media.AudioManager;
 import android.provider.Settings;
 
+import com.android.internal.logging.nano.MetricsProto;
+import com.android.settings.R;
+import com.android.settings.homepage.contextualcards.ContextualCard;
+
 import java.util.Objects;
 
 public class RingerMutedConditionController extends AbnormalRingerConditionController {
     static final int ID = Objects.hash("RingerMutedConditionController");
 
     private final NotificationManager mNotificationManager;
+    private final Context mAppContext;
 
     public RingerMutedConditionController(Context appContext, ConditionManager conditionManager) {
         super(appContext, conditionManager);
+        mAppContext = appContext;
         mNotificationManager =
                 (NotificationManager) appContext.getSystemService(NOTIFICATION_SERVICE);
     }
@@ -52,4 +58,20 @@
                 mAudioManager.getRingerModeInternal() == AudioManager.RINGER_MODE_SILENT;
         return isSilent && !zenModeEnabled;
     }
+
+    @Override
+    public ContextualCard buildContextualCard() {
+        return new ConditionalContextualCard.Builder()
+                .setConditionId(ID)
+                .setMetricsConstant(MetricsProto.MetricsEvent.SETTINGS_CONDITION_DEVICE_MUTED)
+                .setActionText(
+                        mAppContext.getText(R.string.condition_device_muted_action_turn_on_sound))
+                .setName(mAppContext.getPackageName() + "/"
+                        + mAppContext.getText(R.string.condition_device_muted_title))
+                .setTitleText(mAppContext.getText(R.string.condition_device_muted_title).toString())
+                .setSummaryText(
+                        mAppContext.getText(R.string.condition_device_muted_summary).toString())
+                .setIconDrawable(mAppContext.getDrawable(R.drawable.ic_notifications_off_24dp))
+                .build();
+    }
 }
diff --git a/src/com/android/settings/homepage/contextualcards/conditional/RingerVibrateConditionCard.java b/src/com/android/settings/homepage/contextualcards/conditional/RingerVibrateConditionCard.java
deleted file mode 100644
index 38e3d88..0000000
--- a/src/com/android/settings/homepage/contextualcards/conditional/RingerVibrateConditionCard.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2018 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.homepage.contextualcards.conditional;
-
-import android.content.Context;
-import android.graphics.drawable.Drawable;
-
-import com.android.internal.logging.nano.MetricsProto;
-import com.android.settings.R;
-
-public class RingerVibrateConditionCard implements ConditionalCard {
-
-    private final Context mAppContext;
-
-    public RingerVibrateConditionCard(Context appContext) {
-        mAppContext = appContext;
-    }
-
-    @Override
-    public long getId() {
-        return RingerVibrateConditionController.ID;
-    }
-
-    @Override
-    public CharSequence getActionText() {
-        return mAppContext.getText(R.string.condition_device_muted_action_turn_on_sound);
-    }
-
-    @Override
-    public int getMetricsConstant() {
-        return MetricsProto.MetricsEvent.SETTINGS_CONDITION_DEVICE_VIBRATE;
-    }
-
-    @Override
-    public Drawable getIcon() {
-        return mAppContext.getDrawable(R.drawable.ic_volume_ringer_vibrate);
-    }
-
-    @Override
-    public CharSequence getTitle() {
-        return mAppContext.getText(R.string.condition_device_vibrate_title);
-    }
-
-    @Override
-    public CharSequence getSummary() {
-        return mAppContext.getText(R.string.condition_device_vibrate_summary);
-    }
-}
diff --git a/src/com/android/settings/homepage/contextualcards/conditional/RingerVibrateConditionController.java b/src/com/android/settings/homepage/contextualcards/conditional/RingerVibrateConditionController.java
index e230e8c..4c355a3 100644
--- a/src/com/android/settings/homepage/contextualcards/conditional/RingerVibrateConditionController.java
+++ b/src/com/android/settings/homepage/contextualcards/conditional/RingerVibrateConditionController.java
@@ -19,13 +19,20 @@
 import android.content.Context;
 import android.media.AudioManager;
 
+import com.android.internal.logging.nano.MetricsProto;
+import com.android.settings.R;
+import com.android.settings.homepage.contextualcards.ContextualCard;
+
 import java.util.Objects;
 
 public class RingerVibrateConditionController extends AbnormalRingerConditionController {
     static final int ID = Objects.hash("RingerVibrateConditionController");
 
+    private final Context mAppContext;
+
     public RingerVibrateConditionController(Context appContext, ConditionManager conditionManager) {
         super(appContext, conditionManager);
+        mAppContext = appContext;
 
     }
 
@@ -38,4 +45,21 @@
     public boolean isDisplayable() {
         return mAudioManager.getRingerModeInternal() == AudioManager.RINGER_MODE_VIBRATE;
     }
+
+    @Override
+    public ContextualCard buildContextualCard() {
+        return new ConditionalContextualCard.Builder()
+                .setConditionId(ID)
+                .setMetricsConstant(MetricsProto.MetricsEvent.SETTINGS_CONDITION_DEVICE_VIBRATE)
+                .setActionText(
+                        mAppContext.getText(R.string.condition_device_muted_action_turn_on_sound))
+                .setName(mAppContext.getPackageName() + "/"
+                        + mAppContext.getText(R.string.condition_device_vibrate_title))
+                .setTitleText(
+                        mAppContext.getText(R.string.condition_device_vibrate_title).toString())
+                .setSummaryText(
+                        mAppContext.getText(R.string.condition_device_vibrate_summary).toString())
+                .setIconDrawable(mAppContext.getDrawable(R.drawable.ic_volume_ringer_vibrate))
+                .build();
+    }
 }
diff --git a/src/com/android/settings/homepage/contextualcards/conditional/WorkModeConditionCard.java b/src/com/android/settings/homepage/contextualcards/conditional/WorkModeConditionCard.java
deleted file mode 100644
index 86313ad..0000000
--- a/src/com/android/settings/homepage/contextualcards/conditional/WorkModeConditionCard.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2018 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.homepage.contextualcards.conditional;
-
-import android.content.Context;
-import android.graphics.drawable.Drawable;
-
-import com.android.internal.logging.nano.MetricsProto;
-import com.android.settings.R;
-
-public class WorkModeConditionCard implements ConditionalCard {
-
-    private final Context mAppContext;
-
-    public WorkModeConditionCard(Context appContext) {
-        mAppContext = appContext;
-    }
-
-    @Override
-    public long getId() {
-        return WorkModeConditionController.ID;
-    }
-
-    @Override
-    public CharSequence getActionText() {
-        return mAppContext.getText(R.string.condition_turn_on);
-    }
-
-    @Override
-    public int getMetricsConstant() {
-        return MetricsProto.MetricsEvent.SETTINGS_CONDITION_WORK_MODE;
-    }
-
-    @Override
-    public Drawable getIcon() {
-        return mAppContext.getDrawable(R.drawable.ic_signal_workmode_enable);
-    }
-
-    @Override
-    public CharSequence getTitle() {
-        return mAppContext.getText(R.string.condition_work_title);
-    }
-
-    @Override
-    public CharSequence getSummary() {
-        return mAppContext.getText(R.string.condition_work_summary);
-    }
-
-}
diff --git a/src/com/android/settings/homepage/contextualcards/conditional/WorkModeConditionController.java b/src/com/android/settings/homepage/contextualcards/conditional/WorkModeConditionController.java
index 9cdac03..c508403f 100644
--- a/src/com/android/settings/homepage/contextualcards/conditional/WorkModeConditionController.java
+++ b/src/com/android/settings/homepage/contextualcards/conditional/WorkModeConditionController.java
@@ -25,7 +25,10 @@
 import android.os.UserManager;
 import android.text.TextUtils;
 
+import com.android.internal.logging.nano.MetricsProto;
+import com.android.settings.R;
 import com.android.settings.Settings;
+import com.android.settings.homepage.contextualcards.ContextualCard;
 
 import java.util.List;
 import java.util.Objects;
@@ -80,6 +83,20 @@
     }
 
     @Override
+    public ContextualCard buildContextualCard() {
+        return new ConditionalContextualCard.Builder()
+                .setConditionId(ID)
+                .setMetricsConstant(MetricsProto.MetricsEvent.SETTINGS_CONDITION_WORK_MODE)
+                .setActionText(mAppContext.getText(R.string.condition_turn_on))
+                .setName(mAppContext.getPackageName() + "/"
+                        + mAppContext.getText(R.string.condition_work_title))
+                .setTitleText(mAppContext.getText(R.string.condition_work_title).toString())
+                .setSummaryText(mAppContext.getText(R.string.condition_work_summary).toString())
+                .setIconDrawable(mAppContext.getDrawable(R.drawable.ic_signal_workmode_enable))
+                .build();
+    }
+
+    @Override
     public void startMonitoringStateChange() {
         mAppContext.registerReceiver(mReceiver, FILTER);
     }
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/AbnormalRingerConditionControllerBaseTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/AbnormalRingerConditionControllerBaseTest.java
index 91071db..d27e024 100644
--- a/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/AbnormalRingerConditionControllerBaseTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/AbnormalRingerConditionControllerBaseTest.java
@@ -23,6 +23,7 @@
 import android.content.Intent;
 import android.media.AudioManager;
 
+import com.android.settings.homepage.contextualcards.ContextualCard;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 
 import org.junit.Before;
@@ -79,5 +80,10 @@
         public boolean isDisplayable() {
             return false;
         }
+
+        @Override
+        public ContextualCard buildContextualCard() {
+            return new ConditionalContextualCard.Builder().build();
+        }
     }
 }
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/ConditionContextualCardControllerTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/ConditionContextualCardControllerTest.java
index 2befb21..ab82a54 100644
--- a/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/ConditionContextualCardControllerTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/ConditionContextualCardControllerTest.java
@@ -23,9 +23,8 @@
 import static org.mockito.Mockito.when;
 
 import android.content.Context;
-import android.graphics.drawable.Drawable;
 
-import com.android.settings.R;
+import com.android.settings.homepage.contextualcards.ContextualCard;
 import com.android.settings.homepage.contextualcards.ContextualCardUpdateListener;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 
@@ -74,8 +73,8 @@
 
     @Test
     public void onConditionsChanged_listenerIsSet_shouldUpdateData() {
-        final FakeConditionalCard fakeConditionalCard = new FakeConditionalCard(mContext);
-        final List<ConditionalCard> conditionalCards = new ArrayList<>();
+        final ContextualCard fakeConditionalCard = new ConditionalContextualCard.Builder().build();
+        final List<ContextualCard> conditionalCards = new ArrayList<>();
         conditionalCards.add(fakeConditionalCard);
         when(mConditionManager.getDisplayableCards()).thenReturn(conditionalCards);
         mController.setCardUpdateListener(mListener);
@@ -87,8 +86,8 @@
 
     @Test
     public void onConditionsChanged_listenerNotSet_shouldNotUpdateData() {
-        final FakeConditionalCard fakeConditionalCard = new FakeConditionalCard(mContext);
-        final List<ConditionalCard> conditionalCards = new ArrayList<>();
+        final ContextualCard fakeConditionalCard = new ConditionalContextualCard.Builder().build();
+        final List<ContextualCard> conditionalCards = new ArrayList<>();
         conditionalCards.add(fakeConditionalCard);
         when(mConditionManager.getDisplayableCards()).thenReturn(conditionalCards);
 
@@ -96,43 +95,4 @@
 
         verify(mListener, never()).onContextualCardUpdated(any());
     }
-
-    private class FakeConditionalCard implements ConditionalCard {
-
-        private final Context mContext;
-
-        public FakeConditionalCard(Context context) {
-            mContext = context;
-        }
-
-        @Override
-        public long getId() {
-            return 100;
-        }
-
-        @Override
-        public CharSequence getActionText() {
-            return "action_text_test";
-        }
-
-        @Override
-        public int getMetricsConstant() {
-            return 1;
-        }
-
-        @Override
-        public Drawable getIcon() {
-            return mContext.getDrawable(R.drawable.ic_do_not_disturb_on_24dp);
-        }
-
-        @Override
-        public CharSequence getTitle() {
-            return "title_text_test";
-        }
-
-        @Override
-        public CharSequence getSummary() {
-            return "summary_text_test";
-        }
-    }
 }
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/ConditionManagerTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/ConditionManagerTest.java
index 82c6381..e8d5caa 100644
--- a/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/ConditionManagerTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/ConditionManagerTest.java
@@ -41,8 +41,6 @@
     private static final long ID = 123L;
 
     @Mock
-    private ConditionalCard mCard;
-    @Mock
     private ConditionalCardController mController;
     @Mock
     private ConditionListener mConditionListener;
@@ -57,14 +55,11 @@
         mContext = RuntimeEnvironment.application;
         mManager = spy(new ConditionManager(mContext, mConditionListener));
 
-        assertThat(mManager.mCandidates.size()).isEqualTo(mManager.mCardControllers.size());
-
         when(mController.getId()).thenReturn(ID);
-        when(mCard.getId()).thenReturn(ID);
-
-        mManager.mCandidates.clear();
+        when(mController.buildContextualCard()).thenReturn(
+                new ConditionalContextualCard.Builder()
+                        .build());
         mManager.mCardControllers.clear();
-        mManager.mCandidates.add(mCard);
         mManager.mCardControllers.add(mController);
     }
 
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/DndConditionalCardTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/DndConditionalCardTest.java
deleted file mode 100644
index 506d3bf..0000000
--- a/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/DndConditionalCardTest.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2018 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.homepage.contextualcards.conditional;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.anyLong;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RuntimeEnvironment;
-
-@RunWith(SettingsRobolectricTestRunner.class)
-public class DndConditionalCardTest {
-
-    @Mock
-    private ConditionManager mManager;
-    private DndConditionCardController mController;
-
-    private Context mContext;
-    private DndConditionCard mCard;
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-        mContext = spy(RuntimeEnvironment.application);
-
-        mController = new DndConditionCardController(mContext, mManager);
-        when(mManager.getController(anyLong())).thenReturn(mController);
-
-        mCard = new DndConditionCard(mContext, mManager);
-    }
-
-    @Test
-    public void getId_sameAsController() {
-        assertThat(mCard.getId()).isEqualTo(mController.getId());
-    }
-
-}
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/RingerVibrateConditionCardTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/RingerVibrateConditionCardTest.java
deleted file mode 100644
index 0ade54d..0000000
--- a/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/RingerVibrateConditionCardTest.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2018 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.homepage.contextualcards.conditional;
-
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.content.Context;
-
-import com.android.settings.R;
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RuntimeEnvironment;
-
-@RunWith(SettingsRobolectricTestRunner.class)
-public class RingerVibrateConditionCardTest {
-
-    private Context mContext;
-    private RingerVibrateConditionCard mCard;
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-        mContext = RuntimeEnvironment.application;
-        mCard = new RingerVibrateConditionCard(mContext);
-    }
-
-    @Test
-    public void verifyText() {
-        assertThat(mCard.getTitle()).isEqualTo(
-                mContext.getText(R.string.condition_device_vibrate_title));
-        assertThat(mCard.getSummary()).isEqualTo(
-                mContext.getText(R.string.condition_device_vibrate_summary));
-        assertThat(mCard.getActionText()).isEqualTo(
-                mContext.getText(R.string.condition_device_muted_action_turn_on_sound));
-    }
-}