Merge "Evenly space theme options." into ub-launcher3-qt-dev
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 0046cad..4857768 100755
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -7,6 +7,7 @@
 
     <uses-permission android:name="android.permission.CHANGE_OVERLAY_PACKAGES"/>
     <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS"/>
+    <uses-permission android:name="android.permission.SET_WALLPAPER_COMPONENT" />
 
     <application
         android:extractNativeLibs="false"
diff --git a/src/com/android/customization/model/theme/DefaultThemeProvider.java b/src/com/android/customization/model/theme/DefaultThemeProvider.java
index a2b9ab5..e282cbd 100644
--- a/src/com/android/customization/model/theme/DefaultThemeProvider.java
+++ b/src/com/android/customization/model/theme/DefaultThemeProvider.java
@@ -31,15 +31,20 @@
 import static com.android.customization.model.ResourceConstants.SETTINGS_PACKAGE;
 import static com.android.customization.model.ResourceConstants.SYSUI_PACKAGE;
 
+import android.content.ComponentName;
 import android.content.Context;
+import android.content.Intent;
 import android.content.om.OverlayInfo;
 import android.content.om.OverlayManager;
+import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.ResolveInfo;
 import android.content.res.Resources;
 import android.content.res.Resources.NotFoundException;
 import android.graphics.Typeface;
 import android.graphics.drawable.Drawable;
 import android.os.UserHandle;
+import android.service.wallpaper.WallpaperService;
 import android.text.TextUtils;
 import android.util.Log;
 
@@ -54,12 +59,15 @@
 import com.android.customization.module.CustomizationPreferences;
 import com.android.wallpaper.R;
 import com.android.wallpaper.asset.ResourceAsset;
+import com.android.wallpaper.model.LiveWallpaperInfo;
 
 import com.bumptech.glide.request.RequestOptions;
 
 import org.json.JSONException;
 import org.json.JSONObject;
+import org.xmlpull.v1.XmlPullParserException;
 
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Iterator;
@@ -169,26 +177,7 @@
 
                 addNoPreviewIconOverlay(builder, iconSettingsOverlayPackage);
 
-                try {
-                    String wallpaperResName = WALLPAPER_PREFIX + themeName;
-                    int wallpaperResId = mStubApkResources.getIdentifier(wallpaperResName,
-                            "drawable", mStubPackageName);
-                    if (wallpaperResId > 0) {
-                        builder.setWallpaperInfo(mStubPackageName, wallpaperResName,
-                                themeName, wallpaperResId,
-                                mStubApkResources.getIdentifier(WALLPAPER_TITLE_PREFIX + themeName,
-                                        "string", mStubPackageName),
-                                mStubApkResources.getIdentifier(
-                                        WALLPAPER_ATTRIBUTION_PREFIX + themeName, "string",
-                                        mStubPackageName),
-                                mStubApkResources.getIdentifier(WALLPAPER_ACTION_PREFIX + themeName,
-                                        "string", mStubPackageName))
-                                .setWallpaperAsset(
-                                        getDrawableResourceAsset(WALLPAPER_PREFIX, themeName));
-                    }
-                } catch (NotFoundException e) {
-                    // Nothing to do here, if there's no wallpaper we'll just omit wallpaper
-                }
+                addWallpaper(themeName, builder);
 
                 mThemes.add(builder.build(mContext));
             } catch (NameNotFoundException | NotFoundException e) {
@@ -200,6 +189,58 @@
         addCustomTheme();
     }
 
+    private void addWallpaper(String themeName, Builder builder) {
+        try {
+            String wallpaperResName = WALLPAPER_PREFIX + themeName;
+            int wallpaperResId = mStubApkResources.getIdentifier(wallpaperResName,
+                    "drawable", mStubPackageName);
+            if (wallpaperResId > 0) {
+                builder.setWallpaperInfo(mStubPackageName, wallpaperResName,
+                        themeName, wallpaperResId,
+                        mStubApkResources.getIdentifier(WALLPAPER_TITLE_PREFIX + themeName,
+                                "string", mStubPackageName),
+                        mStubApkResources.getIdentifier(
+                                WALLPAPER_ATTRIBUTION_PREFIX + themeName, "string",
+                                mStubPackageName),
+                        mStubApkResources.getIdentifier(WALLPAPER_ACTION_PREFIX + themeName,
+                                "string", mStubPackageName))
+                        .setWallpaperAsset(
+                                getDrawableResourceAsset(WALLPAPER_PREFIX, themeName));
+            } else {
+                // Try to see if it's a live wallpaper reference
+                wallpaperResId = mStubApkResources.getIdentifier(wallpaperResName,
+                        "string", mStubPackageName);
+                if (wallpaperResId > 0) {
+                    String wpComponent = mStubApkResources.getString(wallpaperResId);
+                    String[] componentParts = wpComponent.split("/");
+                    Intent liveWpIntent =  new Intent(WallpaperService.SERVICE_INTERFACE);
+                    liveWpIntent.setComponent(
+                            new ComponentName(componentParts[0],
+                                    componentParts[0] + componentParts[1]));
+                    Context appContext = mContext.getApplicationContext();
+                    PackageManager pm = appContext.getPackageManager();
+                    ResolveInfo resolveInfo =
+                            pm.resolveService(liveWpIntent, PackageManager.GET_META_DATA);
+                    if (resolveInfo != null) {
+                        android.app.WallpaperInfo wallpaperInfo;
+                        try {
+                            wallpaperInfo = new android.app.WallpaperInfo(appContext, resolveInfo);
+                            LiveWallpaperInfo liveInfo = new LiveWallpaperInfo(wallpaperInfo);
+                            builder.setLiveWallpaperInfo(liveInfo)
+                                    .setWallpaperAsset(liveInfo.getThumbAsset(mContext));
+                        } catch (XmlPullParserException e) {
+                            Log.w(TAG, "Skipping wallpaper " + resolveInfo.serviceInfo, e);
+                        } catch (IOException e) {
+                            Log.w(TAG, "Skipping wallpaper " + resolveInfo.serviceInfo, e);
+                        }
+                    }
+                }
+            }
+        } catch (NotFoundException e) {
+            // Nothing to do here, if there's no wallpaper we'll just omit wallpaper
+        }
+    }
+
     private void addColorOverlay(Builder builder, String colorOverlayPackage)
             throws NameNotFoundException {
         if (!TextUtils.isEmpty(colorOverlayPackage)) {
@@ -373,29 +414,7 @@
             addSystemDefaultIcons(builder, SYSUI_PACKAGE, ICONS_FOR_PREVIEW);
         }
 
-        try {
-            String wallpaperResName = WALLPAPER_PREFIX + DEFAULT_THEME_NAME;
-            int wallpaperResId = mStubApkResources.getIdentifier(wallpaperResName,
-                    "drawable", mStubPackageName);
-            if (wallpaperResId > 0) {
-                builder.setWallpaperInfo(mStubPackageName, wallpaperResName, DEFAULT_THEME_NAME,
-                        mStubApkResources.getIdentifier(
-                                wallpaperResName,
-                                "drawable", mStubPackageName),
-                        mStubApkResources.getIdentifier(WALLPAPER_TITLE_PREFIX + DEFAULT_THEME_NAME,
-                                "string", mStubPackageName),
-                        mStubApkResources.getIdentifier(
-                                WALLPAPER_ATTRIBUTION_PREFIX + DEFAULT_THEME_NAME, "string",
-                                mStubPackageName),
-                        mStubApkResources.getIdentifier(
-                                WALLPAPER_ACTION_PREFIX + DEFAULT_THEME_NAME,
-                                "string", mStubPackageName))
-                        .setWallpaperAsset(
-                                getDrawableResourceAsset(WALLPAPER_PREFIX, DEFAULT_THEME_NAME));
-            }
-        } catch (NotFoundException e) {
-            // Nothing to do here, if there's no wallpaper we'll just omit wallpaper
-        }
+        addWallpaper(DEFAULT_THEME_NAME, builder);
 
         mThemes.add(builder.build(mContext));
     }
diff --git a/src/com/android/customization/model/theme/ThemeBundle.java b/src/com/android/customization/model/theme/ThemeBundle.java
index 5b056cf..414719e 100644
--- a/src/com/android/customization/model/theme/ThemeBundle.java
+++ b/src/com/android/customization/model/theme/ThemeBundle.java
@@ -50,6 +50,7 @@
 import com.android.wallpaper.asset.Asset;
 import com.android.wallpaper.asset.BitmapCachingAsset;
 import com.android.wallpaper.asset.ResourceAsset;
+import com.android.wallpaper.model.LiveWallpaperInfo;
 import com.android.wallpaper.model.WallpaperInfo;
 
 import org.json.JSONObject;
@@ -255,7 +256,7 @@
         private PreviewInfo(Context context, Typeface bodyFontFamily, Typeface headlineFontFamily,
                 int colorAccentLight, int colorAccentDark, List<Drawable> icons,
                 Drawable shapeDrawable, @Dimension int cornerRadius,
-                @Nullable ResourceAsset wallpaperAsset, List<Drawable> shapeAppIcons) {
+                @Nullable Asset wallpaperAsset, List<Drawable> shapeAppIcons) {
             this.bodyFontFamily = bodyFontFamily;
             this.headlineFontFamily = headlineFontFamily;
             this.colorAccentLight = colorAccentLight;
@@ -290,7 +291,7 @@
         private String mShapePath;
         private boolean mIsDefault;
         @Dimension private int mCornerRadius;
-        private ResourceAsset mWallpaperAsset;
+        private Asset mWallpaperAsset;
         private WallpaperInfo mWallpaperInfo;
         protected Map<String, String> mPackages = new HashMap<>();
         private List<Drawable> mAppIcons = new ArrayList<>();
@@ -372,7 +373,13 @@
             return this;
         }
 
-        public Builder setWallpaperAsset(ResourceAsset wallpaperAsset) {
+        public Builder setLiveWallpaperInfo(LiveWallpaperInfo info) {
+            mWallpaperInfo = info;
+            return this;
+        }
+
+
+        public Builder setWallpaperAsset(Asset wallpaperAsset) {
             mWallpaperAsset = wallpaperAsset;
             return this;
         }
diff --git a/src/com/android/customization/model/theme/ThemeManager.java b/src/com/android/customization/model/theme/ThemeManager.java
index ec859bf..cd33f6b 100644
--- a/src/com/android/customization/model/theme/ThemeManager.java
+++ b/src/com/android/customization/model/theme/ThemeManager.java
@@ -27,9 +27,7 @@
 import static com.android.customization.model.ResourceConstants.SYSUI_PACKAGE;
 
 import android.graphics.Point;
-import android.os.UserHandle;
 import android.provider.Settings;
-import android.text.TextUtils;
 
 import androidx.annotation.Nullable;
 import androidx.fragment.app.FragmentActivity;
@@ -40,8 +38,6 @@
 import com.android.customization.module.ThemesUserEventLogger;
 import com.android.wallpaper.R;
 import com.android.wallpaper.asset.Asset;
-import com.android.wallpaper.module.Injector;
-import com.android.wallpaper.module.InjectorProvider;
 import com.android.wallpaper.module.WallpaperPersister;
 import com.android.wallpaper.module.WallpaperPersister.SetWallpaperCallback;
 import com.android.wallpaper.module.WallpaperSetter;
@@ -95,7 +91,8 @@
         // Set wallpaper
         if (theme.shouldUseThemeWallpaper()) {
             mWallpaperSetter.requestDestination(mActivity, mActivity.getSupportFragmentManager(),
-                    R.string.set_theme_wallpaper_dialog_message, new Listener() {
+                    R.string.set_theme_wallpaper_dialog_message, theme.getWallpaperInfo(),
+                    new Listener() {
                         @Override
                         public void onSetHomeScreen() {
                             applyWallpaper(theme, WallpaperPersister.DEST_HOME_SCREEN,
@@ -140,19 +137,27 @@
                 mActivity.getResources(),
                 mActivity.getWindowManager().getDefaultDisplay());
         Asset wallpaperAsset = theme.getWallpaperInfo().getAsset(mActivity);
-        wallpaperAsset.decodeRawDimensions(mActivity,
-                dimensions -> {
-                    float scale = 1f;
-                    // Calculate scale to fit the screen height
-                    if (dimensions != null && dimensions.y > 0) {
-                        scale = (float) defaultCropSurfaceSize.y / dimensions.y;
-                    }
-                    mWallpaperSetter.setCurrentWallpaper(mActivity,
-                            theme.getWallpaperInfo(),
-                            wallpaperAsset,
-                            destination,
-                            scale, null, callback);
-                });
+        if (wallpaperAsset != null) {
+            wallpaperAsset.decodeRawDimensions(mActivity,
+                    dimensions -> {
+                        float scale = 1f;
+                        // Calculate scale to fit the screen height
+                        if (dimensions != null && dimensions.y > 0) {
+                            scale = (float) defaultCropSurfaceSize.y / dimensions.y;
+                        }
+                        mWallpaperSetter.setCurrentWallpaper(mActivity,
+                                theme.getWallpaperInfo(),
+                                wallpaperAsset,
+                                destination,
+                                scale, null, callback);
+                    });
+        } else {
+            mWallpaperSetter.setCurrentWallpaper(mActivity,
+                    theme.getWallpaperInfo(),
+                    null,
+                    destination,
+                    1f, null, callback);
+        }
     }
 
     private void applyOverlays(ThemeBundle theme, Callback callback) {