Merge "Fix a grammar issue in string"
diff --git a/res/layout/data_usage_spinner_item.xml b/res/layout/data_usage_spinner_item.xml
new file mode 100644
index 0000000..1706edf
--- /dev/null
+++ b/res/layout/data_usage_spinner_item.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 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.
+-->
+
+<!-- Copied from frameworks/base/core/res/res/layout/simple_spinner_item.xml and modified
+     layout height and added padding. -->
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+          android:id="@android:id/text1"
+          style="?android:attr/spinnerItemStyle"
+          android:singleLine="true"
+          android:layout_width="match_parent"
+          android:layout_height="?android:attr/listPreferredItemHeightSmall"
+          android:ellipsize="marquee"
+          android:textAlignment="inherit"
+          android:gravity="center"
+          android:paddingStart="30dp"
+          android:paddingEnd="30dp"/>
\ No newline at end of file
diff --git a/res/layout/suggestion_tile.xml b/res/layout/suggestion_tile.xml
index e2dd13a..2adfab3 100644
--- a/res/layout/suggestion_tile.xml
+++ b/res/layout/suggestion_tile.xml
@@ -33,26 +33,27 @@
             android:layout_width="@dimen/dashboard_tile_image_size"
             android:layout_height="@dimen/dashboard_tile_image_size"
             android:layout_marginStart="14dp"
-            android:layout_marginEnd="24dp"/>
+            android:layout_marginEnd="24dp" />
 
         <LinearLayout
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:orientation="vertical">
 
-            <TextView android:id="@android:id/title"
+            <TextView
+                android:id="@android:id/title"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:singleLine="true"
                 android:textAppearance="@style/TextAppearance.TileTitle"
                 android:ellipsize="marquee"
-                android:fadingEdge="horizontal"/>
+                android:fadingEdge="horizontal" />
 
-            <TextView android:id="@android:id/summary"
+            <TextView
+                android:id="@android:id/summary"
+                android:textAppearance="@style/TextAppearance.SuggestionSummary"
                 android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:textAppearance="@style/TextAppearance.Small"
-                android:textColor="?android:attr/textColorSecondary"/>
+                android:layout_height="wrap_content" />
 
         </LinearLayout>
 
diff --git a/res/layout/suggestion_tile_with_button.xml b/res/layout/suggestion_tile_with_button.xml
new file mode 100644
index 0000000..0439770
--- /dev/null
+++ b/res/layout/suggestion_tile_with_button.xml
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 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.
+-->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:background="@android:color/white"
+    android:clipChildren="false"
+    android:clipToPadding="false"
+    android:paddingStart="16dp"
+    android:paddingEnd="12dp"
+    android:paddingBottom="20dp"
+    android:paddingTop="16dp"
+    android:orientation="horizontal"
+    android:minHeight="@dimen/dashboard_tile_minimum_height">
+
+    <ImageView
+        android:id="@android:id/icon"
+        android:layout_width="@dimen/dashboard_tile_image_size"
+        android:layout_height="@dimen/dashboard_tile_image_size"
+        android:contentDescription="@null" />
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_gravity="start"
+        android:layout_marginStart="18dp"
+        android:layout_marginTop="2dp"
+        android:clipChildren="false"
+        android:clipToPadding="false"
+        android:orientation="vertical">
+
+        <TextView
+            style="@style/TextAppearance.SuggestionTitle"
+            android:id="@android:id/title"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="6dp" />
+
+        <TextView
+            android:id="@android:id/summary"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="12dp"
+            android:layout_marginStart="6dp"
+            android:layout_marginEnd="50dp"
+            android:textAppearance="@style/TextAppearance.SuggestionSummary" />
+
+        <Button
+            android:id="@android:id/primary"
+            style="@style/SuwGlifButton.Primary"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="12dp"
+            android:text="@string/suggestion_button_text" />
+    </LinearLayout>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 6869fdc..567f255 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -7321,6 +7321,8 @@
          settings button -->
     <string name="notification_app_settings_button">Notification settings</string>
 
+    <!-- Generic label for suggestion card's ok button [CHAR LIMIT=20] -->
+    <string name="suggestion_button_text">Ok</string>
 
     <!-- [CHAR LIMIT=35] Feedback on the device -->
     <string name="device_feedback">Send feedback about this device</string>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index fe92e6d..c9ef22c 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -318,7 +318,10 @@
     <style name="TextAppearance.SuggestionTitle"
            parent="@android:style/TextAppearance.Material.Subhead">
         <item name="android:fontFamily">sans-serif-medium</item>
-        <item name="android:textSize">14sp</item>
+    </style>
+
+    <style name="TextAppearance.SuggestionSummary" parent="TextAppearance.Small">
+        <item name="android:textColor">?android:attr/textColorSecondary</item>
     </style>
 
     <style name="TextAppearance.FingerprintErrorText"
diff --git a/src/com/android/settings/dashboard/DashboardAdapter.java b/src/com/android/settings/dashboard/DashboardAdapter.java
index 9c61873..d4397dc 100644
--- a/src/com/android/settings/dashboard/DashboardAdapter.java
+++ b/src/com/android/settings/dashboard/DashboardAdapter.java
@@ -31,7 +31,6 @@
 import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.Log;
-import android.util.Pair;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
@@ -47,11 +46,9 @@
 import com.android.settings.dashboard.conditional.Condition;
 import com.android.settings.dashboard.conditional.ConditionAdapter;
 import com.android.settings.dashboard.suggestions.SuggestionAdapter;
-import com.android.settings.dashboard.suggestions.SuggestionController;
 import com.android.settings.dashboard.suggestions.SuggestionControllerMixin;
 import com.android.settings.dashboard.suggestions.SuggestionDismissController;
 import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider;
-import com.android.settings.dashboard.suggestions.SuggestionLogHelper;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settingslib.Utils;
 import com.android.settingslib.drawer.DashboardCategory;
@@ -164,24 +161,6 @@
                 .setCategory(category)
                 .build();
         notifyDashboardDataChanged(prevData);
-        List<Tile> shownSuggestions = null;
-        final int mode = mDashboardData.getSuggestionConditionMode();
-        if (mode == DashboardData.HEADER_MODE_DEFAULT) {
-            shownSuggestions = suggestions.subList(0,
-                    Math.min(suggestions.size(), DashboardData.DEFAULT_SUGGESTION_COUNT));
-        } else if (mode != DashboardData.HEADER_MODE_COLLAPSED) {
-            shownSuggestions = suggestions;
-        }
-        if (shownSuggestions != null) {
-            for (Tile suggestion : shownSuggestions) {
-                final String identifier = mSuggestionFeatureProvider.getSuggestionIdentifier(
-                        mContext, suggestion);
-                mMetricsFeatureProvider.action(
-                        mContext, MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION, identifier,
-                        getSuggestionTaggedData());
-                mSuggestionsShownLogged.add(identifier);
-            }
-        }
     }
 
     public void setSuggestionsV2(List<Suggestion> data) {
@@ -191,7 +170,6 @@
                 .setSuggestionsV2(data)
                 .build();
         notifyDashboardDataChanged(prevData);
-        // TODO: Replicate the metrics logging from setCategoriesAndSuggestions()
     }
 
     public void setCategory(DashboardCategory category) {
@@ -331,22 +309,6 @@
         mRecyclerView = recyclerView;
     }
 
-    public void onPause() {
-        if (mDashboardData.getSuggestions() == null) {
-            return;
-        }
-        for (Tile suggestion : mDashboardData.getSuggestions()) {
-            String suggestionId = mSuggestionFeatureProvider.getSuggestionIdentifier(
-                    mContext, suggestion);
-            if (mSuggestionsShownLogged.contains(suggestionId)) {
-                mMetricsFeatureProvider.action(
-                        mContext, MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION, suggestionId,
-                        getSuggestionTaggedData());
-            }
-        }
-        mSuggestionsShownLogged.clear();
-    }
-
     public Object getItem(long itemId) {
         return mDashboardData.getItemEntityById(itemId);
     }
@@ -375,23 +337,6 @@
         }
     }
 
-    private void logSuggestions() {
-        final List<Tile> suggestions = mDashboardData.getSuggestions();
-        if (suggestions == null) {
-            return;
-        }
-        for (Tile suggestion : suggestions) {
-            final String suggestionId = mSuggestionFeatureProvider.getSuggestionIdentifier(
-                    mContext, suggestion);
-            if (!mSuggestionsShownLogged.contains(suggestionId)) {
-                mMetricsFeatureProvider.action(
-                        mContext, MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION, suggestionId,
-                        getSuggestionTaggedData());
-                mSuggestionsShownLogged.add(suggestionId);
-            }
-        }
-    }
-
     @VisibleForTesting
     void onBindSuggestionConditionHeader(final SuggestionAndConditionHeaderHolder holder,
             SuggestionConditionHeaderData data) {
@@ -460,9 +405,7 @@
         holder.itemView.setPadding(0, padding, 0, padding);
 
         holder.itemView.setOnClickListener(v -> {
-            if (moreSuggestions) {
-                logSuggestions();
-            } else if (hasConditions) {
+            if (hasConditions) {
                 mMetricsFeatureProvider.action(mContext,
                         MetricsEvent.ACTION_SETTINGS_CONDITION_EXPAND, true);
             }
@@ -587,11 +530,6 @@
         parent.setVisibility(View.VISIBLE);
     }
 
-    private Pair<Integer, Object>[] getSuggestionTaggedData() {
-        return SuggestionLogHelper.getSuggestionTaggedData(
-                mSuggestionFeatureProvider.isSmartSuggestionEnabled(mContext));
-    }
-
     public static class IconCache {
         private final Context mContext;
         private final ArrayMap<Icon, Drawable> mMap = new ArrayMap<>();
diff --git a/src/com/android/settings/dashboard/DashboardSummary.java b/src/com/android/settings/dashboard/DashboardSummary.java
index 4810c72..30a2fce 100644
--- a/src/com/android/settings/dashboard/DashboardSummary.java
+++ b/src/com/android/settings/dashboard/DashboardSummary.java
@@ -152,9 +152,6 @@
                 mMetricsFeatureProvider.hidden(getContext(), c.getMetricsConstant());
             }
         }
-        if (!getActivity().isChangingConfigurations()) {
-            mAdapter.onPause();
-        }
     }
 
     @Override
diff --git a/src/com/android/settings/dashboard/suggestions/SuggestionAdapter.java b/src/com/android/settings/dashboard/suggestions/SuggestionAdapter.java
index de266e1..8502fa7 100644
--- a/src/com/android/settings/dashboard/suggestions/SuggestionAdapter.java
+++ b/src/com/android/settings/dashboard/suggestions/SuggestionAdapter.java
@@ -21,7 +21,6 @@
 import android.support.v7.widget.RecyclerView;
 import android.text.TextUtils;
 import android.util.Log;
-import android.util.Pair;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
@@ -44,7 +43,7 @@
     private final Context mContext;
     private final MetricsFeatureProvider mMetricsFeatureProvider;
     private final SuggestionFeatureProvider mSuggestionFeatureProvider;
-    @Deprecated // in favor of mNewSuggestions
+    @Deprecated // in favor of mSuggestionsV2
     private final List<Tile> mSuggestions;
     private final List<Suggestion> mSuggestionsV2;
     private final IconCache mCache;
@@ -88,23 +87,15 @@
                     mContext, MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION, id);
             mSuggestionsShownLogged.add(id);
         }
-        // TODO: Add remote view field in Suggestion, and enable this.
-        //        if (suggestion.remoteViews != null) {
-        //            final ViewGroup itemView = (ViewGroup) holder.itemView;
-        //            itemView.removeAllViews();
-        //            itemView.addView(suggestion.remoteViews.apply(itemView.getContext(),
-        //                  itemView));
-        //        } else
-        {
-            holder.icon.setImageDrawable(mCache.getIcon(suggestion.getIcon()));
-            holder.title.setText(suggestion.getTitle());
-            final CharSequence summary = suggestion.getSummary();
-            if (!TextUtils.isEmpty(summary)) {
-                holder.summary.setText(summary);
-                holder.summary.setVisibility(View.VISIBLE);
-            } else {
-                holder.summary.setVisibility(View.GONE);
-            }
+
+        holder.icon.setImageDrawable(mCache.getIcon(suggestion.getIcon()));
+        holder.title.setText(suggestion.getTitle());
+        final CharSequence summary = suggestion.getSummary();
+        if (!TextUtils.isEmpty(summary)) {
+            holder.summary.setText(summary);
+            holder.summary.setVisibility(View.VISIBLE);
+        } else {
+            holder.summary.setVisibility(View.GONE);
         }
         final View divider = holder.itemView.findViewById(R.id.divider);
         if (divider != null) {
@@ -116,8 +107,6 @@
         final View primaryAction = holder.itemView.findViewById(android.R.id.primary);
         if (primaryAction != null) {
             clickHandler = primaryAction;
-            // set the item view to disabled to remove any touch effects
-            holder.itemView.setEnabled(false);
         }
         clickHandler.setOnClickListener(v -> {
             mMetricsFeatureProvider.action(mContext, MetricsEvent.ACTION_SETTINGS_SUGGESTION, id);
@@ -141,7 +130,7 @@
         if (!mSuggestionsShownLogged.contains(suggestionId)) {
             mMetricsFeatureProvider.action(
                     mContext, MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION, suggestionId,
-                    getSuggestionTaggedData());
+                    mSuggestionFeatureProvider.getLoggingTaggedData(mContext));
             mSuggestionsShownLogged.add(suggestionId);
         }
         if (suggestion.remoteViews != null) {
@@ -175,7 +164,7 @@
         clickHandler.setOnClickListener(v -> {
             mMetricsFeatureProvider.action(mContext,
                     MetricsEvent.ACTION_SETTINGS_SUGGESTION, suggestionId,
-                    getSuggestionTaggedData());
+                    mSuggestionFeatureProvider.getLoggingTaggedData(mContext));
             ((SettingsActivity) mContext).startSuggestion(suggestion.intent);
         });
     }
@@ -198,13 +187,12 @@
                     ? R.layout.suggestion_tile_remote_container
                     : R.layout.suggestion_tile;
         } else {
-
-            return R.layout.suggestion_tile;
-            // TODO: Add remote view field in Suggestion, and enable this.
-            //            Suggestion suggestion = getSuggestionsV2(position);
-            //            return suggestion.remoteViews != null
-            //                    ? R.layout.suggestion_tile_remote_container
-            //                    : R.layout.suggestion_tile;
+            final Suggestion suggestion = getSuggestionsV2(position);
+            if ((suggestion.getFlags() & Suggestion.FLAG_HAS_BUTTON) != 0) {
+                return R.layout.suggestion_tile_with_button;
+            } else {
+                return R.layout.suggestion_tile;
+            }
         }
     }
 
@@ -248,11 +236,6 @@
         notifyDataSetChanged();
     }
 
-    private Pair<Integer, Object>[] getSuggestionTaggedData() {
-        return SuggestionLogHelper.getSuggestionTaggedData(
-                mSuggestionFeatureProvider.isSmartSuggestionEnabled(mContext));
-    }
-
     public void removeSuggestion(Suggestion suggestion) {
         mSuggestionsV2.remove(suggestion);
         notifyDataSetChanged();
diff --git a/src/com/android/settings/dashboard/suggestions/SuggestionDismissController.java b/src/com/android/settings/dashboard/suggestions/SuggestionDismissController.java
index b3636c1..f269f69 100644
--- a/src/com/android/settings/dashboard/suggestions/SuggestionDismissController.java
+++ b/src/com/android/settings/dashboard/suggestions/SuggestionDismissController.java
@@ -89,7 +89,7 @@
     public int getSwipeDirs(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
         final int layoutId = viewHolder.getItemViewType();
         if (layoutId == R.layout.suggestion_tile
-                || layoutId == R.layout.suggestion_tile_remote_container) {
+                || layoutId == R.layout.suggestion_tile_with_button) {
             // Only return swipe direction for suggestion tiles. All other types are not swipeable.
             return super.getSwipeDirs(recyclerView, viewHolder);
         }
diff --git a/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProvider.java b/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProvider.java
index 0f8bccc..f911401 100644
--- a/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProvider.java
+++ b/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProvider.java
@@ -21,6 +21,7 @@
 import android.content.SharedPreferences;
 import android.service.settings.suggestions.Suggestion;
 import android.support.annotation.NonNull;
+import android.util.Pair;
 
 import com.android.settingslib.drawer.Tile;
 import com.android.settingslib.suggestions.SuggestionParser;
@@ -93,6 +94,14 @@
 
     /**
      * Returns an identifier for the suggestion
+     *
+     * @deprecated in favor or {@link Suggestion#getId()}
      */
+    @Deprecated
     String getSuggestionIdentifier(Context context, Tile suggestion);
+
+    /**
+     * Returns common tagged data for suggestion logging.
+     */
+    Pair<Integer, Object>[] getLoggingTaggedData(Context context);
 }
diff --git a/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImpl.java b/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImpl.java
index 02a9223..783987d 100644
--- a/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImpl.java
+++ b/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImpl.java
@@ -170,8 +170,7 @@
         if (parser == null || suggestion == null || context == null) {
             return;
         }
-        final Pair<Integer, Object>[] taggedData =
-                SuggestionLogHelper.getSuggestionTaggedData(isSmartSuggestionEnabled(context));
+        final Pair<Integer, Object>[] taggedData = getLoggingTaggedData(context);
 
         mMetricsFeatureProvider.action(
                 context, MetricsEvent.ACTION_SETTINGS_DISMISS_SUGGESTION,
@@ -213,6 +212,14 @@
         return packageName;
     }
 
+    @Override
+    public Pair<Integer, Object>[] getLoggingTaggedData(Context context) {
+        final boolean isSmartSuggestionEnabled = isSmartSuggestionEnabled(context);
+        return new Pair[]{Pair.create(
+                MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED,
+                isSmartSuggestionEnabled ? 1 : 0)};
+    }
+
     @VisibleForTesting
     boolean hasUsedNightDisplay(Context context) {
         final ContentResolver cr = context.getContentResolver();
diff --git a/src/com/android/settings/dashboard/suggestions/SuggestionLogHelper.java b/src/com/android/settings/dashboard/suggestions/SuggestionLogHelper.java
deleted file mode 100644
index 339392f..0000000
--- a/src/com/android/settings/dashboard/suggestions/SuggestionLogHelper.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2017 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.dashboard.suggestions;
-
-import android.util.Pair;
-
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-
-public class SuggestionLogHelper {
-
-    public static Pair<Integer, Object>[] getSuggestionTaggedData(boolean enabled) {
-        return new Pair[]{
-                Pair.create(
-                        MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, enabled ? 1 : 0)};
-    }
-}
diff --git a/src/com/android/settings/datausage/BillingCycleSettings.java b/src/com/android/settings/datausage/BillingCycleSettings.java
index d00749d..fb8119c 100644
--- a/src/com/android/settings/datausage/BillingCycleSettings.java
+++ b/src/com/android/settings/datausage/BillingCycleSettings.java
@@ -264,7 +264,7 @@
                 formatter.getUnitDisplayName(MeasureUnit.GIGABYTE)
             };
             final ArrayAdapter<String> adapter = new ArrayAdapter<String>(
-                    getContext(), android.R.layout.simple_spinner_item, unitNames);
+                    getContext(), R.layout.data_usage_spinner_item, unitNames);
             type.setAdapter(adapter);
 
             if (bytes > 1.5f * GB_IN_BYTES) {
diff --git a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
index 5d7a164..8f61c52 100644
--- a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
+++ b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
@@ -248,7 +248,7 @@
         controllers.add(new BugReportPreferenceControllerV2(context));
         controllers.add(new LocalBackupPasswordPreferenceController(context));
         controllers.add(new StayAwakePreferenceController(context, lifecycle));
-        // hdcp checking
+        controllers.add(new HdcpCheckingPreferenceController(context));
         controllers.add(new BluetoothSnoopLogPreferenceController(context));
         controllers.add(new OemUnlockPreferenceController(context, activity, fragment));
         // running services
@@ -280,7 +280,7 @@
         controllers.add(new WifiRoamScansPreferenceController(context));
         controllers.add(new MobileDataAlwaysOnPreferenceController(context));
         controllers.add(new TetheringHardwareAccelPreferenceController(context));
-        // select usb configuration
+        controllers.add(new SelectUsbConfigPreferenceController(context, lifecycle));
         controllers.add(new BluetoothDeviceNoNamePreferenceController(context));
         controllers.add(new BluetoothAbsoluteVolumePreferenceController(context));
         controllers.add(new BluetoothInbandRingingPreferenceController(context));
diff --git a/src/com/android/settings/development/HdcpCheckingPreferenceController.java b/src/com/android/settings/development/HdcpCheckingPreferenceController.java
new file mode 100644
index 0000000..a443f87
--- /dev/null
+++ b/src/com/android/settings/development/HdcpCheckingPreferenceController.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2017 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.development;
+
+import android.content.Context;
+import android.os.Build;
+import android.os.SystemProperties;
+import android.support.annotation.VisibleForTesting;
+import android.support.v7.preference.ListPreference;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+import android.text.TextUtils;
+
+import com.android.settings.R;
+import com.android.settingslib.development.SystemPropPoker;
+
+public class HdcpCheckingPreferenceController extends
+        DeveloperOptionsPreferenceController implements Preference.OnPreferenceChangeListener {
+
+    private static final String HDCP_CHECKING_KEY = "hdcp_checking";
+
+    @VisibleForTesting
+    static final String HDCP_CHECKING_PROPERTY = "persist.sys.hdcp_checking";
+    @VisibleForTesting
+    static final String USER_BUILD_TYPE = "user";
+
+    private final String[] mListValues;
+    private final String[] mListSummaries;
+    private ListPreference mPreference;
+
+    public HdcpCheckingPreferenceController(Context context) {
+        super(context);
+
+        mListValues = mContext.getResources().getStringArray(R.array.hdcp_checking_values);
+        mListSummaries = mContext.getResources().getStringArray(R.array.hdcp_checking_summaries);
+    }
+
+    @Override
+    public boolean isAvailable() {
+        return !TextUtils.equals(USER_BUILD_TYPE, getBuildType());
+    }
+
+    @Override
+    public String getPreferenceKey() {
+        return HDCP_CHECKING_KEY;
+    }
+
+    @Override
+    public void displayPreference(PreferenceScreen screen) {
+        super.displayPreference(screen);
+
+        mPreference = (ListPreference) screen.findPreference(getPreferenceKey());
+    }
+
+    @Override
+    public boolean onPreferenceChange(Preference preference, Object newValue) {
+        SystemProperties.set(HDCP_CHECKING_PROPERTY, newValue.toString());
+        updateHdcpValues();
+        SystemPropPoker.getInstance().poke();
+        return true;
+    }
+
+    @Override
+    public void updateState(Preference preference) {
+        updateHdcpValues();
+    }
+
+    @Override
+    protected void onDeveloperOptionsSwitchEnabled() {
+        mPreference.setEnabled(true);
+    }
+
+    @Override
+    protected void onDeveloperOptionsSwitchDisabled() {
+        mPreference.setEnabled(false);
+    }
+
+    private void updateHdcpValues() {
+        final String currentValue = SystemProperties.get(HDCP_CHECKING_PROPERTY);
+        int index = 1; // Defaults to drm-only. Needs to match with R.array.hdcp_checking_values
+        for (int i = 0; i < mListValues.length; i++) {
+            if (TextUtils.equals(currentValue, mListValues[i])) {
+                index = i;
+                break;
+            }
+        }
+        mPreference.setValue(mListValues[index]);
+        mPreference.setSummary(mListSummaries[index]);
+    }
+
+    @VisibleForTesting
+    public String getBuildType() {
+        return Build.TYPE;
+    }
+}
diff --git a/src/com/android/settings/development/SelectUsbConfigPreferenceController.java b/src/com/android/settings/development/SelectUsbConfigPreferenceController.java
new file mode 100644
index 0000000..41fe6a3
--- /dev/null
+++ b/src/com/android/settings/development/SelectUsbConfigPreferenceController.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2017 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.development;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.hardware.usb.UsbManager;
+import android.os.Bundle;
+import android.support.annotation.VisibleForTesting;
+import android.support.v7.preference.ListPreference;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+import android.text.TextUtils;
+
+import com.android.settings.R;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.core.lifecycle.LifecycleObserver;
+import com.android.settingslib.core.lifecycle.events.OnCreate;
+import com.android.settingslib.core.lifecycle.events.OnDestroy;
+
+public class SelectUsbConfigPreferenceController extends
+        DeveloperOptionsPreferenceController implements
+        Preference.OnPreferenceChangeListener, LifecycleObserver, OnCreate, OnDestroy {
+
+    private static final String USB_CONFIGURATION_KEY = "select_usb_configuration";
+
+    private final String[] mListValues;
+    private final String[] mListSummaries;
+    private final UsbManager mUsbManager;
+    private BroadcastReceiver mUsbReceiver;
+    private ListPreference mPreference;
+
+    public SelectUsbConfigPreferenceController(Context context, Lifecycle lifecycle) {
+        super(context);
+
+        mListValues = context.getResources().getStringArray(R.array.usb_configuration_values);
+        mListSummaries = context.getResources().getStringArray(R.array.usb_configuration_titles);
+        mUsbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
+        mUsbReceiver = new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                if (mPreference != null) {
+                    updateUsbConfigurationValues();
+                }
+            }
+        };
+        if (lifecycle != null) {
+            lifecycle.addObserver(this);
+        }
+    }
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(UsbManager.ACTION_USB_STATE);
+        mContext.registerReceiver(mUsbReceiver, filter);
+    }
+
+    @Override
+    public String getPreferenceKey() {
+        return USB_CONFIGURATION_KEY;
+    }
+
+    @Override
+    public void displayPreference(PreferenceScreen screen) {
+        super.displayPreference(screen);
+
+        mPreference = (ListPreference) screen.findPreference(getPreferenceKey());
+    }
+
+    @Override
+    public boolean onPreferenceChange(Preference preference, Object newValue) {
+        writeUsbConfigurationOption(newValue.toString());
+        updateUsbConfigurationValues();
+        return true;
+    }
+
+    @Override
+    public void updateState(Preference preference) {
+        updateUsbConfigurationValues();
+    }
+
+    @Override
+    public void onDestroy() {
+        mContext.unregisterReceiver(mUsbReceiver);
+    }
+
+    @Override
+    protected void onDeveloperOptionsSwitchEnabled() {
+        mPreference.setEnabled(true);
+    }
+
+    @Override
+    protected void onDeveloperOptionsSwitchDisabled() {
+        mPreference.setEnabled(false);
+    }
+
+    @VisibleForTesting
+    void setCurrentFunction(String newValue, boolean usbDataUnlocked) {
+        mUsbManager.setCurrentFunction(newValue, usbDataUnlocked);
+    }
+
+    private void updateUsbConfigurationValues() {
+        int index = 0;
+        for (int i = 0; i < mListValues.length; i++) {
+            if (mUsbManager.isFunctionEnabled(mListValues[i])) {
+                index = i;
+                break;
+            }
+        }
+        mPreference.setValue(mListValues[index]);
+        mPreference.setSummary(mListSummaries[index]);
+    }
+
+    private void writeUsbConfigurationOption(String newValue) {
+        if (TextUtils.equals(newValue, "none")) {
+            setCurrentFunction(newValue, false);
+        } else {
+            setCurrentFunction(newValue, true);
+        }
+    }
+
+}
diff --git a/tests/robotests/src/android/service/settings/suggestions/Suggestion.java b/tests/robotests/src/android/service/settings/suggestions/Suggestion.java
index 750bc05..79aeb93 100644
--- a/tests/robotests/src/android/service/settings/suggestions/Suggestion.java
+++ b/tests/robotests/src/android/service/settings/suggestions/Suggestion.java
@@ -18,15 +18,17 @@
 
 import android.app.PendingIntent;
 import android.graphics.drawable.Icon;
-import android.os.Parcel;
 import android.text.TextUtils;
-import android.widget.RemoteViews;
 
 public class Suggestion {
+
+    public static final int FLAG_HAS_BUTTON = 1 << 0;
+
     private final String mId;
     private final CharSequence mTitle;
     private final CharSequence mSummary;
     private final Icon mIcon;
+    private final int mFlags;
     private final PendingIntent mPendingIntent;
 
     /**
@@ -57,6 +59,10 @@
         return mIcon;
     }
 
+    public int getFlags() {
+        return mFlags;
+    }
+
     /**
      * The Intent to launch when the suggestion is activated.
      */
@@ -70,13 +76,16 @@
         mIcon = builder.mIcon;
         mPendingIntent = builder.mPendingIntent;
         mId = builder.mId;
+        mFlags = builder.mFlags;
     }
 
     /**
      * Builder class for {@link Suggestion}.
      */
     public static class Builder {
+
         private final String mId;
+        private int mFlags;
         private CharSequence mTitle;
         private CharSequence mSummary;
         private Icon mIcon;
@@ -114,6 +123,11 @@
             return this;
         }
 
+        public Builder setFlags(int flags) {
+            mFlags = flags;
+            return this;
+        }
+
         /**
          * Sets suggestion intent
          */
diff --git a/tests/robotests/src/com/android/settings/dashboard/DashboardAdapterTest.java b/tests/robotests/src/com/android/settings/dashboard/DashboardAdapterTest.java
index 595a9c6..14da5d6 100644
--- a/tests/robotests/src/com/android/settings/dashboard/DashboardAdapterTest.java
+++ b/tests/robotests/src/com/android/settings/dashboard/DashboardAdapterTest.java
@@ -24,7 +24,6 @@
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -39,12 +38,10 @@
 import android.service.settings.suggestions.Suggestion;
 import android.support.v7.widget.RecyclerView;
 import android.util.DisplayMetrics;
-import android.util.Pair;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.widget.RelativeLayout;
 
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settings.R;
 import com.android.settings.SettingsActivity;
 import com.android.settings.TestConfig;
@@ -61,8 +58,6 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Answers;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Captor;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 import org.robolectric.RuntimeEnvironment;
@@ -88,12 +83,6 @@
     private Condition mCondition;
     @Mock
     private Resources mResources;
-    @Captor
-    private ArgumentCaptor<Integer> mActionCategoryCaptor = ArgumentCaptor.forClass(Integer.class);
-    @Captor
-    private ArgumentCaptor<String> mActionPackageCaptor = ArgumentCaptor.forClass(String.class);
-    @Captor
-    private ArgumentCaptor<Pair> mTaggedDataCaptor = ArgumentCaptor.forClass(Pair.class);
     private FakeFeatureFactory mFactory;
     private DashboardAdapter mDashboardAdapter;
     private DashboardAdapter.SuggestionAndConditionHeaderHolder mSuggestionHolder;
@@ -110,7 +99,7 @@
                 .getSuggestionIdentifier(any(Context.class), any(Tile.class)))
                 .thenAnswer(invocation -> {
                     final Object[] args = invocation.getArguments();
-                    return ((Tile)args[1]).intent.getComponent().getPackageName();
+                    return ((Tile) args[1]).intent.getComponent().getPackageName();
                 });
 
         when(mContext.getResources()).thenReturn(mResources);
@@ -126,282 +115,6 @@
     }
 
     @Test
-    public void testSuggestionsLogs_NotExpanded() {
-        setupSuggestions(makeSuggestions("pkg1", "pkg2", "pkg3"));
-
-        verify(mFactory.metricsFeatureProvider, times(2)).action(
-                any(Context.class), mActionCategoryCaptor.capture(),
-                mActionPackageCaptor.capture(),
-                mTaggedDataCaptor.capture());
-        assertThat(mActionCategoryCaptor.getAllValues()).containsExactly(
-                MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION,
-                MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION);
-        assertThat(mActionPackageCaptor.getAllValues()).containsExactly("pkg1", "pkg2");
-        assertThat(mTaggedDataCaptor.getAllValues()).containsExactly(
-                Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0),
-                Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0));
-    }
-
-    @Test
-    public void testSuggestionsLogs_NotExpandedAndPaused() {
-        setupSuggestions(makeSuggestions("pkg1", "pkg2", "pkg3"));
-
-        mDashboardAdapter.onPause();
-
-        verify(mFactory.metricsFeatureProvider, times(4)).action(
-                any(Context.class), mActionCategoryCaptor.capture(),
-                mActionPackageCaptor.capture(),
-                mTaggedDataCaptor.capture());
-        assertThat(mActionCategoryCaptor.getAllValues()).containsExactly(
-                MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION,
-                MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION,
-                MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION,
-                MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION);
-        assertThat(mActionPackageCaptor.getAllValues()).containsExactly(
-                "pkg1", "pkg2", "pkg1", "pkg2");
-        assertThat(mTaggedDataCaptor.getAllValues()).containsExactly(
-                Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0),
-                Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0),
-                Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0),
-                Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0));
-    }
-
-    @Test
-    public void testSuggestionsLogs_Expanded() {
-        setupSuggestions(makeSuggestions("pkg1", "pkg2", "pkg3"));
-
-        mDashboardAdapter.onBindSuggestionConditionHeader(mSuggestionHolder, mSuggestionHeaderData);
-        mSuggestionHolder.itemView.callOnClick();
-
-        verify(mFactory.metricsFeatureProvider, times(3)).action(
-                any(Context.class), mActionCategoryCaptor.capture(),
-                mActionPackageCaptor.capture(),
-                mTaggedDataCaptor.capture());
-        assertThat(mActionCategoryCaptor.getAllValues()).containsExactly(
-                MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION,
-                MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION,
-                MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION);
-        assertThat(mActionPackageCaptor.getAllValues()).containsExactly(
-                "pkg1", "pkg2", "pkg3");
-        assertThat(mTaggedDataCaptor.getAllValues()).containsExactly(
-                Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0),
-                Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0),
-                Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0));
-    }
-
-    @Test
-    public void testSuggestionsLogs_ExpandedAndPaused() {
-        setupSuggestions(makeSuggestions("pkg1", "pkg2", "pkg3"));
-
-        mDashboardAdapter.onBindSuggestionConditionHeader(mSuggestionHolder, mSuggestionHeaderData);
-        mSuggestionHolder.itemView.callOnClick();
-        mDashboardAdapter.onPause();
-
-        verify(mFactory.metricsFeatureProvider, times(6)).action(
-                any(Context.class), mActionCategoryCaptor.capture(),
-                mActionPackageCaptor.capture(),
-                mTaggedDataCaptor.capture());
-        assertThat(mActionCategoryCaptor.getAllValues()).containsExactly(
-                MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION,
-                MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION,
-                MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION,
-                MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION,
-                MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION,
-                MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION);
-        assertThat(mActionPackageCaptor.getAllValues()).containsExactly(
-                "pkg1", "pkg2", "pkg3", "pkg1", "pkg2", "pkg3");
-        assertThat(mTaggedDataCaptor.getAllValues()).containsExactly(
-                Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0),
-                Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0),
-                Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0),
-                Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0),
-                Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0),
-                Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0));
-    }
-
-    @Test
-    public void testSuggestionsLogs_ExpandedAfterPause() {
-        setupSuggestions(makeSuggestions("pkg1", "pkg2", "pkg3"));
-
-        mDashboardAdapter.onPause();
-        mDashboardAdapter.onBindSuggestionConditionHeader(mSuggestionHolder, mSuggestionHeaderData);
-        mSuggestionHolder.itemView.callOnClick();
-
-        verify(mFactory.metricsFeatureProvider, times(7)).action(
-                any(Context.class), mActionCategoryCaptor.capture(),
-                mActionPackageCaptor.capture(),
-                mTaggedDataCaptor.capture());
-        assertThat(mActionCategoryCaptor.getAllValues()).containsExactly(
-                MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION,
-                MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION,
-                MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION,
-                MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION,
-                MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION,
-                MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION,
-                MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION);
-        assertThat(mActionPackageCaptor.getAllValues()).containsExactly(
-                "pkg1", "pkg2", "pkg1", "pkg2", "pkg1", "pkg2", "pkg3");
-        assertThat(mTaggedDataCaptor.getAllValues()).containsExactly(
-                Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0),
-                Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0),
-                Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0),
-                Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0),
-                Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0),
-                Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0),
-                Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0));
-    }
-
-    @Test
-    public void testSuggestionsLogs_ExpandedAfterPauseAndPausedAgain() {
-        setupSuggestions(makeSuggestions("pkg1", "pkg2", "pkg3"));
-
-        mDashboardAdapter.onPause();
-        mDashboardAdapter.onBindSuggestionConditionHeader(mSuggestionHolder, mSuggestionHeaderData);
-        mSuggestionHolder.itemView.callOnClick();
-        mDashboardAdapter.onPause();
-
-        verify(mFactory.metricsFeatureProvider, times(10)).action(
-                any(Context.class), mActionCategoryCaptor.capture(),
-                mActionPackageCaptor.capture(),
-                mTaggedDataCaptor.capture());
-        assertThat(mActionCategoryCaptor.getAllValues()).containsExactly(
-                MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION,
-                MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION,
-                MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION,
-                MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION,
-                MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION,
-                MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION,
-                MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION,
-                MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION,
-                MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION,
-                MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION);
-        assertThat(mActionPackageCaptor.getAllValues()).containsExactly(
-                "pkg1", "pkg2", "pkg1", "pkg2", "pkg1", "pkg2", "pkg3", "pkg1", "pkg2", "pkg3");
-        assertThat(mTaggedDataCaptor.getAllValues()).containsExactly(
-                Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0),
-                Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0),
-                Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0),
-                Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0),
-                Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0),
-                Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0),
-                Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0),
-                Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0),
-                Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0),
-                Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0));
-    }
-
-    @Test
-    public void testSuggestionsLogs_ExpandedWithLessThanDefaultShown() {
-        setupSuggestions(makeSuggestions("pkg1"));
-
-        mDashboardAdapter.onBindSuggestionConditionHeader(mSuggestionHolder, mSuggestionHeaderData);
-        mSuggestionHolder.itemView.callOnClick();
-
-        verify(mFactory.metricsFeatureProvider, times(1)).action(
-                any(Context.class), mActionCategoryCaptor.capture(),
-                mActionPackageCaptor.capture(),
-                mTaggedDataCaptor.capture());
-        assertThat(mActionCategoryCaptor.getAllValues()).containsExactly(
-                MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION);
-        assertThat(mActionPackageCaptor.getAllValues()).containsExactly("pkg1");
-        assertThat(mTaggedDataCaptor.getAllValues()).containsExactly(
-                Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0));
-    }
-
-    @Test
-    public void testSuggestionsLogs_ExpandedWithLessThanDefaultShownAndPaused() {
-        setupSuggestions(makeSuggestions("pkg1"));
-
-        mDashboardAdapter.onBindSuggestionConditionHeader(mSuggestionHolder, mSuggestionHeaderData);
-        mSuggestionHolder.itemView.callOnClick();
-        mDashboardAdapter.onPause();
-
-        verify(mFactory.metricsFeatureProvider, times(2)).action(
-                any(Context.class), mActionCategoryCaptor.capture(),
-                mActionPackageCaptor.capture(),
-                mTaggedDataCaptor.capture());
-        assertThat(mActionCategoryCaptor.getAllValues()).containsExactly(
-                MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION,
-                MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION);
-        assertThat(mActionPackageCaptor.getAllValues()).containsExactly("pkg1", "pkg1");
-        assertThat(mTaggedDataCaptor.getAllValues()).containsExactly(
-                Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0),
-                Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0));
-    }
-
-    @Test
-    public void testSuggestionsLogs_ExpandedWithLessThanDefaultShownAfterPause() {
-        setupSuggestions(makeSuggestions("pkg1"));
-
-        mDashboardAdapter.onPause();
-        mDashboardAdapter.onBindSuggestionConditionHeader(mSuggestionHolder, mSuggestionHeaderData);
-        mSuggestionHolder.itemView.callOnClick();
-
-        verify(mFactory.metricsFeatureProvider, times(3)).action(
-                any(Context.class), mActionCategoryCaptor.capture(),
-                mActionPackageCaptor.capture(),
-                mTaggedDataCaptor.capture());
-        assertThat(mActionCategoryCaptor.getAllValues()).containsExactly(
-                MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION,
-                MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION,
-                MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION);
-        assertThat(mActionPackageCaptor.getAllValues()).containsExactly("pkg1", "pkg1", "pkg1");
-        assertThat(mTaggedDataCaptor.getAllValues()).containsExactly(
-                Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0),
-                Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0),
-                Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0));
-    }
-
-    @Test
-    public void testSuggestionsLogs_ExpandedWithLessThanDefaultShownAfterPauseAndPausedAgain() {
-        setupSuggestions(makeSuggestions("pkg1"));
-        mDashboardAdapter.onPause();
-        mDashboardAdapter.onBindSuggestionConditionHeader(mSuggestionHolder, mSuggestionHeaderData);
-        mSuggestionHolder.itemView.callOnClick();
-        mDashboardAdapter.onPause();
-
-        verify(mFactory.metricsFeatureProvider, times(4)).action(
-                any(Context.class), mActionCategoryCaptor.capture(),
-                mActionPackageCaptor.capture(),
-                mTaggedDataCaptor.capture());
-        assertThat(mActionCategoryCaptor.getAllValues()).containsExactly(
-                MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION,
-                MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION,
-                MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION,
-                MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION);
-        assertThat(mActionPackageCaptor.getAllValues()).containsExactly(
-                "pkg1", "pkg1", "pkg1", "pkg1");
-        assertThat(mTaggedDataCaptor.getAllValues()).containsExactly(
-                Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0),
-                Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0),
-                Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0),
-                Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0));
-    }
-
-    @Test
-    public void testSuggestionsLogs_SmartSuggestionEnabled() {
-        when(mFactory.suggestionsFeatureProvider
-                .isSmartSuggestionEnabled(any(Context.class))).thenReturn(true);
-        setupSuggestions(makeSuggestions("pkg1"));
-
-        mDashboardAdapter.onBindSuggestionConditionHeader(mSuggestionHolder, mSuggestionHeaderData);
-        mSuggestionHolder.itemView.callOnClick();
-        mDashboardAdapter.onPause();
-
-        verify(mFactory.metricsFeatureProvider, times(2)).action(
-                any(Context.class), mActionCategoryCaptor.capture(),
-                mActionPackageCaptor.capture(),
-                mTaggedDataCaptor.capture());
-        assertThat(mActionCategoryCaptor.getAllValues()).containsExactly(
-                MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION,
-                MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION);
-        assertThat(mActionPackageCaptor.getAllValues()).containsExactly("pkg1", "pkg1");
-        assertThat(mTaggedDataCaptor.getAllValues()).containsExactly(
-                Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 1),
-                Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 1));
-    }
-
-    @Test
     public void testSuggestionsLogs_nullSuggestionsList_shouldNotCrash() {
         setupSuggestions(makeSuggestions("pkg1", "pkg2", "pkg3", "pkg4", "pkg5"));
         mDashboardAdapter.onBindSuggestionConditionHeader(mSuggestionHolder, mSuggestionHeaderData);
@@ -618,6 +331,10 @@
         verify(data).setAdapter(any(ConditionAdapter.class));
     }
 
+    /**
+     * @deprecated in favor of {@link #makeSuggestionsV2(String...)}
+     */
+    @Deprecated
     private List<Tile> makeSuggestions(String... pkgNames) {
         final List<Tile> suggestions = new ArrayList<>();
         for (String pkgName : pkgNames) {
diff --git a/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionAdapterTest.java b/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionAdapterTest.java
index 6b80465..825b388 100644
--- a/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionAdapterTest.java
+++ b/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionAdapterTest.java
@@ -39,6 +39,7 @@
 import android.widget.RemoteViews;
 import android.widget.TextView;
 
+import com.android.internal.logging.nano.MetricsProto;
 import com.android.settings.R;
 import com.android.settings.SettingsActivity;
 import com.android.settings.TestConfig;
@@ -66,7 +67,7 @@
 
     @Mock(answer = Answers.RETURNS_DEEP_STUBS)
     private SettingsActivity mActivity;
-
+    private FakeFeatureFactory mFeatureFactory;
     private Context mContext;
     private SuggestionAdapter mSuggestionAdapter;
     private DashboardAdapter.DashboardItemHolder mSuggestionHolder;
@@ -79,7 +80,7 @@
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         mContext = RuntimeEnvironment.application;
-        FakeFeatureFactory.setupForTest(mActivity);
+        mFeatureFactory = FakeFeatureFactory.setupForTest(mActivity);
 
         final Tile suggestion1 = new Tile();
         final Tile suggestion2 = new Tile();
@@ -144,6 +145,21 @@
     }
 
     @Test
+    public void getItemType_hasButton_shouldReturnSuggestionWithButton() {
+        final List<Suggestion> suggestions = new ArrayList<>();
+        suggestions.add(new Suggestion.Builder("id")
+                .setFlags(Suggestion.FLAG_HAS_BUTTON)
+                .setTitle("123")
+                .setSummary("456")
+                .build());
+        mSuggestionAdapter = new SuggestionAdapter(mContext, null /* suggestions */,
+                suggestions, new ArrayList<>());
+
+        assertThat(mSuggestionAdapter.getItemViewType(0))
+                .isEqualTo(R.layout.suggestion_tile_with_button);
+    }
+
+    @Test
     public void onBindViewHolder_shouldSetListener() {
         final View view = spy(LayoutInflater.from(mContext).inflate(
                 R.layout.suggestion_tile, new LinearLayout(mContext), true));
@@ -157,6 +173,24 @@
     }
 
     @Test
+    public void onBindViewHolder_shouldLog() {
+        final View view = spy(LayoutInflater.from(mContext).inflate(
+                R.layout.suggestion_tile, new LinearLayout(mContext), true));
+        mSuggestionHolder = new DashboardAdapter.DashboardItemHolder(view);
+        mSuggestionAdapter = new SuggestionAdapter(mContext, null /* suggestionV1*/,
+                mOneSuggestionV2, new ArrayList<>());
+
+        // Bind twice
+        mSuggestionAdapter.onBindViewHolder(mSuggestionHolder, 0);
+        mSuggestionAdapter.onBindViewHolder(mSuggestionHolder, 0);
+
+        // Log once
+        verify(mFeatureFactory.metricsFeatureProvider).action(
+                mContext, MetricsProto.MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION,
+                mOneSuggestionV2.get(0).getId());
+    }
+
+    @Test
     public void onBindViewHolder_shouldInflateRemoteView() {
         List<Tile> packages = makeSuggestions("pkg1");
         RemoteViews remoteViews = mock(RemoteViews.class);
diff --git a/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionDismissControllerTest.java b/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionDismissControllerTest.java
index 93bc549..4aced2f 100644
--- a/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionDismissControllerTest.java
+++ b/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionDismissControllerTest.java
@@ -92,7 +92,7 @@
     @Test
     public void getSwipeDirs_isSuggestionTileCard_shouldReturnDirection() {
         final RecyclerView.ViewHolder vh = mock(RecyclerView.ViewHolder.class);
-        when(vh.getItemViewType()).thenReturn(R.layout.suggestion_tile_remote_container);
+        when(vh.getItemViewType()).thenReturn(R.layout.suggestion_tile_with_button);
 
         assertThat(mController.getSwipeDirs(mRecyclerView, vh))
                 .isEqualTo(ItemTouchHelper.START | ItemTouchHelper.END);
diff --git a/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImplTest.java b/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImplTest.java
index 69b76fa..5e56714 100644
--- a/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImplTest.java
+++ b/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImplTest.java
@@ -22,6 +22,7 @@
 import static org.mockito.Matchers.anyString;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyZeroInteractions;
 import static org.mockito.Mockito.when;
@@ -313,4 +314,19 @@
                 new ComponentName(mContext, NightDisplaySuggestionActivity.class);
         assertThat(mProvider.isSuggestionComplete(mContext, componentName)).isFalse();
     }
+
+    @Test
+    public void testGetSmartSuggestionEnabledTaggedData_disabled() {
+        assertThat(mProvider.getLoggingTaggedData(mContext)).asList().containsExactly(
+                Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0));
+    }
+
+    @Test
+    public void testGetSmartSuggestionEnabledTaggedData_enabled() {
+        final SuggestionFeatureProvider provider = spy(mProvider);
+        when(provider.isSmartSuggestionEnabled(any(Context.class))).thenReturn(true);
+
+        assertThat(provider.getLoggingTaggedData(mContext)).asList().containsExactly(
+                Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 1));
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionLogHelperTest.java b/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionLogHelperTest.java
deleted file mode 100644
index 01d253f..0000000
--- a/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionLogHelperTest.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2017 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.dashboard.suggestions;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.util.Pair;
-
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.settings.TestConfig;
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.annotation.Config;
-
-@RunWith(SettingsRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
-public class SuggestionLogHelperTest {
-
-    @Test
-    public void testGetSmartSuggestionEnabledTaggedData_disabled() {
-        assertThat(SuggestionLogHelper.getSuggestionTaggedData(false)).asList().containsExactly(
-                Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0));
-    }
-
-    @Test
-    public void testGetSmartSuggestionEnabledTaggedData_enabled() {
-        assertThat(SuggestionLogHelper.getSuggestionTaggedData(true)).asList().containsExactly(
-                Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 1));
-    }
-}
-
diff --git a/tests/robotests/src/com/android/settings/development/HdcpCheckingPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/HdcpCheckingPreferenceControllerTest.java
new file mode 100644
index 0000000..434941c
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/development/HdcpCheckingPreferenceControllerTest.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2017 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.development;
+
+import static com.android.settings.development.HdcpCheckingPreferenceController
+        .HDCP_CHECKING_PROPERTY;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.os.SystemProperties;
+import android.support.v7.preference.ListPreference;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.settings.R;
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settings.testutils.shadow.SettingsShadowSystemProperties;
+
+import org.junit.After;
+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;
+import org.robolectric.annotation.Config;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH,
+        sdk = TestConfig.SDK_VERSION,
+        shadows = {SettingsShadowSystemProperties.class})
+public class HdcpCheckingPreferenceControllerTest {
+
+    private static final String USER_DEBUG = "userdebug";
+
+    @Mock
+    private ListPreference mPreference;
+    @Mock
+    private PreferenceScreen mScreen;
+
+    private Context mContext;
+    private HdcpCheckingPreferenceController mController;
+
+    /**
+     * Array Values Key
+     *
+     * 0: Never Check
+     * 1: Check for DRM content only
+     * 2: Always Check
+     */
+    private String[] mValues;
+    private String[] mSummaries;
+
+    @Before
+    public void setup() {
+        MockitoAnnotations.initMocks(this);
+        mContext = RuntimeEnvironment.application;
+        mValues = mContext.getResources().getStringArray(R.array.hdcp_checking_values);
+        mSummaries = mContext.getResources().getStringArray(R.array.hdcp_checking_summaries);
+        mController = new HdcpCheckingPreferenceController(mContext);
+        when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
+        mController.displayPreference(mScreen);
+
+    }
+
+    @After
+    public void teardown() {
+        SettingsShadowSystemProperties.clear();
+    }
+
+    @Test
+    public void isAvailable_isUserBuildType_shouldReturnFalse() {
+        mController = spy(mController);
+        doReturn(HdcpCheckingPreferenceController.USER_BUILD_TYPE).when(mController).getBuildType();
+
+        assertThat(mController.isAvailable()).isFalse();
+    }
+
+    @Test
+    public void isAvailable_isUserDebugBuildType_shouldReturnTrue() {
+        mController = spy(mController);
+        doReturn(USER_DEBUG).when(mController).getBuildType();
+
+        assertThat(mController.isAvailable()).isTrue();
+    }
+
+    @Test
+    public void onPreferenceChange_setNeverCheckHdcp_shouldEnableNeverCheckHdcp() {
+        mController.onPreferenceChange(mPreference, mValues[0]);
+
+        assertThat(SystemProperties.get(HDCP_CHECKING_PROPERTY)).isEqualTo(mValues[0]);
+    }
+
+    @Test
+    public void onPreferenceChange_setCheckDrm_shouldEnableCheckDrm() {
+        mController.onPreferenceChange(mPreference, mValues[1]);
+
+        assertThat(SystemProperties.get(HDCP_CHECKING_PROPERTY)).isEqualTo(mValues[1]);
+    }
+
+    @Test
+    public void updateState_neverCheckHdcp_shouldEnableNeverCheckHdcp() {
+        SystemProperties.set(HDCP_CHECKING_PROPERTY, mValues[0]);
+
+        mController.updateState(mPreference);
+
+        verify(mPreference).setValue(mValues[0]);
+        verify(mPreference).setSummary(mSummaries[0]);
+    }
+
+    @Test
+    public void updateState_checkDrm_shouldEnableCheckDrm() {
+        SystemProperties.set(HDCP_CHECKING_PROPERTY, mValues[1]);
+
+        mController.updateState(mPreference);
+
+        verify(mPreference).setValue(mValues[1]);
+        verify(mPreference).setSummary(mSummaries[1]);
+    }
+
+    @Test
+    public void updateState_noValueSet_shouldEnableCheckDrmAsDefault() {
+        SystemProperties.set(HDCP_CHECKING_PROPERTY, null);
+
+        mController.updateState(mPreference);
+
+        verify(mPreference).setValue(mValues[1]);
+        verify(mPreference).setSummary(mSummaries[1]);
+    }
+
+    @Test
+    public void onDeveloperOptionsSwitchDisabled_shouldDisablePreference() {
+        mController.onDeveloperOptionsSwitchDisabled();
+
+        verify(mPreference).setEnabled(false);
+    }
+
+    @Test
+    public void onDeveloperOptionsSwitchEnabled_shouldEnablePreference() {
+        mController.onDeveloperOptionsSwitchEnabled();
+
+        verify(mPreference).setEnabled(true);
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/development/SelectUsbConfigPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/SelectUsbConfigPreferenceControllerTest.java
new file mode 100644
index 0000000..8b96af0
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/development/SelectUsbConfigPreferenceControllerTest.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2017 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.development;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.hardware.usb.UsbManager;
+import android.support.v7.preference.ListPreference;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.settings.R;
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+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;
+import org.robolectric.annotation.Config;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class SelectUsbConfigPreferenceControllerTest {
+
+    @Mock
+    private ListPreference mPreference;
+    @Mock
+    private PreferenceScreen mScreen;
+    @Mock
+    private UsbManager mUsbManager;
+
+    private Context mContext;
+    private Lifecycle mLifecycle;
+    private SelectUsbConfigPreferenceController mController;
+
+    /**
+     * Array Values Key
+     *
+     * 0: Charging
+     * 1: MTP
+     * 2: PTP
+     * 3: RNDIS
+     * 4: Audio Source
+     * 5: MIDI
+     */
+    private String[] mValues;
+    private String[] mSummaries;
+
+    @Before
+    public void setup() {
+        MockitoAnnotations.initMocks(this);
+        mLifecycle = new Lifecycle();
+        mContext = spy(RuntimeEnvironment.application);
+        doReturn(mUsbManager).when(mContext).getSystemService(Context.USB_SERVICE);
+        mValues = mContext.getResources().getStringArray(R.array.usb_configuration_values);
+        mSummaries = mContext.getResources().getStringArray(R.array.usb_configuration_titles);
+        mController = spy(new SelectUsbConfigPreferenceController(mContext, mLifecycle));
+        when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
+        mController.displayPreference(mScreen);
+
+    }
+
+    @Test
+    public void onPreferenceChange_setCharging_shouldEnableCharging() {
+        when(mUsbManager.isFunctionEnabled(mValues[0])).thenReturn(true);
+        doNothing().when(mController).setCurrentFunction(anyString(), anyBoolean());
+        mController.onPreferenceChange(mPreference, mValues[0]);
+
+        verify(mController).setCurrentFunction(mValues[0], false /* usb data unlock */);
+    }
+
+    @Test
+    public void onPreferenceChange_setMtp_shouldEnableMtp() {
+        when(mUsbManager.isFunctionEnabled(mValues[1])).thenReturn(true);
+        doNothing().when(mController).setCurrentFunction(anyString(), anyBoolean());
+        mController.onPreferenceChange(mPreference, mValues[1]);
+
+        verify(mController).setCurrentFunction(mValues[1], true /* usb data unlock */);
+    }
+
+    @Test
+    public void updateState_chargingEnabled_shouldSetPreferenceToCharging() {
+        when(mUsbManager.isFunctionEnabled(mValues[0])).thenReturn(true);
+
+        mController.updateState(mPreference);
+
+        verify(mPreference).setValue(mValues[0]);
+        verify(mPreference).setSummary(mSummaries[0]);
+    }
+
+    @Test
+    public void updateState_RndisEnabled_shouldEnableRndis() {
+        when(mUsbManager.isFunctionEnabled(mValues[3])).thenReturn(true);
+
+        mController.updateState(mPreference);
+
+        verify(mPreference).setValue(mValues[3]);
+        verify(mPreference).setSummary(mSummaries[3]);
+    }
+
+    @Test
+    public void updateState_noValueSet_shouldEnableChargingAsDefault() {
+        mController.updateState(mPreference);
+
+        verify(mPreference).setValue(mValues[0]);
+        verify(mPreference).setSummary(mSummaries[0]);
+    }
+
+    @Test
+    public void onDeveloperOptionsSwitchDisabled_shouldDisablePreference() {
+        mController.onDeveloperOptionsSwitchDisabled();
+
+        verify(mPreference).setEnabled(false);
+    }
+
+    @Test
+    public void onDeveloperOptionsSwitchEnabled_shouldEnablePreference() {
+        mController.onDeveloperOptionsSwitchEnabled();
+
+        verify(mPreference).setEnabled(true);
+    }
+
+    @Test
+    public void onCreate_shouldRegisterReceiver() {
+        mLifecycle.onCreate(null /* bundle */);
+
+        verify(mContext).registerReceiver(any(), any());
+    }
+
+    @Test
+    public void onDestroy_shouldUnregisterReceiver() {
+        doNothing().when(mContext).unregisterReceiver(any());
+        mLifecycle.onDestroy();
+
+        verify(mContext).unregisterReceiver(any());
+    }
+}