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 17748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyalpackage com.android.wallpaperpicker; 18f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka 19f10a4ed72d6b554bd8d9b44465845245fa1235f6Sunny Goyalimport android.annotation.TargetApi; 20f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurkaimport android.app.ActionBar; 21f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurkaimport android.app.Activity; 224428db78eed5d453c3bb376e6e28977c21b1c9ddSunny Goyalimport android.app.WallpaperManager; 237d21299b0f731db1259f7ee22f36548d5b59fbf9Tony Wickhamimport android.content.DialogInterface; 24f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurkaimport android.content.Intent; 2536a594314db8107927ee94762983dad95aad07aeSunny Goyalimport android.content.pm.ActivityInfo; 26f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurkaimport android.content.res.Resources; 272a218b718e5f498a284341532178c84fe3850e63Sunny Goyalimport android.graphics.Bitmap; 28f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurkaimport android.graphics.Matrix; 29f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurkaimport android.graphics.Point; 30f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurkaimport android.graphics.RectF; 314428db78eed5d453c3bb376e6e28977c21b1c9ddSunny Goyalimport android.graphics.drawable.Drawable; 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.widget.Toast; 422a218b718e5f498a284341532178c84fe3850e63Sunny Goyal 43841a502864d307341945eae62569b92cada93e75Sunny Goyalimport com.android.wallpaperpicker.common.CropAndSetWallpaperTask; 44f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurkaimport com.android.gallery3d.common.Utils; 45f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurkaimport com.android.photos.BitmapRegionTileSource; 46f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurkaimport com.android.photos.BitmapRegionTileSource.BitmapSource; 472a218b718e5f498a284341532178c84fe3850e63Sunny Goyalimport com.android.photos.BitmapRegionTileSource.BitmapSource.InBitmapProvider; 482a218b718e5f498a284341532178c84fe3850e63Sunny Goyalimport com.android.photos.views.TiledImageRenderer.TileSource; 49e396f914a5aaedb0607ea62038b80be7556d6c6cTony Wickhamimport com.android.wallpaperpicker.common.DialogUtils; 50841a502864d307341945eae62569b92cada93e75Sunny Goyalimport com.android.wallpaperpicker.common.InputStreamProvider; 512a218b718e5f498a284341532178c84fe3850e63Sunny Goyal 522a218b718e5f498a284341532178c84fe3850e63Sunny Goyalimport java.util.Collections; 532a218b718e5f498a284341532178c84fe3850e63Sunny Goyalimport java.util.Set; 542a218b718e5f498a284341532178c84fe3850e63Sunny Goyalimport java.util.WeakHashMap; 55f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka 56748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyalpublic class WallpaperCropActivity extends Activity implements Handler.Callback { 57748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal private static final String LOGTAG = "WallpaperCropActivity"; 58f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka 592a218b718e5f498a284341532178c84fe3850e63Sunny Goyal private static final int MSG_LOAD_IMAGE = 1; 602a218b718e5f498a284341532178c84fe3850e63Sunny Goyal 61f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka protected CropView mCropView; 622a218b718e5f498a284341532178c84fe3850e63Sunny Goyal protected View mProgressView; 6312d9d42afb5bd750ab52e38cd66f6081f4bd76bfSelim Cinek protected View mSetWallpaperButton; 64f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka 652a218b718e5f498a284341532178c84fe3850e63Sunny Goyal private HandlerThread mLoaderThread; 662a218b718e5f498a284341532178c84fe3850e63Sunny Goyal private Handler mLoaderHandler; 67748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal private LoadRequest mCurrentLoadRequest; 682a218b718e5f498a284341532178c84fe3850e63Sunny Goyal private byte[] mTempStorageForDecoding = new byte[16 * 1024]; 692a218b718e5f498a284341532178c84fe3850e63Sunny Goyal // A weak-set of reusable bitmaps 70748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal private Set<Bitmap> mReusableBitmaps = 712a218b718e5f498a284341532178c84fe3850e63Sunny Goyal Collections.newSetFromMap(new WeakHashMap<Bitmap, Boolean>()); 722a218b718e5f498a284341532178c84fe3850e63Sunny Goyal 737d21299b0f731db1259f7ee22f36548d5b59fbf9Tony Wickham private final DialogInterface.OnCancelListener mOnDialogCancelListener = 747d21299b0f731db1259f7ee22f36548d5b59fbf9Tony Wickham new DialogInterface.OnCancelListener() { 757d21299b0f731db1259f7ee22f36548d5b59fbf9Tony Wickham @Override 767d21299b0f731db1259f7ee22f36548d5b59fbf9Tony Wickham public void onCancel(DialogInterface dialog) { 777d21299b0f731db1259f7ee22f36548d5b59fbf9Tony Wickham showActionBarAndTiles(); 787d21299b0f731db1259f7ee22f36548d5b59fbf9Tony Wickham } 797d21299b0f731db1259f7ee22f36548d5b59fbf9Tony Wickham }; 807d21299b0f731db1259f7ee22f36548d5b59fbf9Tony Wickham 81f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka @Override 827c34dd41f64c30be2348979b2d6847257498d541Sunny Goyal public void onCreate(Bundle savedInstanceState) { 83f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka super.onCreate(savedInstanceState); 842a218b718e5f498a284341532178c84fe3850e63Sunny Goyal 852a218b718e5f498a284341532178c84fe3850e63Sunny Goyal mLoaderThread = new HandlerThread("wallpaper_loader"); 862a218b718e5f498a284341532178c84fe3850e63Sunny Goyal mLoaderThread.start(); 872a218b718e5f498a284341532178c84fe3850e63Sunny Goyal mLoaderHandler = new Handler(mLoaderThread.getLooper(), this); 882a218b718e5f498a284341532178c84fe3850e63Sunny Goyal 89f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka init(); 90f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka if (!enableRotation()) { 9136a594314db8107927ee94762983dad95aad07aeSunny Goyal setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); 92f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka } 93f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka } 94f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka 95f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka protected void init() { 96f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka setContentView(R.layout.wallpaper_cropper); 97f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka 98f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka mCropView = (CropView) findViewById(R.id.cropView); 992a218b718e5f498a284341532178c84fe3850e63Sunny Goyal mProgressView = findViewById(R.id.loading); 100f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka 101f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka Intent cropIntent = getIntent(); 102f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka final Uri imageUri = cropIntent.getData(); 103f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka 104f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka if (imageUri == null) { 105f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka Log.e(LOGTAG, "No URI passed in intent, exiting WallpaperCropActivity"); 106f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka finish(); 107f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka return; 108f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka } 109f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka 110f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka // Action bar 111f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka // Show the custom action bar view 112f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka final ActionBar actionBar = getActionBar(); 113f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka actionBar.setCustomView(R.layout.actionbar_set_wallpaper); 114f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka actionBar.getCustomView().setOnClickListener( 115f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka new View.OnClickListener() { 116f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka @Override 117f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka public void onClick(View v) { 118d8fbf6b0404846ea043c1468e4d8069c62381011Tony Wickham actionBar.hide(); 11939d389f406185d91b588c4caf3225749fd2afdcfTony Wickham // Never fade on finish because we return to the app that started us (e.g. 12039d389f406185d91b588c4caf3225749fd2afdcfTony Wickham // Photos), not the home screen. 12139d389f406185d91b588c4caf3225749fd2afdcfTony Wickham cropImageAndSetWallpaper(imageUri, null, false /* shouldFadeOutOnFinish */); 122f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka } 123f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka }); 124c192530433ab03c02462635e9ffbe3781b666e13Michael Jurka mSetWallpaperButton = findViewById(R.id.set_wallpaper_button); 125f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka 126f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka // Load image in background 127841a502864d307341945eae62569b92cada93e75Sunny Goyal final BitmapRegionTileSource.InputStreamSource bitmapSource = 128841a502864d307341945eae62569b92cada93e75Sunny Goyal new BitmapRegionTileSource.InputStreamSource(this, imageUri); 12912d9d42afb5bd750ab52e38cd66f6081f4bd76bfSelim Cinek mSetWallpaperButton.setEnabled(false); 130f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka Runnable onLoad = new Runnable() { 131f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka public void run() { 132f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka if (bitmapSource.getLoadingState() != BitmapSource.State.LOADED) { 133748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal Toast.makeText(WallpaperCropActivity.this, R.string.wallpaper_load_fail, 134f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka Toast.LENGTH_LONG).show(); 135f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka finish(); 136c192530433ab03c02462635e9ffbe3781b666e13Michael Jurka } else { 13712d9d42afb5bd750ab52e38cd66f6081f4bd76bfSelim Cinek mSetWallpaperButton.setEnabled(true); 138f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka } 139f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka } 140f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka }; 1412a218b718e5f498a284341532178c84fe3850e63Sunny Goyal setCropViewTileSource(bitmapSource, true, false, null, onLoad); 142f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka } 143f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka 1441019588c3cbc255dc523161950adc22483777291Sunny Goyal @Override 1457c34dd41f64c30be2348979b2d6847257498d541Sunny Goyal public void onDestroy() { 1461019588c3cbc255dc523161950adc22483777291Sunny Goyal if (mCropView != null) { 1471019588c3cbc255dc523161950adc22483777291Sunny Goyal mCropView.destroy(); 1481019588c3cbc255dc523161950adc22483777291Sunny Goyal } 1492a218b718e5f498a284341532178c84fe3850e63Sunny Goyal if (mLoaderThread != null) { 1502a218b718e5f498a284341532178c84fe3850e63Sunny Goyal mLoaderThread.quit(); 1512a218b718e5f498a284341532178c84fe3850e63Sunny Goyal } 1521019588c3cbc255dc523161950adc22483777291Sunny Goyal super.onDestroy(); 1531019588c3cbc255dc523161950adc22483777291Sunny Goyal } 1541019588c3cbc255dc523161950adc22483777291Sunny Goyal 1552a218b718e5f498a284341532178c84fe3850e63Sunny Goyal /** 1562a218b718e5f498a284341532178c84fe3850e63Sunny Goyal * This is called on {@link #mLoaderThread} 1572a218b718e5f498a284341532178c84fe3850e63Sunny Goyal */ 158748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal @TargetApi(Build.VERSION_CODES.KITKAT) 1592a218b718e5f498a284341532178c84fe3850e63Sunny Goyal @Override 1602a218b718e5f498a284341532178c84fe3850e63Sunny Goyal public boolean handleMessage(Message msg) { 1612a218b718e5f498a284341532178c84fe3850e63Sunny Goyal if (msg.what == MSG_LOAD_IMAGE) { 1622a218b718e5f498a284341532178c84fe3850e63Sunny Goyal final LoadRequest req = (LoadRequest) msg.obj; 16336a594314db8107927ee94762983dad95aad07aeSunny Goyal final boolean loadSuccess; 1642a218b718e5f498a284341532178c84fe3850e63Sunny Goyal 16536a594314db8107927ee94762983dad95aad07aeSunny Goyal if (req.src == null) { 16636a594314db8107927ee94762983dad95aad07aeSunny Goyal Drawable defaultWallpaper = WallpaperManager.getInstance(this) 16736a594314db8107927ee94762983dad95aad07aeSunny Goyal .getBuiltInDrawable(mCropView.getWidth(), mCropView.getHeight(), 16836a594314db8107927ee94762983dad95aad07aeSunny Goyal false, 0.5f, 0.5f); 16936a594314db8107927ee94762983dad95aad07aeSunny Goyal 17036a594314db8107927ee94762983dad95aad07aeSunny Goyal if (defaultWallpaper == null) { 17136a594314db8107927ee94762983dad95aad07aeSunny Goyal loadSuccess = false; 17236a594314db8107927ee94762983dad95aad07aeSunny Goyal Log.w(LOGTAG, "Null default wallpaper encountered."); 17336a594314db8107927ee94762983dad95aad07aeSunny Goyal } else { 17436a594314db8107927ee94762983dad95aad07aeSunny Goyal loadSuccess = true; 17536a594314db8107927ee94762983dad95aad07aeSunny Goyal req.result = new DrawableTileSource(this, 17636a594314db8107927ee94762983dad95aad07aeSunny Goyal defaultWallpaper, DrawableTileSource.MAX_PREVIEW_SIZE); 17736a594314db8107927ee94762983dad95aad07aeSunny Goyal } 17836a594314db8107927ee94762983dad95aad07aeSunny Goyal } else { 17936a594314db8107927ee94762983dad95aad07aeSunny Goyal try { 18036a594314db8107927ee94762983dad95aad07aeSunny Goyal req.src.loadInBackground(new InBitmapProvider() { 18136a594314db8107927ee94762983dad95aad07aeSunny Goyal 18236a594314db8107927ee94762983dad95aad07aeSunny Goyal @Override 18336a594314db8107927ee94762983dad95aad07aeSunny Goyal public Bitmap forPixelCount(int count) { 18436a594314db8107927ee94762983dad95aad07aeSunny Goyal Bitmap bitmapToReuse = null; 18536a594314db8107927ee94762983dad95aad07aeSunny Goyal // Find the smallest bitmap that satisfies the pixel count limit 18636a594314db8107927ee94762983dad95aad07aeSunny Goyal synchronized (mReusableBitmaps) { 18736a594314db8107927ee94762983dad95aad07aeSunny Goyal int currentBitmapSize = Integer.MAX_VALUE; 18836a594314db8107927ee94762983dad95aad07aeSunny Goyal for (Bitmap b : mReusableBitmaps) { 18936a594314db8107927ee94762983dad95aad07aeSunny Goyal int bitmapSize = b.getWidth() * b.getHeight(); 19036a594314db8107927ee94762983dad95aad07aeSunny Goyal if ((bitmapSize >= count) && (bitmapSize < currentBitmapSize)) { 19136a594314db8107927ee94762983dad95aad07aeSunny Goyal bitmapToReuse = b; 19236a594314db8107927ee94762983dad95aad07aeSunny Goyal currentBitmapSize = bitmapSize; 19336a594314db8107927ee94762983dad95aad07aeSunny Goyal } 1942a218b718e5f498a284341532178c84fe3850e63Sunny Goyal } 19578dfc60f10acbb915aa08312e6b53f5f1bc4e1c3Sunny Goyal 19636a594314db8107927ee94762983dad95aad07aeSunny Goyal if (bitmapToReuse != null) { 19736a594314db8107927ee94762983dad95aad07aeSunny Goyal mReusableBitmaps.remove(bitmapToReuse); 19836a594314db8107927ee94762983dad95aad07aeSunny Goyal } 19978dfc60f10acbb915aa08312e6b53f5f1bc4e1c3Sunny Goyal } 20036a594314db8107927ee94762983dad95aad07aeSunny Goyal return bitmapToReuse; 201d444a550ec1c8992fbac0a036b293fc4759d25c1Selim Cinek } 20236a594314db8107927ee94762983dad95aad07aeSunny Goyal }); 20336a594314db8107927ee94762983dad95aad07aeSunny Goyal } catch (SecurityException securityException) { 20436a594314db8107927ee94762983dad95aad07aeSunny Goyal if (isActivityDestroyed()) { 20536a594314db8107927ee94762983dad95aad07aeSunny Goyal // Temporarily granted permissions are revoked when the activity 20636a594314db8107927ee94762983dad95aad07aeSunny Goyal // finishes, potentially resulting in a SecurityException here. 20736a594314db8107927ee94762983dad95aad07aeSunny Goyal // Even though {@link #isDestroyed} might also return true in different 20836a594314db8107927ee94762983dad95aad07aeSunny Goyal // situations where the configuration changes, we are fine with 20936a594314db8107927ee94762983dad95aad07aeSunny Goyal // catching these cases here as well. 21036a594314db8107927ee94762983dad95aad07aeSunny Goyal return true; 21136a594314db8107927ee94762983dad95aad07aeSunny Goyal } else { 21236a594314db8107927ee94762983dad95aad07aeSunny Goyal // otherwise it had a different cause and we throw it further 21336a594314db8107927ee94762983dad95aad07aeSunny Goyal throw securityException; 214d444a550ec1c8992fbac0a036b293fc4759d25c1Selim Cinek } 215f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka } 21636a594314db8107927ee94762983dad95aad07aeSunny Goyal 217748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal req.result = new BitmapRegionTileSource(WallpaperCropActivity.this, req.src, 21836a594314db8107927ee94762983dad95aad07aeSunny Goyal mTempStorageForDecoding); 21936a594314db8107927ee94762983dad95aad07aeSunny Goyal loadSuccess = req.src.getLoadingState() == BitmapSource.State.LOADED; 220f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka } 2212a218b718e5f498a284341532178c84fe3850e63Sunny Goyal 2222a218b718e5f498a284341532178c84fe3850e63Sunny Goyal runOnUiThread(new Runnable() { 2232a218b718e5f498a284341532178c84fe3850e63Sunny Goyal 2242a218b718e5f498a284341532178c84fe3850e63Sunny Goyal @Override 2252a218b718e5f498a284341532178c84fe3850e63Sunny Goyal public void run() { 2262a218b718e5f498a284341532178c84fe3850e63Sunny Goyal if (req == mCurrentLoadRequest) { 22736a594314db8107927ee94762983dad95aad07aeSunny Goyal onLoadRequestComplete(req, loadSuccess); 2282a218b718e5f498a284341532178c84fe3850e63Sunny Goyal } else { 2292a218b718e5f498a284341532178c84fe3850e63Sunny Goyal addReusableBitmap(req.result); 230f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka } 231f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka } 2322a218b718e5f498a284341532178c84fe3850e63Sunny Goyal }); 2332a218b718e5f498a284341532178c84fe3850e63Sunny Goyal return true; 2342a218b718e5f498a284341532178c84fe3850e63Sunny Goyal } 2352a218b718e5f498a284341532178c84fe3850e63Sunny Goyal return false; 2362a218b718e5f498a284341532178c84fe3850e63Sunny Goyal } 2372a218b718e5f498a284341532178c84fe3850e63Sunny Goyal 2382b79967d4a01b851136f32d89e4d45a3919fa8f0Sunny Goyal @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) 2394428db78eed5d453c3bb376e6e28977c21b1c9ddSunny Goyal public boolean isActivityDestroyed() { 240748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal return Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1 && isDestroyed(); 2412b79967d4a01b851136f32d89e4d45a3919fa8f0Sunny Goyal } 2422b79967d4a01b851136f32d89e4d45a3919fa8f0Sunny Goyal 243748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal private void addReusableBitmap(TileSource src) { 2442a218b718e5f498a284341532178c84fe3850e63Sunny Goyal synchronized (mReusableBitmaps) { 245748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT 246748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal && src instanceof BitmapRegionTileSource) { 2472a218b718e5f498a284341532178c84fe3850e63Sunny Goyal Bitmap preview = ((BitmapRegionTileSource) src).getBitmap(); 2482a218b718e5f498a284341532178c84fe3850e63Sunny Goyal if (preview != null && preview.isMutable()) { 2492a218b718e5f498a284341532178c84fe3850e63Sunny Goyal mReusableBitmaps.add(preview); 250f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka } 251f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka } 2522a218b718e5f498a284341532178c84fe3850e63Sunny Goyal } 2532a218b718e5f498a284341532178c84fe3850e63Sunny Goyal } 2542a218b718e5f498a284341532178c84fe3850e63Sunny Goyal 2557d21299b0f731db1259f7ee22f36548d5b59fbf9Tony Wickham public DialogInterface.OnCancelListener getOnDialogCancelListener() { 2567d21299b0f731db1259f7ee22f36548d5b59fbf9Tony Wickham return mOnDialogCancelListener; 2577d21299b0f731db1259f7ee22f36548d5b59fbf9Tony Wickham } 2587d21299b0f731db1259f7ee22f36548d5b59fbf9Tony Wickham 2597d21299b0f731db1259f7ee22f36548d5b59fbf9Tony Wickham private void showActionBarAndTiles() { 2607d21299b0f731db1259f7ee22f36548d5b59fbf9Tony Wickham getActionBar().show(); 2617d21299b0f731db1259f7ee22f36548d5b59fbf9Tony Wickham View wallpaperStrip = findViewById(R.id.wallpaper_strip); 2627d21299b0f731db1259f7ee22f36548d5b59fbf9Tony Wickham if (wallpaperStrip != null) { 2637d21299b0f731db1259f7ee22f36548d5b59fbf9Tony Wickham wallpaperStrip.setVisibility(View.VISIBLE); 2647d21299b0f731db1259f7ee22f36548d5b59fbf9Tony Wickham } 2657d21299b0f731db1259f7ee22f36548d5b59fbf9Tony Wickham } 2667d21299b0f731db1259f7ee22f36548d5b59fbf9Tony Wickham 2672a218b718e5f498a284341532178c84fe3850e63Sunny Goyal protected void onLoadRequestComplete(LoadRequest req, boolean success) { 2682a218b718e5f498a284341532178c84fe3850e63Sunny Goyal mCurrentLoadRequest = null; 2692a218b718e5f498a284341532178c84fe3850e63Sunny Goyal if (success) { 2702a218b718e5f498a284341532178c84fe3850e63Sunny Goyal TileSource oldSrc = mCropView.getTileSource(); 2712a218b718e5f498a284341532178c84fe3850e63Sunny Goyal mCropView.setTileSource(req.result, null); 2722a218b718e5f498a284341532178c84fe3850e63Sunny Goyal mCropView.setTouchEnabled(req.touchEnabled); 2732a218b718e5f498a284341532178c84fe3850e63Sunny Goyal if (req.moveToLeft) { 2742a218b718e5f498a284341532178c84fe3850e63Sunny Goyal mCropView.moveToLeft(); 2752a218b718e5f498a284341532178c84fe3850e63Sunny Goyal } 2767bd5e80dc5e26102e59b300dec8dfd8abd9184b4Tony Wickham if (req.scaleAndOffsetProvider != null) { 27713d3a076ce25c531c450d139b37b3e5bbd6964e1Tony Wickham TileSource src = req.result; 27813d3a076ce25c531c450d139b37b3e5bbd6964e1Tony Wickham Point wallpaperSize = WallpaperUtils.getDefaultWallpaperSize( 27913d3a076ce25c531c450d139b37b3e5bbd6964e1Tony Wickham getResources(), getWindowManager()); 28013d3a076ce25c531c450d139b37b3e5bbd6964e1Tony Wickham RectF crop = Utils.getMaxCropRect(src.getImageWidth(), src.getImageHeight(), 28113d3a076ce25c531c450d139b37b3e5bbd6964e1Tony Wickham wallpaperSize.x, wallpaperSize.y, false /* leftAligned */); 28213d3a076ce25c531c450d139b37b3e5bbd6964e1Tony Wickham mCropView.setScale(req.scaleAndOffsetProvider.getScale(wallpaperSize, crop)); 28313d3a076ce25c531c450d139b37b3e5bbd6964e1Tony Wickham mCropView.setParallaxOffset(req.scaleAndOffsetProvider.getParallaxOffset(), crop); 2842a218b718e5f498a284341532178c84fe3850e63Sunny Goyal } 2852a218b718e5f498a284341532178c84fe3850e63Sunny Goyal 2862a218b718e5f498a284341532178c84fe3850e63Sunny Goyal // Free last image 2872a218b718e5f498a284341532178c84fe3850e63Sunny Goyal if (oldSrc != null) { 2882a218b718e5f498a284341532178c84fe3850e63Sunny Goyal // Call yield instead of recycle, as we only want to free GL resource. 2892a218b718e5f498a284341532178c84fe3850e63Sunny Goyal // We can still reuse the bitmap for decoding any other image. 2902a218b718e5f498a284341532178c84fe3850e63Sunny Goyal oldSrc.getPreview().yield(); 2912a218b718e5f498a284341532178c84fe3850e63Sunny Goyal } 2922a218b718e5f498a284341532178c84fe3850e63Sunny Goyal addReusableBitmap(oldSrc); 2932a218b718e5f498a284341532178c84fe3850e63Sunny Goyal } 2942a218b718e5f498a284341532178c84fe3850e63Sunny Goyal if (req.postExecute != null) { 2952a218b718e5f498a284341532178c84fe3850e63Sunny Goyal req.postExecute.run(); 2962a218b718e5f498a284341532178c84fe3850e63Sunny Goyal } 297b5351470a2136a3e680d05133138de67b3d5c6abSunny Goyal mProgressView.setVisibility(View.GONE); 2982a218b718e5f498a284341532178c84fe3850e63Sunny Goyal } 2992a218b718e5f498a284341532178c84fe3850e63Sunny Goyal 3004428db78eed5d453c3bb376e6e28977c21b1c9ddSunny Goyal @TargetApi(Build.VERSION_CODES.KITKAT) 3012a218b718e5f498a284341532178c84fe3850e63Sunny Goyal public final void setCropViewTileSource(BitmapSource bitmapSource, boolean touchEnabled, 3027bd5e80dc5e26102e59b300dec8dfd8abd9184b4Tony Wickham boolean moveToLeft, CropViewScaleAndOffsetProvider scaleAndOffsetProvider, 3037bd5e80dc5e26102e59b300dec8dfd8abd9184b4Tony Wickham Runnable postExecute) { 3042a218b718e5f498a284341532178c84fe3850e63Sunny Goyal final LoadRequest req = new LoadRequest(); 3052a218b718e5f498a284341532178c84fe3850e63Sunny Goyal req.moveToLeft = moveToLeft; 3062a218b718e5f498a284341532178c84fe3850e63Sunny Goyal req.src = bitmapSource; 3072a218b718e5f498a284341532178c84fe3850e63Sunny Goyal req.touchEnabled = touchEnabled; 3082a218b718e5f498a284341532178c84fe3850e63Sunny Goyal req.postExecute = postExecute; 3097bd5e80dc5e26102e59b300dec8dfd8abd9184b4Tony Wickham req.scaleAndOffsetProvider = scaleAndOffsetProvider; 3102a218b718e5f498a284341532178c84fe3850e63Sunny Goyal mCurrentLoadRequest = req; 3112a218b718e5f498a284341532178c84fe3850e63Sunny Goyal 3122a218b718e5f498a284341532178c84fe3850e63Sunny Goyal // Remove any pending requests 3132a218b718e5f498a284341532178c84fe3850e63Sunny Goyal mLoaderHandler.removeMessages(MSG_LOAD_IMAGE); 3142a218b718e5f498a284341532178c84fe3850e63Sunny Goyal Message.obtain(mLoaderHandler, MSG_LOAD_IMAGE, req).sendToTarget(); 3152a218b718e5f498a284341532178c84fe3850e63Sunny Goyal 316f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka // We don't want to show the spinner every time we load an image, because that would be 317f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka // annoying; instead, only start showing the spinner if loading the image has taken 318f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka // longer than 1 sec (ie 1000 ms) 3192a218b718e5f498a284341532178c84fe3850e63Sunny Goyal mProgressView.postDelayed(new Runnable() { 320f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka public void run() { 3212a218b718e5f498a284341532178c84fe3850e63Sunny Goyal if (mCurrentLoadRequest == req) { 3222a218b718e5f498a284341532178c84fe3850e63Sunny Goyal mProgressView.setVisibility(View.VISIBLE); 323f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka } 324f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka } 325f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka }, 1000); 326f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka } 327f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka 3282a218b718e5f498a284341532178c84fe3850e63Sunny Goyal 329f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka public boolean enableRotation() { 330748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal return true; 331f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka } 332f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka 33339d389f406185d91b588c4caf3225749fd2afdcfTony Wickham public void cropImageAndSetWallpaper(Resources res, int resId, boolean shouldFadeOutOnFinish) { 334f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka // crop this image and scale it down to the default wallpaper size for 335f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka // this device 336841a502864d307341945eae62569b92cada93e75Sunny Goyal InputStreamProvider streamProvider = InputStreamProvider.fromResource(res, resId); 337f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka Point inSize = mCropView.getSourceDimensions(); 3383faa8a34b7c27a0e3b1d85da373a29036a9d1387Sunny Goyal Point outSize = WallpaperUtils.getDefaultWallpaperSize(getResources(), 339f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka getWindowManager()); 340f10a4ed72d6b554bd8d9b44465845245fa1235f6Sunny Goyal RectF crop = Utils.getMaxCropRect( 341f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka inSize.x, inSize.y, outSize.x, outSize.y, false); 3424428db78eed5d453c3bb376e6e28977c21b1c9ddSunny Goyal // Passing 0, 0 will cause launcher to revert to using the 3434428db78eed5d453c3bb376e6e28977c21b1c9ddSunny Goyal // default wallpaper size 34439d389f406185d91b588c4caf3225749fd2afdcfTony Wickham CropAndFinishHandler onEndCrop = new CropAndFinishHandler(new Point(0, 0), 34539d389f406185d91b588c4caf3225749fd2afdcfTony Wickham shouldFadeOutOnFinish); 346841a502864d307341945eae62569b92cada93e75Sunny Goyal CropAndSetWallpaperTask cropTask = new CropAndSetWallpaperTask( 347841a502864d307341945eae62569b92cada93e75Sunny Goyal streamProvider, this, crop, streamProvider.getRotationFromExif(this), 348841a502864d307341945eae62569b92cada93e75Sunny Goyal outSize.x, outSize.y, onEndCrop); 3497d21299b0f731db1259f7ee22f36548d5b59fbf9Tony Wickham DialogUtils.executeCropTaskAfterPrompt(this, cropTask, getOnDialogCancelListener()); 350f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka } 351f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka 352f10a4ed72d6b554bd8d9b44465845245fa1235f6Sunny Goyal @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) 3534428db78eed5d453c3bb376e6e28977c21b1c9ddSunny Goyal public void cropImageAndSetWallpaper(Uri uri, 354841a502864d307341945eae62569b92cada93e75Sunny Goyal CropAndSetWallpaperTask.OnBitmapCroppedHandler onBitmapCroppedHandler, 35539d389f406185d91b588c4caf3225749fd2afdcfTony Wickham boolean shouldFadeOutOnFinish) { 356f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka // Get the crop 357f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka boolean ltr = mCropView.getLayoutDirection() == View.LAYOUT_DIRECTION_LTR; 358f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka 359f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka Display d = getWindowManager().getDefaultDisplay(); 360f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka 361f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka Point displaySize = new Point(); 362f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka d.getSize(displaySize); 363f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka boolean isPortrait = displaySize.x < displaySize.y; 364f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka 3653faa8a34b7c27a0e3b1d85da373a29036a9d1387Sunny Goyal Point defaultWallpaperSize = WallpaperUtils.getDefaultWallpaperSize(getResources(), 366f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka getWindowManager()); 367f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka // Get the crop 368f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka RectF cropRect = mCropView.getCrop(); 369b24af13c8359963ecdea420a1b395149e7477f83Selim Cinek 370500dfeb109f614fd42e2cc383c5dcfecaa981b38Selim Cinek Point inSize = mCropView.getSourceDimensions(); 371500dfeb109f614fd42e2cc383c5dcfecaa981b38Selim Cinek 372f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka int cropRotation = mCropView.getImageRotation(); 373f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka float cropScale = mCropView.getWidth() / (float) cropRect.width(); 374f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka 375f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka Matrix rotateMatrix = new Matrix(); 376f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka rotateMatrix.setRotate(cropRotation); 377f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka float[] rotatedInSize = new float[] { inSize.x, inSize.y }; 378f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka rotateMatrix.mapPoints(rotatedInSize); 379f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka rotatedInSize[0] = Math.abs(rotatedInSize[0]); 380f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka rotatedInSize[1] = Math.abs(rotatedInSize[1]); 381f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka 3821116efa8af024cb9fcae059c16e23caea984729fSelim Cinek // due to rounding errors in the cropview renderer the edges can be slightly offset 3831116efa8af024cb9fcae059c16e23caea984729fSelim Cinek // therefore we ensure that the boundaries are sanely defined 3841116efa8af024cb9fcae059c16e23caea984729fSelim Cinek cropRect.left = Math.max(0, cropRect.left); 3851116efa8af024cb9fcae059c16e23caea984729fSelim Cinek cropRect.right = Math.min(rotatedInSize[0], cropRect.right); 3861116efa8af024cb9fcae059c16e23caea984729fSelim Cinek cropRect.top = Math.max(0, cropRect.top); 3871116efa8af024cb9fcae059c16e23caea984729fSelim Cinek cropRect.bottom = Math.min(rotatedInSize[1], cropRect.bottom); 3881116efa8af024cb9fcae059c16e23caea984729fSelim Cinek 389f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka // ADJUST CROP WIDTH 390f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka // Extend the crop all the way to the right, for parallax 391f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka // (or all the way to the left, in RTL) 392841a502864d307341945eae62569b92cada93e75Sunny Goyal float extraSpace = ltr ? rotatedInSize[0] - cropRect.right : cropRect.left; 393f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka // Cap the amount of extra width 394f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka float maxExtraSpace = defaultWallpaperSize.x / cropScale - cropRect.width(); 395f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka extraSpace = Math.min(extraSpace, maxExtraSpace); 396f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka 397841a502864d307341945eae62569b92cada93e75Sunny Goyal if (ltr) { 398841a502864d307341945eae62569b92cada93e75Sunny Goyal cropRect.right += extraSpace; 399f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka } else { 400841a502864d307341945eae62569b92cada93e75Sunny Goyal cropRect.left -= extraSpace; 401f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka } 402f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka 403f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka // ADJUST CROP HEIGHT 404f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka if (isPortrait) { 405f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka cropRect.bottom = cropRect.top + defaultWallpaperSize.y / cropScale; 406f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka } else { // LANDSCAPE 407f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka float extraPortraitHeight = 408f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka defaultWallpaperSize.y / cropScale - cropRect.height(); 409f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka float expandHeight = 410f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka Math.min(Math.min(rotatedInSize[1] - cropRect.bottom, cropRect.top), 411f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka extraPortraitHeight / 2); 412f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka cropRect.top -= expandHeight; 413f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka cropRect.bottom += expandHeight; 414f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka } 4154428db78eed5d453c3bb376e6e28977c21b1c9ddSunny Goyal 416f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka final int outWidth = (int) Math.round(cropRect.width() * cropScale); 417f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka final int outHeight = (int) Math.round(cropRect.height() * cropScale); 41839d389f406185d91b588c4caf3225749fd2afdcfTony Wickham CropAndFinishHandler onEndCrop = new CropAndFinishHandler(new Point(outWidth, outHeight), 41939d389f406185d91b588c4caf3225749fd2afdcfTony Wickham shouldFadeOutOnFinish); 420f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka 421841a502864d307341945eae62569b92cada93e75Sunny Goyal CropAndSetWallpaperTask cropTask = new CropAndSetWallpaperTask( 422841a502864d307341945eae62569b92cada93e75Sunny Goyal InputStreamProvider.fromUri(this, uri), this, 4237d21299b0f731db1259f7ee22f36548d5b59fbf9Tony Wickham cropRect, cropRotation, outWidth, outHeight, onEndCrop) { 4247d21299b0f731db1259f7ee22f36548d5b59fbf9Tony Wickham @Override 4257d21299b0f731db1259f7ee22f36548d5b59fbf9Tony Wickham protected void onPreExecute() { 4267d21299b0f731db1259f7ee22f36548d5b59fbf9Tony Wickham // Give some feedback so user knows something is happening. 4277d21299b0f731db1259f7ee22f36548d5b59fbf9Tony Wickham mProgressView.setVisibility(View.VISIBLE); 4287d21299b0f731db1259f7ee22f36548d5b59fbf9Tony Wickham } 4297d21299b0f731db1259f7ee22f36548d5b59fbf9Tony Wickham }; 430f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka if (onBitmapCroppedHandler != null) { 431f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka cropTask.setOnBitmapCropped(onBitmapCroppedHandler); 432f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka } 4337d21299b0f731db1259f7ee22f36548d5b59fbf9Tony Wickham DialogUtils.executeCropTaskAfterPrompt(this, cropTask, getOnDialogCancelListener()); 434f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka } 435f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka 436841a502864d307341945eae62569b92cada93e75Sunny Goyal public void setBoundsAndFinish(Point bounds, boolean overrideTransition) { 437841a502864d307341945eae62569b92cada93e75Sunny Goyal WallpaperUtils.saveWallpaperDimensions(bounds.x, bounds.y, this); 438841a502864d307341945eae62569b92cada93e75Sunny Goyal setResult(Activity.RESULT_OK); 439841a502864d307341945eae62569b92cada93e75Sunny Goyal finish(); 440841a502864d307341945eae62569b92cada93e75Sunny Goyal if (overrideTransition) { 441841a502864d307341945eae62569b92cada93e75Sunny Goyal overridePendingTransition(0, R.anim.fade_out); 442841a502864d307341945eae62569b92cada93e75Sunny Goyal } 443841a502864d307341945eae62569b92cada93e75Sunny Goyal } 444841a502864d307341945eae62569b92cada93e75Sunny Goyal 445841a502864d307341945eae62569b92cada93e75Sunny Goyal public class CropAndFinishHandler implements CropAndSetWallpaperTask.OnEndCropHandler { 4464428db78eed5d453c3bb376e6e28977c21b1c9ddSunny Goyal private final Point mBounds; 44739d389f406185d91b588c4caf3225749fd2afdcfTony Wickham private boolean mShouldFadeOutOnFinish; 44839d389f406185d91b588c4caf3225749fd2afdcfTony Wickham 44939d389f406185d91b588c4caf3225749fd2afdcfTony Wickham /** 45039d389f406185d91b588c4caf3225749fd2afdcfTony Wickham * @param shouldFadeOutOnFinish Whether the wallpaper picker should override the default 45139d389f406185d91b588c4caf3225749fd2afdcfTony Wickham * exit animation to fade out instead. This should only be set to true if the wallpaper 45239d389f406185d91b588c4caf3225749fd2afdcfTony Wickham * preview will exactly match the actual wallpaper on the page we are returning to. 45339d389f406185d91b588c4caf3225749fd2afdcfTony Wickham */ 45439d389f406185d91b588c4caf3225749fd2afdcfTony Wickham public CropAndFinishHandler(Point bounds, boolean shouldFadeOutOnFinish) { 4554428db78eed5d453c3bb376e6e28977c21b1c9ddSunny Goyal mBounds = bounds; 45639d389f406185d91b588c4caf3225749fd2afdcfTony Wickham mShouldFadeOutOnFinish = shouldFadeOutOnFinish; 4574428db78eed5d453c3bb376e6e28977c21b1c9ddSunny Goyal } 4584428db78eed5d453c3bb376e6e28977c21b1c9ddSunny Goyal 4594428db78eed5d453c3bb376e6e28977c21b1c9ddSunny Goyal @Override 46039d389f406185d91b588c4caf3225749fd2afdcfTony Wickham public void run(boolean cropSucceeded) { 461841a502864d307341945eae62569b92cada93e75Sunny Goyal setBoundsAndFinish(mBounds, cropSucceeded && mShouldFadeOutOnFinish); 4624428db78eed5d453c3bb376e6e28977c21b1c9ddSunny Goyal } 4634428db78eed5d453c3bb376e6e28977c21b1c9ddSunny Goyal } 4644428db78eed5d453c3bb376e6e28977c21b1c9ddSunny Goyal 4652a218b718e5f498a284341532178c84fe3850e63Sunny Goyal static class LoadRequest { 4662a218b718e5f498a284341532178c84fe3850e63Sunny Goyal BitmapSource src; 4672a218b718e5f498a284341532178c84fe3850e63Sunny Goyal boolean touchEnabled; 4682a218b718e5f498a284341532178c84fe3850e63Sunny Goyal boolean moveToLeft; 4692a218b718e5f498a284341532178c84fe3850e63Sunny Goyal Runnable postExecute; 4707bd5e80dc5e26102e59b300dec8dfd8abd9184b4Tony Wickham CropViewScaleAndOffsetProvider scaleAndOffsetProvider; 4712a218b718e5f498a284341532178c84fe3850e63Sunny Goyal 4722a218b718e5f498a284341532178c84fe3850e63Sunny Goyal TileSource result; 4732a218b718e5f498a284341532178c84fe3850e63Sunny Goyal } 4742a218b718e5f498a284341532178c84fe3850e63Sunny Goyal 4757bd5e80dc5e26102e59b300dec8dfd8abd9184b4Tony Wickham public interface CropViewScaleAndOffsetProvider { 47613d3a076ce25c531c450d139b37b3e5bbd6964e1Tony Wickham float getScale(Point wallpaperSize, RectF crop); 4777bd5e80dc5e26102e59b300dec8dfd8abd9184b4Tony Wickham float getParallaxOffset(); 4782a218b718e5f498a284341532178c84fe3850e63Sunny Goyal } 479f1b220be2b401f203cfb490f2e78af32700ef4bbMichael Jurka} 480