Reuse slice metadata and list content

It seems to be good for performance, not sure exact impact when lots
of content is involved, but in slices without content, speedup is
near 2x.

Test: :slice-benchmark:connectedMinDepVersionsDebugAndroidTest
Bug: 119113402
Change-Id: I2e650d57e858514086861bd93190261bd8151a59
diff --git a/slices/view/src/main/java/androidx/slice/SliceMetadata.java b/slices/view/src/main/java/androidx/slice/SliceMetadata.java
index 79f73ca..b124b81 100644
--- a/slices/view/src/main/java/androidx/slice/SliceMetadata.java
+++ b/slices/view/src/main/java/androidx/slice/SliceMetadata.java
@@ -487,4 +487,12 @@
         return (mExpiry == 0 || mExpiry == SliceHints.INFINITY || now > mExpiry)
                 ? 0 : mExpiry - now;
     }
+
+    /**
+     * @hide
+     */
+    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+    public ListContent getListContent() {
+        return mListContent;
+    }
 }
diff --git a/slices/view/src/main/java/androidx/slice/widget/SliceView.java b/slices/view/src/main/java/androidx/slice/widget/SliceView.java
index 940fc44..c2c019b 100644
--- a/slices/view/src/main/java/androidx/slice/widget/SliceView.java
+++ b/slices/view/src/main/java/androidx/slice/widget/SliceView.java
@@ -451,10 +451,13 @@
         initSliceMetrics(slice);
         boolean isUpdate = slice != null && mCurrentSlice != null
                 && slice.getUri().equals(mCurrentSlice.getUri());
+        SliceMetadata oldSliceData = mSliceMetadata;
+        mCurrentSlice = slice;
+        mSliceMetadata = mCurrentSlice != null ? SliceMetadata.from(getContext(), mCurrentSlice)
+                : null;
         if (isUpdate) {
             // If its an update check the loading state
-            SliceMetadata oldSliceData = SliceMetadata.from(getContext(), mCurrentSlice);
-            SliceMetadata newSliceData = SliceMetadata.from(getContext(), slice);
+            SliceMetadata newSliceData = mSliceMetadata;
             if (oldSliceData.getLoadingState() == SliceMetadata.LOADED_ALL
                     && newSliceData.getLoadingState() == SliceMetadata.LOADED_NONE) {
                 // If it's the same slice going from "loaded all" to "loaded none"... let's
@@ -464,12 +467,11 @@
         } else {
             mCurrentView.resetView();
         }
-        mCurrentSlice = slice;
-        mListContent = new ListContent(mCurrentSlice);
+        mListContent = mSliceMetadata != null ? mSliceMetadata.getListContent() : null;
         if (mShowActionDividers) {
             showActionDividers(true);
         }
-        if (!mListContent.isValid()) {
+        if (mListContent == null || !mListContent.isValid()) {
             mActions = null;
             mCurrentView.resetView();
             updateActions();
@@ -479,7 +481,6 @@
         mCurrentView.setLoadingActions(null);
 
         // Check if the slice content is expired and show when it was last updated
-        mSliceMetadata = SliceMetadata.from(getContext(), mCurrentSlice);
         mActions = mSliceMetadata.getSliceActions();
         mCurrentView.setLastUpdated(mSliceMetadata.getLastUpdatedTime());
         mCurrentView.setShowLastUpdated(mShowLastUpdated && mSliceMetadata.isExpired());