Add an option to the long press on image menu to save that image as the home screen wallpaper.

See b/2210111

Change-Id: I911633772358504f0e82fe940f9f2efc4ef403de
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 3d970ab..c5324cd 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -27,6 +27,7 @@
     <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
     <uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT"/>
     <uses-permission android:name="android.permission.INTERNET" />
+    <uses-permission android:name="android.permission.SET_WALLPAPER" />
     <uses-permission android:name="android.permission.WAKE_LOCK"/>
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
     <uses-permission android:name="com.android.browser.permission.READ_HISTORY_BOOKMARKS"/>
diff --git a/res/menu/browsercontext.xml b/res/menu/browsercontext.xml
index 8b2678e..70cf8d4 100644
--- a/res/menu/browsercontext.xml
+++ b/res/menu/browsercontext.xml
@@ -54,6 +54,8 @@
             android:title="@string/contextmenu_download_image"/>
         <item android:id="@+id/view_image_context_menu_id"
             android:title="@string/contextmenu_view_image"/>
+        <item android:id="@+id/set_wallpaper_context_menu_id"
+            android:title="@string/contextmenu_set_wallpaper"/>
     </group>
 </menu>
  
diff --git a/res/values/strings.xml b/res/values/strings.xml
index cc9857a..01f728a 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -266,6 +266,9 @@
     <string name="contextmenu_download_image">Save image</string>
     <!-- Context Menu item to view the image by itself in the browser -->
     <string name="contextmenu_view_image">View image</string>
+    <!-- Context Menu item to set the image as the home screen wallpaper -->
+    <string name="contextmenu_set_wallpaper">Set as wallpaper</string>
+
     <!-- Context Menu item to open the dialer app with the selected phone number
             -->
     <string name="contextmenu_dial_dot">Dial\u2026</string>
@@ -767,6 +770,9 @@
     <!-- Caption for a button that is shown when the zoom widget is showing.  The button's action will switch to the zoom overview mode. -->
     <string name="zoom_overview_button_text">Overview</string>
 
+    <!-- Text in the progress dialog when we are setting an image as the home screen wallpaper. -->
+    <string name="progress_dialog_setting_wallpaper">Setting wallpaper...</string>
+
     <string name="error_console_header_text_minimized" translatable="false">Show JavaScript console</string>
     <string name="error_console_header_text_maximized" translatable="false">JavaScript console</string>
     <string name="error_console_eval_text_hint" translatable="false">Evaluate JavaScript</string>
diff --git a/src/com/android/browser/BrowserActivity.java b/src/com/android/browser/BrowserActivity.java
index c9d5393..7b14528 100644
--- a/src/com/android/browser/BrowserActivity.java
+++ b/src/com/android/browser/BrowserActivity.java
@@ -109,6 +109,8 @@
 
 import java.io.ByteArrayOutputStream;
 import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
 import java.net.MalformedURLException;
 import java.net.URI;
 import java.net.URISyntaxException;
@@ -1681,6 +1683,8 @@
                         new Intent(Intent.ACTION_VIEW, Uri.parse(extra)));
                 menu.findItem(R.id.download_context_menu_id).
                         setOnMenuItemClickListener(new Download(extra));
+                menu.findItem(R.id.set_wallpaper_context_menu_id).
+                        setOnMenuItemClickListener(new SetAsWallpaper(extra));
                 break;
 
             default:
@@ -1826,6 +1830,82 @@
         }
     }
 
+    private class SetAsWallpaper extends Thread implements
+            OnMenuItemClickListener, DialogInterface.OnCancelListener {
+        private URL mUrl;
+        private ProgressDialog mWallpaperProgress;
+        private boolean mCanceled = false;
+
+        public SetAsWallpaper(String url) {
+            try {
+                mUrl = new URL(url);
+            } catch (MalformedURLException e) {
+                mUrl = null;
+            }
+        }
+
+        public void onCancel(DialogInterface dialog) {
+            mCanceled = true;
+        }
+
+        public boolean onMenuItemClick(MenuItem item) {
+            if (mUrl != null) {
+                // The user may have tried to set a image with a large file size as their
+                // background so it may take a few moments to perform the operation. Display
+                // a progress spinner while it is working.
+                mWallpaperProgress = new ProgressDialog(BrowserActivity.this);
+                mWallpaperProgress.setIndeterminate(true);
+                mWallpaperProgress.setMessage(getText(R.string.progress_dialog_setting_wallpaper));
+                mWallpaperProgress.setCancelable(true);
+                mWallpaperProgress.setOnCancelListener(this);
+                mWallpaperProgress.show();
+                start();
+            }
+            return true;
+        }
+
+        public void run() {
+            Drawable oldWallpaper = BrowserActivity.this.getWallpaper();
+            try {
+                // TODO: This will cause the resource to be downloaded again, when we
+                // should in most cases be able to grab it from the cache. To fix this
+                // we should query WebCore to see if we can access a cached version and
+                // instead open an input stream on that. This pattern could also be used
+                // in the download manager where the same problem exists.
+                InputStream inputstream = mUrl.openStream();
+                if (inputstream != null) {
+                    setWallpaper(inputstream);
+                }
+            } catch (IOException e) {
+                Log.e(LOGTAG, "Unable to set new wallpaper");
+                // Act as though the user canceled the operation so we try to
+                // restore the old wallpaper.
+                mCanceled = true;
+            }
+
+            if (mCanceled) {
+                // Restore the old wallpaper if the user cancelled whilst we were setting
+                // the new wallpaper.
+                int width = oldWallpaper.getIntrinsicWidth();
+                int height = oldWallpaper.getIntrinsicHeight();
+                Bitmap bm = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
+                Canvas canvas = new Canvas(bm);
+                oldWallpaper.setBounds(0, 0, width, height);
+                oldWallpaper.draw(canvas);
+                try {
+                    setWallpaper(bm);
+                } catch (IOException e) {
+                    Log.e(LOGTAG, "Unable to restore old wallpaper.");
+                }
+                mCanceled = false;
+            }
+
+            if (mWallpaperProgress.isShowing()) {
+                mWallpaperProgress.dismiss();
+            }
+        }
+    }
+
     private void copy(CharSequence text) {
         try {
             IClipboard clip = IClipboard.Stub.asInterface(ServiceManager.getService("clipboard"));