Merge "Settings: update color mode preview to final content" into pi-dev
diff --git a/res/drawable-nodpi/gesture_swipe_up.png b/res/drawable-nodpi/gesture_swipe_up.png
index b9390d2..ef3610e 100644
--- a/res/drawable-nodpi/gesture_swipe_up.png
+++ b/res/drawable-nodpi/gesture_swipe_up.png
Binary files differ
diff --git a/res/layout/settings_main_dashboard.xml b/res/layout/settings_main_dashboard.xml
index 10ff2ee..c430d6d 100644
--- a/res/layout/settings_main_dashboard.xml
+++ b/res/layout/settings_main_dashboard.xml
@@ -27,7 +27,7 @@
         android:id="@+id/search_bar_container"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:background="@color/suggestion_condition_background">
+        android:background="?android:attr/colorPrimary">
         <android.support.v7.widget.CardView
             android:id="@+id/search_bar"
             android:layout_width="match_parent"
diff --git a/res/raw/gesture_swipe_up.mp4 b/res/raw/gesture_swipe_up.mp4
index 16cbb2b..a8959e4 100644
--- a/res/raw/gesture_swipe_up.mp4
+++ b/res/raw/gesture_swipe_up.mp4
Binary files differ
diff --git a/res/values/colors.xml b/res/values/colors.xml
index 397d9e7..1fa434d 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -95,7 +95,7 @@
     <color name="usage_graph_dots">#B0BEC5</color>
 
     <!-- Gestures settings -->
-    <color name="gestures_setting_background_color">#f4f4f4</color>
+    <color name="gestures_setting_background_color">#ffffff</color>
 
     <color name="status_bar_color">#3c3c3c</color>
 
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 6ca4715..9075891 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -474,7 +474,7 @@
     </style>
 
     <style name="SuggestionConditionStyle">
-        <item name="android:background">@color/suggestion_condition_background</item>
+        <item name="android:background">?android:attr/colorPrimary</item>
     </style>
 
     <style name="TextAppearance.SearchBar" parent="@android:style/TextAppearance.Material.Widget.Toolbar.Subtitle">
diff --git a/res/xml/assist_gesture_settings.xml b/res/xml/assist_gesture_settings.xml
index b2ceac9..7cbd483 100644
--- a/res/xml/assist_gesture_settings.xml
+++ b/res/xml/assist_gesture_settings.xml
@@ -30,6 +30,7 @@
         android:key="gesture_assist"
         android:title="@string/assist_gesture_title"
         app:keywords="@string/keywords_assist_gesture_launch"
-        app:controller="com.android.settings.gestures.AssistGestureSettingsPreferenceController" />
+        app:controller="com.android.settings.gestures.AssistGestureSettingsPreferenceController"
+        app:allowDividerAbove="true" />
 
 </PreferenceScreen>
diff --git a/res/xml/auto_brightness_detail.xml b/res/xml/auto_brightness_detail.xml
index 88c878a..8b683f1 100644
--- a/res/xml/auto_brightness_detail.xml
+++ b/res/xml/auto_brightness_detail.xml
@@ -33,6 +33,7 @@
         settings:keywords="@string/keywords_display_auto_brightness"
         settings:controller="com.android.settings.display.AutoBrightnessPreferenceController"
         settings:useAdminDisabledSummary="true"
-        settings:userRestriction="no_config_brightness" />
+        settings:userRestriction="no_config_brightness"
+        settings:allowDividerAbove="true" />
 
 </PreferenceScreen>
\ No newline at end of file
diff --git a/res/xml/double_tap_power_settings.xml b/res/xml/double_tap_power_settings.xml
index 6614899..c04a90b 100644
--- a/res/xml/double_tap_power_settings.xml
+++ b/res/xml/double_tap_power_settings.xml
@@ -31,6 +31,7 @@
         android:title="@string/double_tap_power_for_camera_title"
         android:summary="@string/double_tap_power_for_camera_summary"
         app:keywords="@string/keywords_gesture"
-        app:controller="com.android.settings.gestures.DoubleTapPowerPreferenceController" />
+        app:controller="com.android.settings.gestures.DoubleTapPowerPreferenceController"
+        app:allowDividerAbove="true" />
 
 </PreferenceScreen>
\ No newline at end of file
diff --git a/res/xml/double_tap_screen_settings.xml b/res/xml/double_tap_screen_settings.xml
index 4d2e168..2734143 100644
--- a/res/xml/double_tap_screen_settings.xml
+++ b/res/xml/double_tap_screen_settings.xml
@@ -31,6 +31,7 @@
         android:title="@string/ambient_display_title"
         android:summary="@string/ambient_display_summary"
         app:keywords="@string/keywords_gesture"
-        app:controller="com.android.settings.gestures.DoubleTapScreenPreferenceController" />
+        app:controller="com.android.settings.gestures.DoubleTapScreenPreferenceController"
+        app:allowDividerAbove="true" />
 
 </PreferenceScreen>
\ No newline at end of file
diff --git a/res/xml/double_twist_gesture_settings.xml b/res/xml/double_twist_gesture_settings.xml
index 1da862d..f91bd35 100644
--- a/res/xml/double_twist_gesture_settings.xml
+++ b/res/xml/double_twist_gesture_settings.xml
@@ -31,6 +31,7 @@
         android:title="@string/double_twist_for_camera_mode_title"
         android:summary="@string/double_twist_for_camera_mode_summary"
         app:keywords="@string/keywords_gesture"
-        app:controller="com.android.settings.gestures.DoubleTwistPreferenceController" />
+        app:controller="com.android.settings.gestures.DoubleTwistPreferenceController"
+        app:allowDividerAbove="true" />
 
 </PreferenceScreen>
\ No newline at end of file
diff --git a/res/xml/pick_up_gesture_settings.xml b/res/xml/pick_up_gesture_settings.xml
index ccf2d8a..47f707a 100644
--- a/res/xml/pick_up_gesture_settings.xml
+++ b/res/xml/pick_up_gesture_settings.xml
@@ -31,6 +31,7 @@
         android:title="@string/ambient_display_pickup_title"
         android:summary="@string/ambient_display_pickup_summary"
         app:keywords="@string/keywords_gesture"
-        app:controller="com.android.settings.gestures.PickupGesturePreferenceController" />
+        app:controller="com.android.settings.gestures.PickupGesturePreferenceController"
+        app:allowDividerAbove="true" />
 
 </PreferenceScreen>
\ No newline at end of file
diff --git a/res/xml/prevent_ringing_gesture_settings.xml b/res/xml/prevent_ringing_gesture_settings.xml
index 08146e4..5135664 100644
--- a/res/xml/prevent_ringing_gesture_settings.xml
+++ b/res/xml/prevent_ringing_gesture_settings.xml
@@ -32,6 +32,7 @@
         android:entries="@array/gesture_prevent_ringing_entries"
         android:entryValues="@array/gesture_prevent_ringing_values"
         app:controller="com.android.settings.gestures.PreventRingingPreferenceController"
-        app:keywords="@string/keywords_gesture" />
+        app:keywords="@string/keywords_gesture"
+        app:allowDividerAbove="true" />
 
 </PreferenceScreen>
\ No newline at end of file
diff --git a/res/xml/swipe_to_notification_settings.xml b/res/xml/swipe_to_notification_settings.xml
index 04dc0c7..b126170 100644
--- a/res/xml/swipe_to_notification_settings.xml
+++ b/res/xml/swipe_to_notification_settings.xml
@@ -30,6 +30,7 @@
         android:title="@string/fingerprint_swipe_for_notifications_title"
         android:summary="@string/fingerprint_swipe_for_notifications_summary"
         app:keywords="@string/keywords_gesture"
-        app:controller="com.android.settings.gestures.SwipeToNotificationPreferenceController" />
+        app:controller="com.android.settings.gestures.SwipeToNotificationPreferenceController"
+        app:allowDividerAbove="true" />
 
 </PreferenceScreen>
\ No newline at end of file
diff --git a/res/xml/swipe_up_gesture_settings.xml b/res/xml/swipe_up_gesture_settings.xml
index 0f1dc4a..cc1db16 100644
--- a/res/xml/swipe_up_gesture_settings.xml
+++ b/res/xml/swipe_up_gesture_settings.xml
@@ -31,6 +31,7 @@
         android:title="@string/swipe_up_to_switch_apps_title"
         android:summary="@string/swipe_up_to_switch_apps_summary"
         app:keywords="@string/keywords_gesture"
-        app:controller="com.android.settings.gestures.SwipeUpPreferenceController" />
+        app:controller="com.android.settings.gestures.SwipeUpPreferenceController"
+        app:allowDividerAbove="true" />
 
 </PreferenceScreen>
\ No newline at end of file
diff --git a/src/com/android/settings/slices/SettingsSliceProvider.java b/src/com/android/settings/slices/SettingsSliceProvider.java
index 70e9d76..f449605 100644
--- a/src/com/android/settings/slices/SettingsSliceProvider.java
+++ b/src/com/android/settings/slices/SettingsSliceProvider.java
@@ -29,6 +29,7 @@
 import android.support.annotation.VisibleForTesting;
 import android.support.v4.graphics.drawable.IconCompat;
 import android.text.TextUtils;
+import android.util.ArrayMap;
 import android.util.Log;
 import android.util.Pair;
 
@@ -38,6 +39,7 @@
 import java.net.URISyntaxException;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.WeakHashMap;
@@ -111,12 +113,14 @@
     SlicesDatabaseAccessor mSlicesDatabaseAccessor;
 
     @VisibleForTesting
+    Map<Uri, SliceData> mSliceWeakDataCache;
     Map<Uri, SliceData> mSliceDataCache;
 
     @Override
     public boolean onCreateSliceProvider() {
         mSlicesDatabaseAccessor = new SlicesDatabaseAccessor(getContext());
-        mSliceDataCache = new WeakHashMap<>();
+        mSliceDataCache = new ArrayMap<>();
+        mSliceWeakDataCache = new WeakHashMap<>();
         return true;
     }
 
@@ -132,6 +136,17 @@
     }
 
     @Override
+    public void onSlicePinned(Uri sliceUri) {
+        // Start warming the slice, we expect someone will want it soon.
+        loadSliceInBackground(sliceUri);
+    }
+
+    @Override
+    public void onSliceUnpinned(Uri sliceUri) {
+        mSliceDataCache.remove(sliceUri);
+    }
+
+    @Override
     public Slice onBindSlice(Uri sliceUri) {
         String path = sliceUri.getPath();
         // If adding a new Slice, do not directly match Slice URIs.
@@ -141,14 +156,16 @@
                 return createWifiSlice(sliceUri);
         }
 
-        SliceData cachedSliceData = mSliceDataCache.get(sliceUri);
+        SliceData cachedSliceData = mSliceWeakDataCache.get(sliceUri);
         if (cachedSliceData == null) {
             loadSliceInBackground(sliceUri);
             return getSliceStub(sliceUri);
         }
 
         // Remove the SliceData from the cache after it has been used to prevent a memory-leak.
-        mSliceDataCache.remove(sliceUri);
+        if (!mSliceDataCache.containsKey(sliceUri)) {
+            mSliceWeakDataCache.remove(sliceUri);
+        }
         return SliceBuilderUtils.buildSlice(getContext(), cachedSliceData);
     }
 
@@ -236,7 +253,12 @@
         long startBuildTime = System.currentTimeMillis();
 
         final SliceData sliceData = mSlicesDatabaseAccessor.getSliceDataFromUri(uri);
-        mSliceDataCache.put(uri, sliceData);
+        List<Uri> pinnedSlices = getContext().getSystemService(
+                SliceManager.class).getPinnedSlices();
+        if (pinnedSlices.contains(uri)) {
+            mSliceDataCache.put(uri, sliceData);
+        }
+        mSliceWeakDataCache.put(uri, sliceData);
         getContext().getContentResolver().notifyChange(uri, null /* content observer */);
 
         Log.d(TAG, "Built slice (" + uri + ") in: " +
diff --git a/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java b/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java
index b5399ea..0fda33e 100644
--- a/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java
+++ b/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java
@@ -21,9 +21,12 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.when;
 
+import android.app.slice.SliceManager;
 import android.content.ContentResolver;
 import android.content.ContentValues;
 import android.content.Context;
@@ -43,7 +46,9 @@
 
 import androidx.slice.Slice;
 
+import java.util.Arrays;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.HashMap;
 
 /**
@@ -65,17 +70,22 @@
     private Context mContext;
     private SettingsSliceProvider mProvider;
     private SQLiteDatabase mDb;
+    private SliceManager mManager;
 
     @Before
     public void setUp() {
         mContext = spy(RuntimeEnvironment.application);
         mProvider = spy(new SettingsSliceProvider());
+        mProvider.mSliceWeakDataCache = new HashMap<>();
         mProvider.mSliceDataCache = new HashMap<>();
         mProvider.mSlicesDatabaseAccessor = new SlicesDatabaseAccessor(mContext);
         when(mProvider.getContext()).thenReturn(mContext);
 
         mDb = SlicesDatabaseHelper.getInstance(mContext).getWritableDatabase();
         SlicesDatabaseHelper.getInstance(mContext).setIndexedState();
+        mManager = mock(SliceManager.class);
+        when(mContext.getSystemService(SliceManager.class)).thenReturn(mManager);
+        when(mManager.getPinnedSlices()).thenReturn(Collections.emptyList());
     }
 
     @After
@@ -99,6 +109,30 @@
         Uri uri = SliceBuilderUtils.getUri(INTENT_PATH, false);
 
         mProvider.loadSlice(uri);
+        SliceData data = mProvider.mSliceWeakDataCache.get(uri);
+
+        assertThat(data.getKey()).isEqualTo(KEY);
+        assertThat(data.getTitle()).isEqualTo(TITLE);
+    }
+
+    @Test
+    public void testLoadSlice_doesntCacheWithoutPin() {
+        insertSpecialCase(KEY);
+        Uri uri = SliceBuilderUtils.getUri(INTENT_PATH, false);
+
+        mProvider.loadSlice(uri);
+        SliceData data = mProvider.mSliceDataCache.get(uri);
+
+        assertThat(data).isNull();
+    }
+
+    @Test
+    public void testLoadSlice_cachesWithPin() {
+        insertSpecialCase(KEY);
+        Uri uri = SliceBuilderUtils.getUri(INTENT_PATH, false);
+        when(mManager.getPinnedSlices()).thenReturn(Arrays.asList(uri));
+
+        mProvider.loadSlice(uri);
         SliceData data = mProvider.mSliceDataCache.get(uri);
 
         assertThat(data.getKey()).isEqualTo(KEY);
@@ -108,11 +142,23 @@
     @Test
     public void testLoadSlice_cachedEntryRemovedOnBuild() {
         SliceData data = getDummyData();
-        mProvider.mSliceDataCache.put(data.getUri(), data);
+        mProvider.mSliceWeakDataCache.put(data.getUri(), data);
         mProvider.onBindSlice(data.getUri());
         insertSpecialCase(data.getKey());
 
-        SliceData cachedData = mProvider.mSliceDataCache.get(data.getUri());
+        SliceData cachedData = mProvider.mSliceWeakDataCache.get(data.getUri());
+
+        assertThat(cachedData).isNull();
+    }
+
+    @Test
+    public void testLoadSlice_cachedEntryRemovedOnUnpin() {
+        SliceData data = getDummyData();
+        mProvider.mSliceDataCache.put(data.getUri(), data);
+        mProvider.onSliceUnpinned(data.getUri());
+        insertSpecialCase(data.getKey());
+
+        SliceData cachedData = mProvider.mSliceWeakDataCache.get(data.getUri());
 
         assertThat(cachedData).isNull();
     }