Merge "Explicitly detach from wallpaper service when disconnecting" into sc-dev
diff --git a/src/com/android/wallpaper/model/Category.java b/src/com/android/wallpaper/model/Category.java
index c353e19..99d7500 100755
--- a/src/com/android/wallpaper/model/Category.java
+++ b/src/com/android/wallpaper/model/Category.java
@@ -20,6 +20,8 @@
 import android.graphics.drawable.Drawable;
 import android.text.TextUtils;
 
+import androidx.annotation.Nullable;
+
 import com.android.wallpaper.asset.Asset;
 
 /**
@@ -64,6 +66,25 @@
     }
 
     /**
+     * Returns true if this category contains a single Wallpaper, which could then be retrieved
+     * via {@link #getSingleWallpaper()}
+     */
+    public boolean isSingleWallpaperCategory() {
+        return false;
+    }
+
+    /**
+     * If {@link #isSingleWallpaperCategory()} returned true, this method will return the single
+     * wallpaper contained in this category.
+     * @return a {@link WallpaperInfo} for the one wallpaper in this category, if this category is
+     * a single wallpaper category, or {@code null} otherwise.
+     */
+    @Nullable
+    public WallpaperInfo getSingleWallpaper() {
+        return null;
+    }
+
+    /**
      * @return The title of the category.
      */
     public String getTitle() {
diff --git a/src/com/android/wallpaper/model/WallpaperCategory.java b/src/com/android/wallpaper/model/WallpaperCategory.java
index 858d19f..0393a48 100755
--- a/src/com/android/wallpaper/model/WallpaperCategory.java
+++ b/src/com/android/wallpaper/model/WallpaperCategory.java
@@ -21,6 +21,7 @@
 import android.util.AttributeSet;
 
 import androidx.annotation.IdRes;
+import androidx.annotation.Nullable;
 import androidx.annotation.StringRes;
 
 import com.android.wallpaper.asset.Asset;
@@ -83,6 +84,17 @@
         return true;
     }
 
+    @Override
+    public boolean isSingleWallpaperCategory() {
+        return mWallpapers != null && mWallpapers.size() == 1;
+    }
+
+    @Nullable
+    @Override
+    public WallpaperInfo getSingleWallpaper() {
+        return isSingleWallpaperCategory() ? mWallpapers.get(0) : null;
+    }
+
     /**
      * Returns the mutable list of wallpapers backed by this WallpaperCategory. All reads and writes
      * on the returned list must be synchronized with {@code mWallpapersLock}.
diff --git a/src/com/android/wallpaper/module/DefaultCategoryProvider.java b/src/com/android/wallpaper/module/DefaultCategoryProvider.java
index eeb9925..9372e7a 100755
--- a/src/com/android/wallpaper/module/DefaultCategoryProvider.java
+++ b/src/com/android/wallpaper/module/DefaultCategoryProvider.java
@@ -312,10 +312,6 @@
                                 || parser.getDepth() > categoryDepth)
                                 && type != XmlPullParser.END_DOCUMENT) {
                             if (type == XmlPullParser.START_TAG) {
-                                if (!publishedPlaceholder) {
-                                    publishProgress(categoryBuilder.buildPlaceholder());
-                                    publishedPlaceholder = true;
-                                }
                                 WallpaperInfo wallpaper = null;
                                 if (SystemStaticWallpaperInfo.TAG_NAME.equals(parser.getName())) {
                                     wallpaper = SystemStaticWallpaperInfo
@@ -329,12 +325,19 @@
                                 }
                                 if (wallpaper != null) {
                                     categoryBuilder.addWallpaper(wallpaper);
+                                    // Publish progress only if there's at least one wallpaper
+                                    if (!publishedPlaceholder) {
+                                        publishProgress(categoryBuilder.buildPlaceholder());
+                                        publishedPlaceholder = true;
+                                    }
                                 }
                             }
                         }
                         WallpaperCategory category = categoryBuilder.build();
-                        categories.add(category);
-                        publishProgress(category);
+                        if (!category.getUnmodifiableWallpapers().isEmpty()) {
+                            categories.add(category);
+                            publishProgress(category);
+                        }
                     }
                 }
             } catch (IOException | XmlPullParserException e) {
diff --git a/src/com/android/wallpaper/picker/CategorySelectorFragment.java b/src/com/android/wallpaper/picker/CategorySelectorFragment.java
index 4c04942..0455f47 100644
--- a/src/com/android/wallpaper/picker/CategorySelectorFragment.java
+++ b/src/com/android/wallpaper/picker/CategorySelectorFragment.java
@@ -15,6 +15,9 @@
  */
 package com.android.wallpaper.picker;
 
+import static com.android.wallpaper.picker.WallpaperPickerDelegate.PREVIEW_LIVE_WALLPAPER_REQUEST_CODE;
+import static com.android.wallpaper.picker.WallpaperPickerDelegate.PREVIEW_WALLPAPER_REQUEST_CODE;
+
 import android.app.Activity;
 import android.app.AlertDialog;
 import android.content.Intent;
@@ -44,6 +47,8 @@
 import com.android.wallpaper.asset.Asset;
 import com.android.wallpaper.model.Category;
 import com.android.wallpaper.model.CategoryProvider;
+import com.android.wallpaper.model.LiveWallpaperInfo;
+import com.android.wallpaper.model.WallpaperInfo;
 import com.android.wallpaper.module.InjectorProvider;
 import com.android.wallpaper.module.UserEventLogger;
 import com.android.wallpaper.util.DeepLinkUtils;
@@ -289,8 +294,9 @@
 
         @Override
         public void onClick(View view) {
+            Activity activity = getActivity();
             final UserEventLogger eventLogger =
-                    InjectorProvider.getInjector().getUserEventLogger(getActivity());
+                    InjectorProvider.getInjector().getUserEventLogger(activity);
             eventLogger.logCategorySelected(mCategory.getCollectionId());
 
             if (mCategory.supportsCustomPhotos()) {
@@ -309,6 +315,20 @@
                 return;
             }
 
+            if (mCategory.isSingleWallpaperCategory()) {
+                WallpaperInfo wallpaper = mCategory.getSingleWallpaper();
+                // Log click on individual wallpaper
+                eventLogger.logIndividualWallpaperSelected(mCategory.getCollectionId());
+
+                InjectorProvider.getInjector().getWallpaperPersister(activity)
+                        .setWallpaperInfoInPreview(wallpaper);
+                wallpaper.showPreview(activity,
+                        new PreviewActivity.PreviewActivityIntentFactory(),
+                        wallpaper instanceof LiveWallpaperInfo ? PREVIEW_LIVE_WALLPAPER_REQUEST_CODE
+                                : PREVIEW_WALLPAPER_REQUEST_CODE);
+                return;
+            }
+
             getCategorySelectorFragmentHost().show(mCategory);
         }