WallpaperCropActivity.java revision 2a218b718e5f498a284341532178c84fe3850e63
1f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka/* 2f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka * Copyright (C) 2013 The Android Open Source Project 3f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka * 4f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka * Licensed under the Apache License, Version 2.0 (the "License"); 5f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka * you may not use this file except in compliance with the License. 6f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka * You may obtain a copy of the License at 7f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka * 8f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka * http://www.apache.org/licenses/LICENSE-2.0 9f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka * 10f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka * Unless required by applicable law or agreed to in writing, software 11f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka * distributed under the License is distributed on an "AS IS" BASIS, 12f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka * See the License for the specific language governing permissions and 14f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka * limitations under the License. 15f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka */ 16f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka 17f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurkapackage com.android.launcher3; 18f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka 19f10a4ed72d6b554bd8d9b44465845245fa1235f6Sunny Goyalimport android.annotation.TargetApi; 20f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurkaimport android.app.ActionBar; 21f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurkaimport android.app.Activity; 22f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurkaimport android.app.WallpaperManager; 23f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurkaimport android.content.Context; 24f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurkaimport android.content.Intent; 25f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurkaimport android.content.SharedPreferences; 26f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurkaimport android.content.res.Configuration; 27f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurkaimport android.content.res.Resources; 282a218b718e5f498a284341532178c84fe3850e63Sunny Goyalimport android.graphics.Bitmap; 29f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurkaimport android.graphics.Matrix; 30f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurkaimport android.graphics.Point; 31f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurkaimport android.graphics.RectF; 32f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurkaimport android.net.Uri; 33f10a4ed72d6b554bd8d9b44465845245fa1235f6Sunny Goyalimport android.os.Build; 34f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurkaimport android.os.Bundle; 352a218b718e5f498a284341532178c84fe3850e63Sunny Goyalimport android.os.Handler; 362a218b718e5f498a284341532178c84fe3850e63Sunny Goyalimport android.os.HandlerThread; 372a218b718e5f498a284341532178c84fe3850e63Sunny Goyalimport android.os.Message; 38f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurkaimport android.util.Log; 39f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurkaimport android.view.Display; 40f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurkaimport android.view.View; 41f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurkaimport android.view.WindowManager; 42f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurkaimport android.widget.Toast; 432a218b718e5f498a284341532178c84fe3850e63Sunny Goyal 44f10a4ed72d6b554bd8d9b44465845245fa1235f6Sunny Goyalimport com.android.gallery3d.common.BitmapCropTask; 45f10a4ed72d6b554bd8d9b44465845245fa1235f6Sunny Goyalimport com.android.gallery3d.common.BitmapUtils; 46f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurkaimport com.android.gallery3d.common.Utils; 47f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurkaimport com.android.photos.BitmapRegionTileSource; 48f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurkaimport com.android.photos.BitmapRegionTileSource.BitmapSource; 492a218b718e5f498a284341532178c84fe3850e63Sunny Goyalimport com.android.photos.BitmapRegionTileSource.BitmapSource.InBitmapProvider; 502a218b718e5f498a284341532178c84fe3850e63Sunny Goyalimport com.android.photos.views.TiledImageRenderer.TileSource; 512a218b718e5f498a284341532178c84fe3850e63Sunny Goyal 522a218b718e5f498a284341532178c84fe3850e63Sunny Goyalimport java.util.Collections; 532a218b718e5f498a284341532178c84fe3850e63Sunny Goyalimport java.util.Iterator; 542a218b718e5f498a284341532178c84fe3850e63Sunny Goyalimport java.util.Set; 552a218b718e5f498a284341532178c84fe3850e63Sunny Goyalimport java.util.WeakHashMap; 56f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka 572a218b718e5f498a284341532178c84fe3850e63Sunny Goyalpublic class WallpaperCropActivity extends Activity implements Handler.Callback { 58f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka private static final String LOGTAG = "Launcher3.CropActivity"; 59f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka 60f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka protected static final String WALLPAPER_WIDTH_KEY = "wallpaper.width"; 61f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka protected static final String WALLPAPER_HEIGHT_KEY = "wallpaper.height"; 62f10a4ed72d6b554bd8d9b44465845245fa1235f6Sunny Goyal 63f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka /** 64f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka * The maximum bitmap size we allow to be returned through the intent. 65f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka * Intents have a maximum of 1MB in total size. However, the Bitmap seems to 66f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka * have some overhead to hit so that we go way below the limit here to make 67f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka * sure the intent stays below 1MB.We should consider just returning a byte 68f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka * array instead of a Bitmap instance to avoid overhead. 69f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka */ 70f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka public static final int MAX_BMAP_IN_INTENT = 750000; 71f10a4ed72d6b554bd8d9b44465845245fa1235f6Sunny Goyal public static final float WALLPAPER_SCREENS_SPAN = 2f; 72f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka 732a218b718e5f498a284341532178c84fe3850e63Sunny Goyal private static final int MSG_LOAD_IMAGE = 1; 742a218b718e5f498a284341532178c84fe3850e63Sunny Goyal 75f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka protected CropView mCropView; 762a218b718e5f498a284341532178c84fe3850e63Sunny Goyal protected View mProgressView; 77f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka protected Uri mUri; 7812d9d42afb5bd750ab52e38cd66f6081f4bd76bfSelim Cinek protected View mSetWallpaperButton; 79f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka 802a218b718e5f498a284341532178c84fe3850e63Sunny Goyal private HandlerThread mLoaderThread; 812a218b718e5f498a284341532178c84fe3850e63Sunny Goyal private Handler mLoaderHandler; 822a218b718e5f498a284341532178c84fe3850e63Sunny Goyal private LoadRequest mCurrentLoadRequest; 832a218b718e5f498a284341532178c84fe3850e63Sunny Goyal private byte[] mTempStorageForDecoding = new byte[16 * 1024]; 842a218b718e5f498a284341532178c84fe3850e63Sunny Goyal // A weak-set of reusable bitmaps 852a218b718e5f498a284341532178c84fe3850e63Sunny Goyal private Set<Bitmap> mReusableBitmaps = 862a218b718e5f498a284341532178c84fe3850e63Sunny Goyal Collections.newSetFromMap(new WeakHashMap<Bitmap, Boolean>()); 872a218b718e5f498a284341532178c84fe3850e63Sunny Goyal 88f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka @Override 89f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka protected void onCreate(Bundle savedInstanceState) { 90f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka super.onCreate(savedInstanceState); 912a218b718e5f498a284341532178c84fe3850e63Sunny Goyal 922a218b718e5f498a284341532178c84fe3850e63Sunny Goyal mLoaderThread = new HandlerThread("wallpaper_loader"); 932a218b718e5f498a284341532178c84fe3850e63Sunny Goyal mLoaderThread.start(); 942a218b718e5f498a284341532178c84fe3850e63Sunny Goyal mLoaderHandler = new Handler(mLoaderThread.getLooper(), this); 952a218b718e5f498a284341532178c84fe3850e63Sunny Goyal 96f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka init(); 97f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka if (!enableRotation()) { 98f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka setRequestedOrientation(Configuration.ORIENTATION_PORTRAIT); 99f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka } 100f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka } 101f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka 102f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka protected void init() { 103f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka setContentView(R.layout.wallpaper_cropper); 104f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka 105f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka mCropView = (CropView) findViewById(R.id.cropView); 1062a218b718e5f498a284341532178c84fe3850e63Sunny Goyal mProgressView = findViewById(R.id.loading); 107f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka 108f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka Intent cropIntent = getIntent(); 109f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka final Uri imageUri = cropIntent.getData(); 110f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka 111f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka if (imageUri == null) { 112f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka Log.e(LOGTAG, "No URI passed in intent, exiting WallpaperCropActivity"); 113f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka finish(); 114f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka return; 115f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka } 116f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka 117f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka // Action bar 118f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka // Show the custom action bar view 119f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka final ActionBar actionBar = getActionBar(); 120f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka actionBar.setCustomView(R.layout.actionbar_set_wallpaper); 121f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka actionBar.getCustomView().setOnClickListener( 122f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka new View.OnClickListener() { 123f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka @Override 124f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka public void onClick(View v) { 125f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka boolean finishActivityWhenDone = true; 126f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka cropImageAndSetWallpaper(imageUri, null, finishActivityWhenDone); 127f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka } 128f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka }); 129c192530433ab03c02462635e9ffbe3781b666e13Michael Jurka mSetWallpaperButton = findViewById(R.id.set_wallpaper_button); 130f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka 131f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka // Load image in background 132f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka final BitmapRegionTileSource.UriBitmapSource bitmapSource = 133f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka new BitmapRegionTileSource.UriBitmapSource(this, imageUri, 1024); 13412d9d42afb5bd750ab52e38cd66f6081f4bd76bfSelim Cinek mSetWallpaperButton.setEnabled(false); 135f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka Runnable onLoad = new Runnable() { 136f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka public void run() { 137f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka if (bitmapSource.getLoadingState() != BitmapSource.State.LOADED) { 138f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka Toast.makeText(WallpaperCropActivity.this, 139f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka getString(R.string.wallpaper_load_fail), 140f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka Toast.LENGTH_LONG).show(); 141f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka finish(); 142c192530433ab03c02462635e9ffbe3781b666e13Michael Jurka } else { 14312d9d42afb5bd750ab52e38cd66f6081f4bd76bfSelim Cinek mSetWallpaperButton.setEnabled(true); 144f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka } 145f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka } 146f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka }; 1472a218b718e5f498a284341532178c84fe3850e63Sunny Goyal setCropViewTileSource(bitmapSource, true, false, null, onLoad); 148f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka } 149f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka 1501019588c3cbc255dc523161950adc22483777291Sunny Goyal @Override 1511019588c3cbc255dc523161950adc22483777291Sunny Goyal protected void onDestroy() { 1521019588c3cbc255dc523161950adc22483777291Sunny Goyal if (mCropView != null) { 1531019588c3cbc255dc523161950adc22483777291Sunny Goyal mCropView.destroy(); 1541019588c3cbc255dc523161950adc22483777291Sunny Goyal } 1552a218b718e5f498a284341532178c84fe3850e63Sunny Goyal if (mLoaderThread != null) { 1562a218b718e5f498a284341532178c84fe3850e63Sunny Goyal mLoaderThread.quit(); 1572a218b718e5f498a284341532178c84fe3850e63Sunny Goyal } 1581019588c3cbc255dc523161950adc22483777291Sunny Goyal super.onDestroy(); 1591019588c3cbc255dc523161950adc22483777291Sunny Goyal } 1601019588c3cbc255dc523161950adc22483777291Sunny Goyal 1612a218b718e5f498a284341532178c84fe3850e63Sunny Goyal /** 1622a218b718e5f498a284341532178c84fe3850e63Sunny Goyal * This is called on {@link #mLoaderThread} 1632a218b718e5f498a284341532178c84fe3850e63Sunny Goyal */ 1642a218b718e5f498a284341532178c84fe3850e63Sunny Goyal @Override 1652a218b718e5f498a284341532178c84fe3850e63Sunny Goyal public boolean handleMessage(Message msg) { 1662a218b718e5f498a284341532178c84fe3850e63Sunny Goyal if (msg.what == MSG_LOAD_IMAGE) { 1672a218b718e5f498a284341532178c84fe3850e63Sunny Goyal final LoadRequest req = (LoadRequest) msg.obj; 1682a218b718e5f498a284341532178c84fe3850e63Sunny Goyal try { 1692a218b718e5f498a284341532178c84fe3850e63Sunny Goyal req.src.loadInBackground(new InBitmapProvider() { 1702a218b718e5f498a284341532178c84fe3850e63Sunny Goyal 1712a218b718e5f498a284341532178c84fe3850e63Sunny Goyal @Override 1722a218b718e5f498a284341532178c84fe3850e63Sunny Goyal public Bitmap forPixelCount(int count) { 1732a218b718e5f498a284341532178c84fe3850e63Sunny Goyal synchronized (mReusableBitmaps) { 1742a218b718e5f498a284341532178c84fe3850e63Sunny Goyal Iterator<Bitmap> itr = mReusableBitmaps.iterator(); 1752a218b718e5f498a284341532178c84fe3850e63Sunny Goyal while (itr.hasNext()) { 1762a218b718e5f498a284341532178c84fe3850e63Sunny Goyal Bitmap b = itr.next(); 1772a218b718e5f498a284341532178c84fe3850e63Sunny Goyal if (b.getWidth() * b.getHeight() >= count) { 1782a218b718e5f498a284341532178c84fe3850e63Sunny Goyal itr.remove(); 1792a218b718e5f498a284341532178c84fe3850e63Sunny Goyal return b; 1802a218b718e5f498a284341532178c84fe3850e63Sunny Goyal } 1812a218b718e5f498a284341532178c84fe3850e63Sunny Goyal } 182d444a550ec1c8992fbac0a036b293fc4759d25c1Selim Cinek } 1832a218b718e5f498a284341532178c84fe3850e63Sunny Goyal return null; 184d444a550ec1c8992fbac0a036b293fc4759d25c1Selim Cinek } 1852a218b718e5f498a284341532178c84fe3850e63Sunny Goyal }); 1862a218b718e5f498a284341532178c84fe3850e63Sunny Goyal } catch (SecurityException securityException) { 1872a218b718e5f498a284341532178c84fe3850e63Sunny Goyal if (isDestroyed()) { 1882a218b718e5f498a284341532178c84fe3850e63Sunny Goyal // Temporarily granted permissions are revoked when the activity 1892a218b718e5f498a284341532178c84fe3850e63Sunny Goyal // finishes, potentially resulting in a SecurityException here. 1902a218b718e5f498a284341532178c84fe3850e63Sunny Goyal // Even though {@link #isDestroyed} might also return true in different 1912a218b718e5f498a284341532178c84fe3850e63Sunny Goyal // situations where the configuration changes, we are fine with 1922a218b718e5f498a284341532178c84fe3850e63Sunny Goyal // catching these cases here as well. 1932a218b718e5f498a284341532178c84fe3850e63Sunny Goyal return true; 1942a218b718e5f498a284341532178c84fe3850e63Sunny Goyal } else { 1952a218b718e5f498a284341532178c84fe3850e63Sunny Goyal // otherwise it had a different cause and we throw it further 1962a218b718e5f498a284341532178c84fe3850e63Sunny Goyal throw securityException; 197f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka } 198f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka } 1992a218b718e5f498a284341532178c84fe3850e63Sunny Goyal 2002a218b718e5f498a284341532178c84fe3850e63Sunny Goyal req.result = new BitmapRegionTileSource(this, req.src, mTempStorageForDecoding); 2012a218b718e5f498a284341532178c84fe3850e63Sunny Goyal runOnUiThread(new Runnable() { 2022a218b718e5f498a284341532178c84fe3850e63Sunny Goyal 2032a218b718e5f498a284341532178c84fe3850e63Sunny Goyal @Override 2042a218b718e5f498a284341532178c84fe3850e63Sunny Goyal public void run() { 2052a218b718e5f498a284341532178c84fe3850e63Sunny Goyal if (req == mCurrentLoadRequest) { 2062a218b718e5f498a284341532178c84fe3850e63Sunny Goyal onLoadRequestComplete(req, 2072a218b718e5f498a284341532178c84fe3850e63Sunny Goyal req.src.getLoadingState() == BitmapSource.State.LOADED); 2082a218b718e5f498a284341532178c84fe3850e63Sunny Goyal } else { 2092a218b718e5f498a284341532178c84fe3850e63Sunny Goyal addReusableBitmap(req.result); 210f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka } 211f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka } 2122a218b718e5f498a284341532178c84fe3850e63Sunny Goyal }); 2132a218b718e5f498a284341532178c84fe3850e63Sunny Goyal return true; 2142a218b718e5f498a284341532178c84fe3850e63Sunny Goyal } 2152a218b718e5f498a284341532178c84fe3850e63Sunny Goyal return false; 2162a218b718e5f498a284341532178c84fe3850e63Sunny Goyal } 2172a218b718e5f498a284341532178c84fe3850e63Sunny Goyal 2182a218b718e5f498a284341532178c84fe3850e63Sunny Goyal private void addReusableBitmap(TileSource src) { 2192a218b718e5f498a284341532178c84fe3850e63Sunny Goyal synchronized (mReusableBitmaps) { 2202a218b718e5f498a284341532178c84fe3850e63Sunny Goyal if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT 2212a218b718e5f498a284341532178c84fe3850e63Sunny Goyal && src instanceof BitmapRegionTileSource) { 2222a218b718e5f498a284341532178c84fe3850e63Sunny Goyal Bitmap preview = ((BitmapRegionTileSource) src).getBitmap(); 2232a218b718e5f498a284341532178c84fe3850e63Sunny Goyal if (preview != null && preview.isMutable()) { 2242a218b718e5f498a284341532178c84fe3850e63Sunny Goyal mReusableBitmaps.add(preview); 225f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka } 226f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka } 2272a218b718e5f498a284341532178c84fe3850e63Sunny Goyal } 2282a218b718e5f498a284341532178c84fe3850e63Sunny Goyal } 2292a218b718e5f498a284341532178c84fe3850e63Sunny Goyal 2302a218b718e5f498a284341532178c84fe3850e63Sunny Goyal protected void onLoadRequestComplete(LoadRequest req, boolean success) { 2312a218b718e5f498a284341532178c84fe3850e63Sunny Goyal mCurrentLoadRequest = null; 2322a218b718e5f498a284341532178c84fe3850e63Sunny Goyal if (success) { 2332a218b718e5f498a284341532178c84fe3850e63Sunny Goyal TileSource oldSrc = mCropView.getTileSource(); 2342a218b718e5f498a284341532178c84fe3850e63Sunny Goyal mCropView.setTileSource(req.result, null); 2352a218b718e5f498a284341532178c84fe3850e63Sunny Goyal mCropView.setTouchEnabled(req.touchEnabled); 2362a218b718e5f498a284341532178c84fe3850e63Sunny Goyal if (req.moveToLeft) { 2372a218b718e5f498a284341532178c84fe3850e63Sunny Goyal mCropView.moveToLeft(); 2382a218b718e5f498a284341532178c84fe3850e63Sunny Goyal } 2392a218b718e5f498a284341532178c84fe3850e63Sunny Goyal if (req.scaleProvider != null) { 2402a218b718e5f498a284341532178c84fe3850e63Sunny Goyal mCropView.setScale(req.scaleProvider.getScale(req.result)); 2412a218b718e5f498a284341532178c84fe3850e63Sunny Goyal } 2422a218b718e5f498a284341532178c84fe3850e63Sunny Goyal 2432a218b718e5f498a284341532178c84fe3850e63Sunny Goyal // Free last image 2442a218b718e5f498a284341532178c84fe3850e63Sunny Goyal if (oldSrc != null) { 2452a218b718e5f498a284341532178c84fe3850e63Sunny Goyal // Call yield instead of recycle, as we only want to free GL resource. 2462a218b718e5f498a284341532178c84fe3850e63Sunny Goyal // We can still reuse the bitmap for decoding any other image. 2472a218b718e5f498a284341532178c84fe3850e63Sunny Goyal oldSrc.getPreview().yield(); 2482a218b718e5f498a284341532178c84fe3850e63Sunny Goyal } 2492a218b718e5f498a284341532178c84fe3850e63Sunny Goyal addReusableBitmap(oldSrc); 2502a218b718e5f498a284341532178c84fe3850e63Sunny Goyal } 2512a218b718e5f498a284341532178c84fe3850e63Sunny Goyal if (req.postExecute != null) { 2522a218b718e5f498a284341532178c84fe3850e63Sunny Goyal req.postExecute.run(); 2532a218b718e5f498a284341532178c84fe3850e63Sunny Goyal } 2542a218b718e5f498a284341532178c84fe3850e63Sunny Goyal } 2552a218b718e5f498a284341532178c84fe3850e63Sunny Goyal 2562a218b718e5f498a284341532178c84fe3850e63Sunny Goyal public final void setCropViewTileSource(BitmapSource bitmapSource, boolean touchEnabled, 2572a218b718e5f498a284341532178c84fe3850e63Sunny Goyal boolean moveToLeft, CropViewScaleProvider scaleProvider, Runnable postExecute) { 2582a218b718e5f498a284341532178c84fe3850e63Sunny Goyal final LoadRequest req = new LoadRequest(); 2592a218b718e5f498a284341532178c84fe3850e63Sunny Goyal req.moveToLeft = moveToLeft; 2602a218b718e5f498a284341532178c84fe3850e63Sunny Goyal req.src = bitmapSource; 2612a218b718e5f498a284341532178c84fe3850e63Sunny Goyal req.touchEnabled = touchEnabled; 2622a218b718e5f498a284341532178c84fe3850e63Sunny Goyal req.postExecute = postExecute; 2632a218b718e5f498a284341532178c84fe3850e63Sunny Goyal req.scaleProvider = scaleProvider; 2642a218b718e5f498a284341532178c84fe3850e63Sunny Goyal mCurrentLoadRequest = req; 2652a218b718e5f498a284341532178c84fe3850e63Sunny Goyal 2662a218b718e5f498a284341532178c84fe3850e63Sunny Goyal // Remove any pending requests 2672a218b718e5f498a284341532178c84fe3850e63Sunny Goyal mLoaderHandler.removeMessages(MSG_LOAD_IMAGE); 2682a218b718e5f498a284341532178c84fe3850e63Sunny Goyal Message.obtain(mLoaderHandler, MSG_LOAD_IMAGE, req).sendToTarget(); 2692a218b718e5f498a284341532178c84fe3850e63Sunny Goyal 270f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka // We don't want to show the spinner every time we load an image, because that would be 271f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka // annoying; instead, only start showing the spinner if loading the image has taken 272f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka // longer than 1 sec (ie 1000 ms) 2732a218b718e5f498a284341532178c84fe3850e63Sunny Goyal mProgressView.postDelayed(new Runnable() { 274f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka public void run() { 2752a218b718e5f498a284341532178c84fe3850e63Sunny Goyal if (mCurrentLoadRequest == req) { 2762a218b718e5f498a284341532178c84fe3850e63Sunny Goyal mProgressView.setVisibility(View.VISIBLE); 277f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka } 278f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka } 279f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka }, 1000); 280f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka } 281f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka 2822a218b718e5f498a284341532178c84fe3850e63Sunny Goyal 283f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka public boolean enableRotation() { 284f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka return getResources().getBoolean(R.bool.allow_rotation); 285f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka } 286f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka 287f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka public static String getSharedPreferencesKey() { 2888f82fb850ed00ceb769822dce56cce63fb33f291Helena Josol return LauncherFiles.WALLPAPER_CROP_PREFERENCES_KEY; 289f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka } 290f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka 291723f3b60d150ebda26849bc57493bfc7afc43cc7Sunny Goyal protected void setWallpaper(Uri uri, final boolean finishActivityWhenDone) { 292f10a4ed72d6b554bd8d9b44465845245fa1235f6Sunny Goyal int rotation = BitmapUtils.getRotationFromExif(this, uri); 293f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka BitmapCropTask cropTask = new BitmapCropTask( 294723f3b60d150ebda26849bc57493bfc7afc43cc7Sunny Goyal this, uri, null, rotation, 0, 0, true, false, null); 295f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka final Point bounds = cropTask.getImageBounds(); 296f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka Runnable onEndCrop = new Runnable() { 297f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka public void run() { 298f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka updateWallpaperDimensions(bounds.x, bounds.y); 299f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka if (finishActivityWhenDone) { 300f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka setResult(Activity.RESULT_OK); 301f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka finish(); 302f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka } 303f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka } 304f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka }; 305f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka cropTask.setOnEndRunnable(onEndCrop); 306f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka cropTask.setNoCrop(true); 307f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka cropTask.execute(); 308f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka } 309f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka 310f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka protected void cropImageAndSetWallpaper( 311f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka Resources res, int resId, final boolean finishActivityWhenDone) { 312f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka // crop this image and scale it down to the default wallpaper size for 313f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka // this device 314f10a4ed72d6b554bd8d9b44465845245fa1235f6Sunny Goyal int rotation = BitmapUtils.getRotationFromExif(res, resId); 315f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka Point inSize = mCropView.getSourceDimensions(); 316f10a4ed72d6b554bd8d9b44465845245fa1235f6Sunny Goyal Point outSize = BitmapUtils.getDefaultWallpaperSize(getResources(), 317f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka getWindowManager()); 318f10a4ed72d6b554bd8d9b44465845245fa1235f6Sunny Goyal RectF crop = Utils.getMaxCropRect( 319f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka inSize.x, inSize.y, outSize.x, outSize.y, false); 320f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka Runnable onEndCrop = new Runnable() { 321f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka public void run() { 322f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka // Passing 0, 0 will cause launcher to revert to using the 323f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka // default wallpaper size 324f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka updateWallpaperDimensions(0, 0); 325f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka if (finishActivityWhenDone) { 326f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka setResult(Activity.RESULT_OK); 327f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka finish(); 328f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka } 329f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka } 330f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka }; 331f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka BitmapCropTask cropTask = new BitmapCropTask(this, res, resId, 332f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka crop, rotation, outSize.x, outSize.y, true, false, onEndCrop); 333f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka cropTask.execute(); 334f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka } 335f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka 336f10a4ed72d6b554bd8d9b44465845245fa1235f6Sunny Goyal @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) 337f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka protected void cropImageAndSetWallpaper(Uri uri, 338f10a4ed72d6b554bd8d9b44465845245fa1235f6Sunny Goyal BitmapCropTask.OnBitmapCroppedHandler onBitmapCroppedHandler, final boolean finishActivityWhenDone) { 339942b9eefdc1a918ccc259a54bc61cb7fbfb03bfdMichael Jurka boolean centerCrop = getResources().getBoolean(R.bool.center_crop); 340f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka // Get the crop 341f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka boolean ltr = mCropView.getLayoutDirection() == View.LAYOUT_DIRECTION_LTR; 342f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka 343f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka Display d = getWindowManager().getDefaultDisplay(); 344f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka 345f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka Point displaySize = new Point(); 346f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka d.getSize(displaySize); 347f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka boolean isPortrait = displaySize.x < displaySize.y; 348f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka 349f10a4ed72d6b554bd8d9b44465845245fa1235f6Sunny Goyal Point defaultWallpaperSize = BitmapUtils.getDefaultWallpaperSize(getResources(), 350f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka getWindowManager()); 351f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka // Get the crop 352f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka RectF cropRect = mCropView.getCrop(); 353b24af13c8359963ecdea420a1b395149e7477f83Selim Cinek 354500dfeb109f614fd42e2cc383c5dcfecaa981b38Selim Cinek Point inSize = mCropView.getSourceDimensions(); 355500dfeb109f614fd42e2cc383c5dcfecaa981b38Selim Cinek 356f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka int cropRotation = mCropView.getImageRotation(); 357f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka float cropScale = mCropView.getWidth() / (float) cropRect.width(); 358f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka 359500dfeb109f614fd42e2cc383c5dcfecaa981b38Selim Cinek 360f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka Matrix rotateMatrix = new Matrix(); 361f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka rotateMatrix.setRotate(cropRotation); 362f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka float[] rotatedInSize = new float[] { inSize.x, inSize.y }; 363f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka rotateMatrix.mapPoints(rotatedInSize); 364f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka rotatedInSize[0] = Math.abs(rotatedInSize[0]); 365f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka rotatedInSize[1] = Math.abs(rotatedInSize[1]); 366f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka 3671116efa8af024cb9fcae059c16e23caea984729fSelim Cinek 3681116efa8af024cb9fcae059c16e23caea984729fSelim Cinek // due to rounding errors in the cropview renderer the edges can be slightly offset 3691116efa8af024cb9fcae059c16e23caea984729fSelim Cinek // therefore we ensure that the boundaries are sanely defined 3701116efa8af024cb9fcae059c16e23caea984729fSelim Cinek cropRect.left = Math.max(0, cropRect.left); 3711116efa8af024cb9fcae059c16e23caea984729fSelim Cinek cropRect.right = Math.min(rotatedInSize[0], cropRect.right); 3721116efa8af024cb9fcae059c16e23caea984729fSelim Cinek cropRect.top = Math.max(0, cropRect.top); 3731116efa8af024cb9fcae059c16e23caea984729fSelim Cinek cropRect.bottom = Math.min(rotatedInSize[1], cropRect.bottom); 3741116efa8af024cb9fcae059c16e23caea984729fSelim Cinek 375f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka // ADJUST CROP WIDTH 376f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka // Extend the crop all the way to the right, for parallax 377f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka // (or all the way to the left, in RTL) 378942b9eefdc1a918ccc259a54bc61cb7fbfb03bfdMichael Jurka float extraSpace; 379942b9eefdc1a918ccc259a54bc61cb7fbfb03bfdMichael Jurka if (centerCrop) { 380942b9eefdc1a918ccc259a54bc61cb7fbfb03bfdMichael Jurka extraSpace = 2f * Math.min(rotatedInSize[0] - cropRect.right, cropRect.left); 381942b9eefdc1a918ccc259a54bc61cb7fbfb03bfdMichael Jurka } else { 382942b9eefdc1a918ccc259a54bc61cb7fbfb03bfdMichael Jurka extraSpace = ltr ? rotatedInSize[0] - cropRect.right : cropRect.left; 383942b9eefdc1a918ccc259a54bc61cb7fbfb03bfdMichael Jurka } 384f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka // Cap the amount of extra width 385f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka float maxExtraSpace = defaultWallpaperSize.x / cropScale - cropRect.width(); 386f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka extraSpace = Math.min(extraSpace, maxExtraSpace); 387f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka 388942b9eefdc1a918ccc259a54bc61cb7fbfb03bfdMichael Jurka if (centerCrop) { 389942b9eefdc1a918ccc259a54bc61cb7fbfb03bfdMichael Jurka cropRect.left -= extraSpace / 2f; 390942b9eefdc1a918ccc259a54bc61cb7fbfb03bfdMichael Jurka cropRect.right += extraSpace / 2f; 391f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka } else { 392942b9eefdc1a918ccc259a54bc61cb7fbfb03bfdMichael Jurka if (ltr) { 393942b9eefdc1a918ccc259a54bc61cb7fbfb03bfdMichael Jurka cropRect.right += extraSpace; 394942b9eefdc1a918ccc259a54bc61cb7fbfb03bfdMichael Jurka } else { 395942b9eefdc1a918ccc259a54bc61cb7fbfb03bfdMichael Jurka cropRect.left -= extraSpace; 396942b9eefdc1a918ccc259a54bc61cb7fbfb03bfdMichael Jurka } 397f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka } 398f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka 399f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka // ADJUST CROP HEIGHT 400f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka if (isPortrait) { 401f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka cropRect.bottom = cropRect.top + defaultWallpaperSize.y / cropScale; 402f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka } else { // LANDSCAPE 403f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka float extraPortraitHeight = 404f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka defaultWallpaperSize.y / cropScale - cropRect.height(); 405f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka float expandHeight = 406f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka Math.min(Math.min(rotatedInSize[1] - cropRect.bottom, cropRect.top), 407f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka extraPortraitHeight / 2); 408f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka cropRect.top -= expandHeight; 409f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka cropRect.bottom += expandHeight; 410f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka } 411f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka final int outWidth = (int) Math.round(cropRect.width() * cropScale); 412f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka final int outHeight = (int) Math.round(cropRect.height() * cropScale); 413f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka 414f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka Runnable onEndCrop = new Runnable() { 415f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka public void run() { 416f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka updateWallpaperDimensions(outWidth, outHeight); 417f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka if (finishActivityWhenDone) { 418f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka setResult(Activity.RESULT_OK); 419f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka finish(); 420f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka } 421f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka } 422f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka }; 423f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka BitmapCropTask cropTask = new BitmapCropTask(this, uri, 424f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka cropRect, cropRotation, outWidth, outHeight, true, false, onEndCrop); 425f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka if (onBitmapCroppedHandler != null) { 426f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka cropTask.setOnBitmapCropped(onBitmapCroppedHandler); 427f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka } 428f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka cropTask.execute(); 429f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka } 430f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka 431f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka protected void updateWallpaperDimensions(int width, int height) { 432f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka String spKey = getSharedPreferencesKey(); 433f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka SharedPreferences sp = getSharedPreferences(spKey, Context.MODE_MULTI_PROCESS); 434f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka SharedPreferences.Editor editor = sp.edit(); 435f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka if (width != 0 && height != 0) { 436f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka editor.putInt(WALLPAPER_WIDTH_KEY, width); 437f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka editor.putInt(WALLPAPER_HEIGHT_KEY, height); 438f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka } else { 439f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka editor.remove(WALLPAPER_WIDTH_KEY); 440f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka editor.remove(WALLPAPER_HEIGHT_KEY); 441f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka } 442f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka editor.commit(); 443f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka 444f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka suggestWallpaperDimension(getResources(), 445608c0af2e8bcf5ee546b52097ce0184496a7c4a1Adam Cohen sp, getWindowManager(), WallpaperManager.getInstance(this), true); 446f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka } 447f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka 448f10a4ed72d6b554bd8d9b44465845245fa1235f6Sunny Goyal public static void suggestWallpaperDimension(Resources res, 449f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka final SharedPreferences sharedPrefs, 450f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka WindowManager windowManager, 451608c0af2e8bcf5ee546b52097ce0184496a7c4a1Adam Cohen final WallpaperManager wallpaperManager, boolean fallBackToDefaults) { 452f10a4ed72d6b554bd8d9b44465845245fa1235f6Sunny Goyal final Point defaultWallpaperSize = BitmapUtils.getDefaultWallpaperSize(res, windowManager); 453f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka // If we have saved a wallpaper width/height, use that instead 454608c0af2e8bcf5ee546b52097ce0184496a7c4a1Adam Cohen 455608c0af2e8bcf5ee546b52097ce0184496a7c4a1Adam Cohen int savedWidth = sharedPrefs.getInt(WALLPAPER_WIDTH_KEY, -1); 456608c0af2e8bcf5ee546b52097ce0184496a7c4a1Adam Cohen int savedHeight = sharedPrefs.getInt(WALLPAPER_HEIGHT_KEY, -1); 457608c0af2e8bcf5ee546b52097ce0184496a7c4a1Adam Cohen 458608c0af2e8bcf5ee546b52097ce0184496a7c4a1Adam Cohen if (savedWidth == -1 || savedHeight == -1) { 459608c0af2e8bcf5ee546b52097ce0184496a7c4a1Adam Cohen if (!fallBackToDefaults) { 460608c0af2e8bcf5ee546b52097ce0184496a7c4a1Adam Cohen return; 461608c0af2e8bcf5ee546b52097ce0184496a7c4a1Adam Cohen } else { 462608c0af2e8bcf5ee546b52097ce0184496a7c4a1Adam Cohen savedWidth = defaultWallpaperSize.x; 463608c0af2e8bcf5ee546b52097ce0184496a7c4a1Adam Cohen savedHeight = defaultWallpaperSize.y; 464608c0af2e8bcf5ee546b52097ce0184496a7c4a1Adam Cohen } 465608c0af2e8bcf5ee546b52097ce0184496a7c4a1Adam Cohen } 466608c0af2e8bcf5ee546b52097ce0184496a7c4a1Adam Cohen 467f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka if (savedWidth != wallpaperManager.getDesiredMinimumWidth() || 468f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka savedHeight != wallpaperManager.getDesiredMinimumHeight()) { 469f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka wallpaperManager.suggestDesiredDimensions(savedWidth, savedHeight); 470f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka } 471f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka } 4722a218b718e5f498a284341532178c84fe3850e63Sunny Goyal 4732a218b718e5f498a284341532178c84fe3850e63Sunny Goyal static class LoadRequest { 4742a218b718e5f498a284341532178c84fe3850e63Sunny Goyal BitmapSource src; 4752a218b718e5f498a284341532178c84fe3850e63Sunny Goyal boolean touchEnabled; 4762a218b718e5f498a284341532178c84fe3850e63Sunny Goyal boolean moveToLeft; 4772a218b718e5f498a284341532178c84fe3850e63Sunny Goyal Runnable postExecute; 4782a218b718e5f498a284341532178c84fe3850e63Sunny Goyal CropViewScaleProvider scaleProvider; 4792a218b718e5f498a284341532178c84fe3850e63Sunny Goyal 4802a218b718e5f498a284341532178c84fe3850e63Sunny Goyal TileSource result; 4812a218b718e5f498a284341532178c84fe3850e63Sunny Goyal } 4822a218b718e5f498a284341532178c84fe3850e63Sunny Goyal 4832a218b718e5f498a284341532178c84fe3850e63Sunny Goyal interface CropViewScaleProvider { 4842a218b718e5f498a284341532178c84fe3850e63Sunny Goyal float getScale(TileSource src); 4852a218b718e5f498a284341532178c84fe3850e63Sunny Goyal } 486f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka} 487