blob: 2cb223a6e762b0d31cc2e080a6fc5023052a2391 [file] [log] [blame]
John Reck3527dd12011-02-22 10:35:29 -08001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.browser;
18
19import android.app.ProgressDialog;
20import android.app.WallpaperManager;
21import android.content.Context;
22import android.content.DialogInterface;
23import android.graphics.Bitmap;
Ben Murdochb860a622011-02-21 18:40:02 +000024import android.graphics.BitmapFactory;
John Reck3527dd12011-02-22 10:35:29 -080025import android.graphics.Canvas;
26import android.graphics.drawable.Drawable;
27import android.util.Log;
28import android.view.MenuItem;
29import android.view.MenuItem.OnMenuItemClickListener;
30
Ben Murdochb860a622011-02-21 18:40:02 +000031import java.io.BufferedInputStream;
John Reck3527dd12011-02-22 10:35:29 -080032import java.io.IOException;
33import java.io.InputStream;
34import java.net.MalformedURLException;
35import java.net.URL;
36
37/**
38 * Handle setWallpaper requests
39 *
40 */
41public class WallpaperHandler extends Thread
42 implements OnMenuItemClickListener, DialogInterface.OnCancelListener {
43
44
45 private static final String LOGTAG = "WallpaperHandler";
Ben Murdochb860a622011-02-21 18:40:02 +000046 // This should be large enough for BitmapFactory to decode the header so
47 // that we can mark and reset the input stream to avoid duplicate network i/o
48 private static final int BUFFER_SIZE = 128 * 1024;
John Reck3527dd12011-02-22 10:35:29 -080049
50 private Context mContext;
51 private URL mUrl;
52 private ProgressDialog mWallpaperProgress;
53 private boolean mCanceled = false;
54
55 public WallpaperHandler(Context context, String url) {
56 mContext = context;
57 try {
58 mUrl = new URL(url);
59 } catch (MalformedURLException e) {
60 mUrl = null;
61 }
62 }
63
64 @Override
65 public void onCancel(DialogInterface dialog) {
66 mCanceled = true;
67 }
68
69 @Override
70 public boolean onMenuItemClick(MenuItem item) {
71 if (mUrl != null) {
72 // The user may have tried to set a image with a large file size as
73 // their background so it may take a few moments to perform the
74 // operation.
75 // Display a progress spinner while it is working.
76 mWallpaperProgress = new ProgressDialog(mContext);
77 mWallpaperProgress.setIndeterminate(true);
78 mWallpaperProgress.setMessage(mContext.getResources()
79 .getText(R.string.progress_dialog_setting_wallpaper));
80 mWallpaperProgress.setCancelable(true);
81 mWallpaperProgress.setOnCancelListener(this);
82 mWallpaperProgress.show();
83 start();
84 }
85 return true;
86 }
87
88 @Override
89 public void run() {
Ben Murdochb860a622011-02-21 18:40:02 +000090 WallpaperManager wm = WallpaperManager.getInstance(mContext);
91 Drawable oldWallpaper = wm.getDrawable();
92 InputStream inputstream = null;
John Reck3527dd12011-02-22 10:35:29 -080093 try {
94 // TODO: This will cause the resource to be downloaded again, when
95 // we should in most cases be able to grab it from the cache. To fix
96 // this we should query WebCore to see if we can access a cached
97 // version and instead open an input stream on that. This pattern
98 // could also be used in the download manager where the same problem
99 // exists.
Ben Murdochb860a622011-02-21 18:40:02 +0000100 inputstream = mUrl.openStream();
John Reck3527dd12011-02-22 10:35:29 -0800101 if (inputstream != null) {
Ben Murdochb860a622011-02-21 18:40:02 +0000102 if (!inputstream.markSupported()) {
103 inputstream = new BufferedInputStream(inputstream, BUFFER_SIZE);
104 }
105 inputstream.mark(BUFFER_SIZE);
106 BitmapFactory.Options options = new BitmapFactory.Options();
107 options.inJustDecodeBounds = true;
108 // We give decodeStream a wrapped input stream so it doesn't
109 // mess with our mark (currently it sets a mark of 1024)
110 BitmapFactory.decodeStream(
111 new BufferedInputStream(inputstream), null, options);
112 int maxWidth = wm.getDesiredMinimumWidth();
113 int maxHeight = wm.getDesiredMinimumHeight();
114 // Give maxWidth and maxHeight some leeway
115 maxWidth *= 1.25;
116 maxHeight *= 1.25;
117 int bmWidth = options.outWidth;
118 int bmHeight = options.outHeight;
119
120 int scale = 1;
121 while (bmWidth > maxWidth || bmHeight > maxWidth) {
122 scale <<= 1;
123 bmWidth >>= 1;
124 bmHeight >>= 1;
125 }
126 options.inJustDecodeBounds = false;
127 options.inSampleSize = scale;
128 try {
129 inputstream.reset();
130 } catch (IOException e) {
131 // BitmapFactory read more than we could buffer
132 // Re-open the stream
133 inputstream.close();
134 inputstream = mUrl.openStream();
135 }
136 Bitmap scaledWallpaper = BitmapFactory.decodeStream(inputstream,
137 null, options);
138 wm.setBitmap(scaledWallpaper);
John Reck3527dd12011-02-22 10:35:29 -0800139 }
140 } catch (IOException e) {
141 Log.e(LOGTAG, "Unable to set new wallpaper");
142 // Act as though the user canceled the operation so we try to
143 // restore the old wallpaper.
144 mCanceled = true;
Ben Murdochb860a622011-02-21 18:40:02 +0000145 } finally {
146 if (inputstream != null) {
147 try {
148 inputstream.close();
149 } catch (IOException e) {
150 // Ignore
151 }
152 }
John Reck3527dd12011-02-22 10:35:29 -0800153 }
154
155 if (mCanceled) {
156 // Restore the old wallpaper if the user cancelled whilst we were
157 // setting
158 // the new wallpaper.
159 int width = oldWallpaper.getIntrinsicWidth();
160 int height = oldWallpaper.getIntrinsicHeight();
161 Bitmap bm = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
162 Canvas canvas = new Canvas(bm);
163 oldWallpaper.setBounds(0, 0, width, height);
164 oldWallpaper.draw(canvas);
165 try {
Ben Murdochb860a622011-02-21 18:40:02 +0000166 wm.setBitmap(bm);
John Reck3527dd12011-02-22 10:35:29 -0800167 } catch (IOException e) {
168 Log.e(LOGTAG, "Unable to restore old wallpaper.");
169 }
170 mCanceled = false;
171 }
172
173 if (mWallpaperProgress.isShowing()) {
174 mWallpaperProgress.dismiss();
175 }
176 }
177}