Merge "Prompt users to set wallpaper on lockscreen on N+." into ub-launcher3-burnaby-nyc
diff --git a/WallpaperPicker/res/values/arrays.xml b/WallpaperPicker/res/values/arrays.xml
new file mode 100644
index 0000000..5c10b98
--- /dev/null
+++ b/WallpaperPicker/res/values/arrays.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 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.
+-->
+<resources>
+    <string-array name="which_wallpaper_options">
+        <item>@string/which_wallpaper_option_home_screen</item>
+        <item>@string/which_wallpaper_option_lock_screen</item>
+        <item>@string/which_wallpaper_option_home_screen_and_lock_screen</item>
+    </string-array>
+</resources>
\ No newline at end of file
diff --git a/WallpaperPicker/res/values/strings.xml b/WallpaperPicker/res/values/strings.xml
index 2bfd476..aef6a1a 100644
--- a/WallpaperPicker/res/values/strings.xml
+++ b/WallpaperPicker/res/values/strings.xml
@@ -53,4 +53,11 @@
     <string name="pick_wallpaper">Wallpapers</string>
     <!-- Title of activity for cropping wallpapers -->
     <string name="crop_wallpaper">Crop wallpaper</string>
+
+    <!-- Option for setting the wallpaper only on the home screen. -->
+    <string name="which_wallpaper_option_home_screen">Home screen</string>
+    <!-- Option for setting the wallpaper only on the lock screen. -->
+    <string name="which_wallpaper_option_lock_screen">Lock screen</string>
+    <!-- Option for setting the wallpaper on both the home screen and lock screen. -->
+    <string name="which_wallpaper_option_home_screen_and_lock_screen">Home screen and lock screen</string>
 </resources>
diff --git a/WallpaperPicker/src/com/android/gallery3d/common/BitmapCropTask.java b/WallpaperPicker/src/com/android/gallery3d/common/BitmapCropTask.java
index 8b51447..2d10b72 100644
--- a/WallpaperPicker/src/com/android/gallery3d/common/BitmapCropTask.java
+++ b/WallpaperPicker/src/com/android/gallery3d/common/BitmapCropTask.java
@@ -33,7 +33,9 @@
 import android.util.Log;
 import android.widget.Toast;
 
+import com.android.launcher3.NycWallpaperUtils;
 import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
 
 import java.io.BufferedInputStream;
 import java.io.ByteArrayInputStream;
@@ -42,7 +44,7 @@
 import java.io.IOException;
 import java.io.InputStream;
 
-public class BitmapCropTask extends AsyncTask<Void, Void, Boolean> {
+public class BitmapCropTask extends AsyncTask<Integer, Void, Boolean> {
 
     public interface OnBitmapCroppedHandler {
         public void onBitmapCropped(byte[] imageBytes);
@@ -175,7 +177,7 @@
     public Bitmap getCroppedBitmap() {
         return mCroppedBitmap;
     }
-    public boolean cropBitmap() {
+    public boolean cropBitmap(int whichWallpaper) {
         boolean failure = false;
 
 
@@ -189,7 +191,11 @@
             try {
                 InputStream is = regenerateInputStream();
                 if (is != null) {
-                    wallpaperManager.setStream(is);
+                    if (!Utilities.isNycOrAbove()) {
+                        wallpaperManager.setStream(is);
+                    } else {
+                        NycWallpaperUtils.setStream(mContext, is, null, true, whichWallpaper);
+                    }
                     Utils.closeSilently(is);
                 }
             } catch (IOException e) {
@@ -375,7 +381,13 @@
                 if (mSetWallpaper && wallpaperManager != null) {
                     try {
                         byte[] outByteArray = tmpOut.toByteArray();
-                        wallpaperManager.setStream(new ByteArrayInputStream(outByteArray));
+                        if (!Utilities.isNycOrAbove()) {
+                            wallpaperManager.setStream(new ByteArrayInputStream(outByteArray));
+                        } else {
+                            NycWallpaperUtils.setStream(mContext,
+                                    new ByteArrayInputStream(outByteArray), null, true,
+                                    whichWallpaper);
+                        }
                         if (mOnBitmapCroppedHandler != null) {
                             mOnBitmapCroppedHandler.onBitmapCropped(outByteArray);
                         }
@@ -393,8 +405,8 @@
     }
 
     @Override
-    protected Boolean doInBackground(Void... params) {
-        return cropBitmap();
+    protected Boolean doInBackground(Integer... params) {
+        return cropBitmap(params.length == 0 ? NycWallpaperUtils.FLAG_SET_SYSTEM : params[0]);
     }
 
     @Override
diff --git a/WallpaperPicker/src/com/android/launcher3/NycWallpaperUtils.java b/WallpaperPicker/src/com/android/launcher3/NycWallpaperUtils.java
new file mode 100644
index 0000000..abac830
--- /dev/null
+++ b/WallpaperPicker/src/com/android/launcher3/NycWallpaperUtils.java
@@ -0,0 +1,79 @@
+package com.android.launcher3;
+
+import android.app.AlertDialog;
+import android.app.WallpaperManager;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.graphics.Rect;
+import android.os.AsyncTask;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+/**
+ * Utility class used to help set lockscreen wallpapers on N+.
+ */
+public class NycWallpaperUtils {
+    public static final int FLAG_SET_SYSTEM = 1 << 0; // TODO: use WallpaperManager.FLAG_SET_SYSTEM
+    public static final int FLAG_SET_LOCK = 1 << 1; // TODO: use WallpaperManager.FLAG_SET_LOCK
+
+    /**
+     * Calls cropTask.execute(), once the user has selected which wallpaper to set. On pre-N
+     * devices, the prompt is not displayed since there is no API to set the lockscreen wallpaper.
+     */
+    public static void executeCropTaskAfterPrompt(
+            Context context, final AsyncTask<Integer, ?, ?> cropTask,
+            DialogInterface.OnCancelListener onCancelListener) {
+        if (Utilities.isNycOrAbove()) {
+            new AlertDialog.Builder(context)
+                    .setTitle(R.string.wallpaper_instructions)
+                    .setItems(R.array.which_wallpaper_options, new DialogInterface.OnClickListener() {
+                        @Override
+                        public void onClick(DialogInterface dialog, int selectedItemIndex) {
+                            int whichWallpaper;
+                            if (selectedItemIndex == 0) {
+                                whichWallpaper = FLAG_SET_SYSTEM;
+                            } else if (selectedItemIndex == 1) {
+                                whichWallpaper = FLAG_SET_LOCK;
+                            } else {
+                                whichWallpaper = FLAG_SET_SYSTEM | FLAG_SET_LOCK;
+                            }
+                            cropTask.execute(whichWallpaper);
+                        }
+                    })
+                    .setOnCancelListener(onCancelListener)
+                    .show();
+        } else {
+            cropTask.execute(FLAG_SET_SYSTEM);
+        }
+    }
+
+    public static void setStream(Context context, final InputStream data, Rect visibleCropHint,
+            boolean allowBackup, int whichWallpaper) throws IOException {
+        WallpaperManager wallpaperManager = WallpaperManager.getInstance(context);
+        try {
+            // TODO: use mWallpaperManager.setStream(data, visibleCropHint, allowBackup, which)
+            // without needing reflection.
+            Method setStream = WallpaperManager.class.getMethod("setStream", InputStream.class,
+                    Rect.class, boolean.class, int.class);
+            setStream.invoke(wallpaperManager, data, visibleCropHint, allowBackup, whichWallpaper);
+        } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
+            // Fall back to previous implementation (set system)
+            wallpaperManager.setStream(data);
+        }
+    }
+
+    public static void clear(Context context, int whichWallpaper) throws IOException {
+        WallpaperManager wallpaperManager = WallpaperManager.getInstance(context);
+        try {
+            // TODO: use mWallpaperManager.clear(whichWallpaper) without needing reflection.
+            Method clear = WallpaperManager.class.getMethod("clear", int.class);
+            clear.invoke(wallpaperManager, whichWallpaper);
+        } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
+            // Fall back to previous implementation (clear system)
+            wallpaperManager.clear();
+        }
+    }
+}
\ No newline at end of file
diff --git a/WallpaperPicker/src/com/android/launcher3/WallpaperCropActivity.java b/WallpaperPicker/src/com/android/launcher3/WallpaperCropActivity.java
index 75bdb8a..364cdb8 100644
--- a/WallpaperPicker/src/com/android/launcher3/WallpaperCropActivity.java
+++ b/WallpaperPicker/src/com/android/launcher3/WallpaperCropActivity.java
@@ -21,6 +21,7 @@
 import android.app.Activity;
 import android.app.WallpaperManager;
 import android.content.Context;
+import android.content.DialogInterface;
 import android.content.Intent;
 import android.content.SharedPreferences;
 import android.content.res.Configuration;
@@ -86,6 +87,18 @@
     @Thunk Set<Bitmap> mReusableBitmaps =
             Collections.newSetFromMap(new WeakHashMap<Bitmap, Boolean>());
 
+    private final DialogInterface.OnCancelListener mOnDialogCancelListener =
+            new DialogInterface.OnCancelListener() {
+                @Override
+                public void onCancel(DialogInterface dialog) {
+                    getActionBar().show();
+                    View wallpaperStrip = findViewById(R.id.wallpaper_strip);
+                    if (wallpaperStrip != null) {
+                        wallpaperStrip.setVisibility(View.VISIBLE);
+                    }
+                }
+            };
+
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
@@ -242,6 +255,10 @@
         }
     }
 
+    public DialogInterface.OnCancelListener getOnDialogCancelListener() {
+        return mOnDialogCancelListener;
+    }
+
     protected void onLoadRequestComplete(LoadRequest req, boolean success) {
         mCurrentLoadRequest = null;
         if (success) {
@@ -326,7 +343,7 @@
         };
         cropTask.setOnEndRunnable(onEndCrop);
         cropTask.setNoCrop(true);
-        cropTask.execute();
+        NycWallpaperUtils.executeCropTaskAfterPrompt(this, cropTask, getOnDialogCancelListener());
     }
 
     protected void cropImageAndSetWallpaper(Resources res, int resId,
@@ -335,8 +352,7 @@
         // this device
         int rotation = BitmapUtils.getRotationFromExif(res, resId);
         Point inSize = mCropView.getSourceDimensions();
-        Point outSize = WallpaperUtils.getDefaultWallpaperSize(getResources(),
-                getWindowManager());
+        Point outSize = WallpaperUtils.getDefaultWallpaperSize(getResources(), getWindowManager());
         RectF crop = Utils.getMaxCropRect(
                 inSize.x, inSize.y, outSize.x, outSize.y, false);
         BitmapCropTask.OnEndCropHandler onEndCrop = new BitmapCropTask.OnEndCropHandler() {
@@ -355,7 +371,7 @@
         };
         BitmapCropTask cropTask = new BitmapCropTask(getContext(), res, resId,
                 crop, rotation, outSize.x, outSize.y, true, false, onEndCrop);
-        cropTask.execute();
+        NycWallpaperUtils.executeCropTaskAfterPrompt(this, cropTask, getOnDialogCancelListener());
     }
 
     @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
diff --git a/WallpaperPicker/src/com/android/launcher3/WallpaperPickerActivity.java b/WallpaperPicker/src/com/android/launcher3/WallpaperPickerActivity.java
index 4998bf4..46e4716 100644
--- a/WallpaperPicker/src/com/android/launcher3/WallpaperPickerActivity.java
+++ b/WallpaperPicker/src/com/android/launcher3/WallpaperPickerActivity.java
@@ -849,7 +849,7 @@
                 (int) rotatedBounds[0], (int) rotatedBounds[1], width, height, leftAligned);
         cropTask.setCropBounds(cropRect);
 
-        if (cropTask.cropBitmap()) {
+        if (cropTask.cropBitmap(NycWallpaperUtils.FLAG_SET_SYSTEM)) {
             return cropTask.getCroppedBitmap();
         } else {
             return null;