diff options
author | Sunny Goyal <sunnygoyal@google.com> | 2015-08-14 20:28:39 -0700 |
---|---|---|
committer | Sunny Goyal <sunnygoyal@google.com> | 2015-08-31 12:36:54 -0700 |
commit | e4c28f8e137971a6ad196e27b20880d39cf4c342 (patch) | |
tree | bf619b8d598043872376e6cdceb663d1cc35d8dc /WallpaperPicker/src | |
parent | 1ea392f0bc30134a800be224d8fbcf1af63bb80b (diff) | |
download | android_packages_apps_Trebuchet-e4c28f8e137971a6ad196e27b20880d39cf4c342.tar.gz android_packages_apps_Trebuchet-e4c28f8e137971a6ad196e27b20880d39cf4c342.tar.bz2 android_packages_apps_Trebuchet-e4c28f8e137971a6ad196e27b20880d39cf4c342.zip |
Refactoring wallpaper picker activity
> Moving different tiles to individual classes
> Moving some utility methods to corresponding tile classes
> No functionality change
Change-Id: I493cf309f4e3d817a9300be004c475d208f8dadb
Diffstat (limited to 'WallpaperPicker/src')
15 files changed, 1140 insertions, 1222 deletions
diff --git a/WallpaperPicker/src/com/android/launcher3/LiveWallpaperListAdapter.java b/WallpaperPicker/src/com/android/launcher3/LiveWallpaperListAdapter.java deleted file mode 100644 index b53fce119..000000000 --- a/WallpaperPicker/src/com/android/launcher3/LiveWallpaperListAdapter.java +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.launcher3; - -import android.app.WallpaperInfo; -import android.app.WallpaperManager; -import android.content.Context; -import android.content.Intent; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; -import android.graphics.drawable.Drawable; -import android.os.AsyncTask; -import android.service.wallpaper.WallpaperService; -import android.util.Log; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.BaseAdapter; -import android.widget.ImageView; -import android.widget.ListAdapter; -import android.widget.TextView; - -import com.android.launcher3.util.Thunk; - -import org.xmlpull.v1.XmlPullParserException; - -import java.io.IOException; -import java.text.Collator; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; - -public class LiveWallpaperListAdapter extends BaseAdapter implements ListAdapter { - private static final String LOG_TAG = "LiveWallpaperListAdapter"; - - private final LayoutInflater mInflater; - private final PackageManager mPackageManager; - - @Thunk List<LiveWallpaperTile> mWallpapers; - - @SuppressWarnings("unchecked") - public LiveWallpaperListAdapter(Context context) { - mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); - mPackageManager = context.getPackageManager(); - - List<ResolveInfo> list = mPackageManager.queryIntentServices( - new Intent(WallpaperService.SERVICE_INTERFACE), - PackageManager.GET_META_DATA); - - mWallpapers = new ArrayList<LiveWallpaperTile>(); - - new LiveWallpaperEnumerator(context).execute(list); - } - - public int getCount() { - if (mWallpapers == null) { - return 0; - } - return mWallpapers.size(); - } - - public LiveWallpaperTile getItem(int position) { - return mWallpapers.get(position); - } - - public long getItemId(int position) { - return position; - } - - public View getView(int position, View convertView, ViewGroup parent) { - View view; - - if (convertView == null) { - view = mInflater.inflate(R.layout.wallpaper_picker_live_wallpaper_item, parent, false); - } else { - view = convertView; - } - - LiveWallpaperTile wallpaperInfo = mWallpapers.get(position); - wallpaperInfo.setView(view); - ImageView image = (ImageView) view.findViewById(R.id.wallpaper_image); - ImageView icon = (ImageView) view.findViewById(R.id.wallpaper_icon); - if (wallpaperInfo.mThumbnail != null) { - image.setImageDrawable(wallpaperInfo.mThumbnail); - icon.setVisibility(View.GONE); - } else { - icon.setImageDrawable(wallpaperInfo.mInfo.loadIcon(mPackageManager)); - icon.setVisibility(View.VISIBLE); - } - - TextView label = (TextView) view.findViewById(R.id.wallpaper_item_label); - label.setText(wallpaperInfo.mInfo.loadLabel(mPackageManager)); - - return view; - } - - public static class LiveWallpaperTile extends WallpaperPickerActivity.WallpaperTileInfo { - @Thunk Drawable mThumbnail; - @Thunk WallpaperInfo mInfo; - public LiveWallpaperTile(Drawable thumbnail, WallpaperInfo info, Intent intent) { - mThumbnail = thumbnail; - mInfo = info; - } - @Override - public void onClick(WallpaperPickerActivity a) { - Intent preview = new Intent(WallpaperManager.ACTION_CHANGE_LIVE_WALLPAPER); - preview.putExtra(WallpaperManager.EXTRA_LIVE_WALLPAPER_COMPONENT, - mInfo.getComponent()); - a.startActivityForResultSafely(preview, - WallpaperPickerActivity.PICK_WALLPAPER_THIRD_PARTY_ACTIVITY); - } - } - - private class LiveWallpaperEnumerator extends - AsyncTask<List<ResolveInfo>, LiveWallpaperTile, Void> { - private Context mContext; - private int mWallpaperPosition; - - public LiveWallpaperEnumerator(Context context) { - super(); - mContext = context; - mWallpaperPosition = 0; - } - - @Override - protected Void doInBackground(List<ResolveInfo>... params) { - final PackageManager packageManager = mContext.getPackageManager(); - - List<ResolveInfo> list = params[0]; - - Collections.sort(list, new Comparator<ResolveInfo>() { - final Collator mCollator; - - { - mCollator = Collator.getInstance(); - } - - public int compare(ResolveInfo info1, ResolveInfo info2) { - return mCollator.compare(info1.loadLabel(packageManager), - info2.loadLabel(packageManager)); - } - }); - - for (ResolveInfo resolveInfo : list) { - WallpaperInfo info = null; - try { - info = new WallpaperInfo(mContext, resolveInfo); - } catch (XmlPullParserException e) { - Log.w(LOG_TAG, "Skipping wallpaper " + resolveInfo.serviceInfo, e); - continue; - } catch (IOException e) { - Log.w(LOG_TAG, "Skipping wallpaper " + resolveInfo.serviceInfo, e); - continue; - } - - - Drawable thumb = info.loadThumbnail(packageManager); - Intent launchIntent = new Intent(WallpaperService.SERVICE_INTERFACE); - launchIntent.setClassName(info.getPackageName(), info.getServiceName()); - LiveWallpaperTile wallpaper = new LiveWallpaperTile(thumb, info, launchIntent); - publishProgress(wallpaper); - } - // Send a null object to show loading is finished - publishProgress((LiveWallpaperTile) null); - - return null; - } - - @Override - protected void onProgressUpdate(LiveWallpaperTile...infos) { - for (LiveWallpaperTile info : infos) { - if (info == null) { - LiveWallpaperListAdapter.this.notifyDataSetChanged(); - break; - } - if (info.mThumbnail != null) { - info.mThumbnail.setDither(true); - } - if (mWallpaperPosition < mWallpapers.size()) { - mWallpapers.set(mWallpaperPosition, info); - } else { - mWallpapers.add(info); - } - mWallpaperPosition++; - } - } - } -} diff --git a/WallpaperPicker/src/com/android/launcher3/SavedWallpaperImages.java b/WallpaperPicker/src/com/android/launcher3/SavedWallpaperImages.java index 64b0ac466..9124e414a 100644 --- a/WallpaperPicker/src/com/android/launcher3/SavedWallpaperImages.java +++ b/WallpaperPicker/src/com/android/launcher3/SavedWallpaperImages.java @@ -26,29 +26,24 @@ import android.graphics.BitmapFactory; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.util.Log; -import android.util.Pair; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.BaseAdapter; -import android.widget.ListAdapter; + +import com.android.launcher3.wallpapertileinfo.FileWallpaperInfo; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; +import java.util.List; +public class SavedWallpaperImages { -public class SavedWallpaperImages extends BaseAdapter implements ListAdapter { private static String TAG = "Launcher3.SavedWallpaperImages"; - private ImageDb mDb; - ArrayList<SavedWallpaperTile> mImages; - Context mContext; - LayoutInflater mLayoutInflater; - public static class SavedWallpaperTile extends WallpaperPickerActivity.FileWallpaperInfo { + public static class SavedWallpaperInfo extends FileWallpaperInfo { + private int mDbId; - public SavedWallpaperTile(int dbId, File target, Drawable thumb) { + + public SavedWallpaperInfo(int dbId, File target, Drawable thumb) { super(target, thumb); mDbId = dbId; } @@ -59,19 +54,22 @@ public class SavedWallpaperImages extends BaseAdapter implements ListAdapter { } } + private final ImageDb mDb; + private final Context mContext; + public SavedWallpaperImages(Context context) { // We used to store the saved images in the cache directory, but that meant they'd get // deleted sometimes-- move them to the data directory ImageDb.moveFromCacheDirectoryIfNecessary(context); mDb = new ImageDb(context); mContext = context; - mLayoutInflater = LayoutInflater.from(context); } - public void loadThumbnailsAndImageIdList() { - mImages = new ArrayList<SavedWallpaperTile>(); + public List<SavedWallpaperInfo> loadThumbnailsAndImageIdList() { + List<SavedWallpaperInfo> result = new ArrayList<SavedWallpaperInfo>(); + SQLiteDatabase db = mDb.getReadableDatabase(); - Cursor result = db.query(ImageDb.TABLE_NAME, + Cursor c = db.query(ImageDb.TABLE_NAME, new String[] { ImageDb.COLUMN_ID, ImageDb.COLUMN_IMAGE_THUMBNAIL_FILENAME, ImageDb.COLUMN_IMAGE_FILENAME}, // cols to return @@ -82,43 +80,24 @@ public class SavedWallpaperImages extends BaseAdapter implements ListAdapter { ImageDb.COLUMN_ID + " DESC", null); - while (result.moveToNext()) { - String filename = result.getString(1); + while (c.moveToNext()) { + String filename = c.getString(1); File file = new File(mContext.getFilesDir(), filename); Bitmap thumb = BitmapFactory.decodeFile(file.getAbsolutePath()); if (thumb != null) { - mImages.add(new SavedWallpaperTile(result.getInt(0), - new File(mContext.getFilesDir(), result.getString(2)), - new BitmapDrawable(thumb))); + result.add(new SavedWallpaperInfo(c.getInt(0), + new File(mContext.getFilesDir(), c.getString(2)), + new BitmapDrawable(mContext.getResources(), thumb))); } } - result.close(); - } - - public int getCount() { - return mImages.size(); + c.close(); + return result; } - public SavedWallpaperTile getItem(int position) { - return mImages.get(position); - } - - public long getItemId(int position) { - return position; - } - - public View getView(int position, View convertView, ViewGroup parent) { - Drawable thumbDrawable = mImages.get(position).mThumb; - if (thumbDrawable == null) { - Log.e(TAG, "Error decoding thumbnail for wallpaper #" + position); - } - return WallpaperPickerActivity.createImageTileView( - mLayoutInflater, convertView, parent, thumbDrawable); - } + public void deleteImage(int id) { + SQLiteDatabase db = mDb.getWritableDatabase(); - private Pair<String, String> getImageFilenames(int id) { - SQLiteDatabase db = mDb.getReadableDatabase(); Cursor result = db.query(ImageDb.TABLE_NAME, new String[] { ImageDb.COLUMN_IMAGE_THUMBNAIL_FILENAME, ImageDb.COLUMN_IMAGE_FILENAME }, // cols to return @@ -128,24 +107,12 @@ public class SavedWallpaperImages extends BaseAdapter implements ListAdapter { null, null, null); - if (result.getCount() > 0) { - result.moveToFirst(); - String thumbFilename = result.getString(0); - String imageFilename = result.getString(1); - result.close(); - return new Pair<String, String>(thumbFilename, imageFilename); - } else { - return null; + if (result.moveToFirst()) { + new File(mContext.getFilesDir(), result.getString(0)).delete(); + new File(mContext.getFilesDir(), result.getString(1)).delete(); } - } + result.close(); - public void deleteImage(int id) { - Pair<String, String> filenames = getImageFilenames(id); - File imageFile = new File(mContext.getFilesDir(), filenames.first); - imageFile.delete(); - File thumbFile = new File(mContext.getFilesDir(), filenames.second); - thumbFile.delete(); - SQLiteDatabase db = mDb.getWritableDatabase(); db.delete(ImageDb.TABLE_NAME, ImageDb.COLUMN_ID + " = ?", // SELECT query new String[] { @@ -177,20 +144,16 @@ public class SavedWallpaperImages extends BaseAdapter implements ListAdapter { } } - static class ImageDb extends SQLiteOpenHelper { + private static class ImageDb extends SQLiteOpenHelper { final static int DB_VERSION = 1; final static String TABLE_NAME = "saved_wallpaper_images"; final static String COLUMN_ID = "id"; final static String COLUMN_IMAGE_THUMBNAIL_FILENAME = "image_thumbnail"; final static String COLUMN_IMAGE_FILENAME = "image"; - Context mContext; - public ImageDb(Context context) { super(context, context.getDatabasePath(LauncherFiles.WALLPAPER_IMAGES_DB).getPath(), null, DB_VERSION); - // Store the context for later use - mContext = context; } public static void moveFromCacheDirectoryIfNecessary(Context context) { diff --git a/WallpaperPicker/src/com/android/launcher3/ThirdPartyWallpaperPickerListAdapter.java b/WallpaperPicker/src/com/android/launcher3/ThirdPartyWallpaperPickerListAdapter.java deleted file mode 100644 index f46da53ec..000000000 --- a/WallpaperPicker/src/com/android/launcher3/ThirdPartyWallpaperPickerListAdapter.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.launcher3; - -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.pm.ActivityInfo; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; -import android.graphics.Rect; -import android.graphics.drawable.Drawable; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.BaseAdapter; -import android.widget.ListAdapter; -import android.widget.TextView; - -import com.android.launcher3.util.Thunk; - -import java.util.ArrayList; -import java.util.List; - -public class ThirdPartyWallpaperPickerListAdapter extends BaseAdapter implements ListAdapter { - private final LayoutInflater mInflater; - private final PackageManager mPackageManager; - private final int mIconSize; - - private List<ThirdPartyWallpaperTile> mThirdPartyWallpaperPickers = - new ArrayList<ThirdPartyWallpaperTile>(); - - public static class ThirdPartyWallpaperTile extends WallpaperPickerActivity.WallpaperTileInfo { - @Thunk ResolveInfo mResolveInfo; - public ThirdPartyWallpaperTile(ResolveInfo resolveInfo) { - mResolveInfo = resolveInfo; - } - @Override - public void onClick(WallpaperPickerActivity a) { - final ComponentName itemComponentName = new ComponentName( - mResolveInfo.activityInfo.packageName, mResolveInfo.activityInfo.name); - Intent launchIntent = new Intent(Intent.ACTION_SET_WALLPAPER); - launchIntent.setComponent(itemComponentName); - a.startActivityForResultSafely( - launchIntent, WallpaperPickerActivity.PICK_WALLPAPER_THIRD_PARTY_ACTIVITY); - } - } - - public ThirdPartyWallpaperPickerListAdapter(Context context) { - mInflater = LayoutInflater.from(context); - mPackageManager = context.getPackageManager(); - mIconSize = context.getResources().getDimensionPixelSize(R.dimen.wallpaperItemIconSize); - final PackageManager pm = mPackageManager; - - final Intent pickWallpaperIntent = new Intent(Intent.ACTION_SET_WALLPAPER); - final List<ResolveInfo> apps = - pm.queryIntentActivities(pickWallpaperIntent, 0); - - // Get list of image picker intents - Intent pickImageIntent = new Intent(Intent.ACTION_GET_CONTENT); - pickImageIntent.setType("image/*"); - final List<ResolveInfo> imagePickerActivities = - pm.queryIntentActivities(pickImageIntent, 0); - final ComponentName[] imageActivities = new ComponentName[imagePickerActivities.size()]; - for (int i = 0; i < imagePickerActivities.size(); i++) { - ActivityInfo activityInfo = imagePickerActivities.get(i).activityInfo; - imageActivities[i] = new ComponentName(activityInfo.packageName, activityInfo.name); - } - - outerLoop: - for (ResolveInfo info : apps) { - final ComponentName itemComponentName = - new ComponentName(info.activityInfo.packageName, info.activityInfo.name); - final String itemPackageName = itemComponentName.getPackageName(); - // Exclude anything from our own package, and the old Launcher, - // and live wallpaper picker - if (itemPackageName.equals(context.getPackageName()) || - itemPackageName.equals("com.android.launcher") || - itemPackageName.equals("com.android.wallpaper.livepicker")) { - continue; - } - // Exclude any package that already responds to the image picker intent - for (ResolveInfo imagePickerActivityInfo : imagePickerActivities) { - if (itemPackageName.equals( - imagePickerActivityInfo.activityInfo.packageName)) { - continue outerLoop; - } - } - mThirdPartyWallpaperPickers.add(new ThirdPartyWallpaperTile(info)); - } - } - - public int getCount() { - return mThirdPartyWallpaperPickers.size(); - } - - public ThirdPartyWallpaperTile getItem(int position) { - return mThirdPartyWallpaperPickers.get(position); - } - - public long getItemId(int position) { - return position; - } - - public View getView(int position, View convertView, ViewGroup parent) { - View view; - - if (convertView == null) { - view = mInflater.inflate(R.layout.wallpaper_picker_third_party_item, parent, false); - } else { - view = convertView; - } - - ResolveInfo info = mThirdPartyWallpaperPickers.get(position).mResolveInfo; - TextView label = (TextView) view.findViewById(R.id.wallpaper_item_label); - label.setText(info.loadLabel(mPackageManager)); - Drawable icon = info.loadIcon(mPackageManager); - icon.setBounds(new Rect(0, 0, mIconSize, mIconSize)); - label.setCompoundDrawables(null, icon, null, null); - return view; - } -} diff --git a/WallpaperPicker/src/com/android/launcher3/ToggleOnTapCallback.java b/WallpaperPicker/src/com/android/launcher3/ToggleOnTapCallback.java new file mode 100644 index 000000000..2bc48ee17 --- /dev/null +++ b/WallpaperPicker/src/com/android/launcher3/ToggleOnTapCallback.java @@ -0,0 +1,67 @@ +package com.android.launcher3; + +import android.view.View; +import android.view.ViewPropertyAnimator; +import android.view.animation.AccelerateInterpolator; +import android.view.animation.DecelerateInterpolator; + +import com.android.launcher3.util.Thunk; + +/** + * Callback that toggles the visibility of the target view when crop view is tapped. + */ +public class ToggleOnTapCallback implements CropView.TouchCallback { + + @Thunk final View mViewtoToggle; + + private ViewPropertyAnimator mAnim; + private boolean mIgnoreNextTap; + + public ToggleOnTapCallback(View viewtoHide) { + mViewtoToggle = viewtoHide; + } + + @Override + public void onTouchDown() { + if (mAnim != null) { + mAnim.cancel(); + } + if (mViewtoToggle.getAlpha() == 1f) { + mIgnoreNextTap = true; + } + + mAnim = mViewtoToggle.animate(); + mAnim.alpha(0f) + .setDuration(150) + .withEndAction(new Runnable() { + public void run() { + mViewtoToggle.setVisibility(View.INVISIBLE); + } + }); + + mAnim.setInterpolator(new AccelerateInterpolator(0.75f)); + mAnim.start(); + } + + @Override + public void onTouchUp() { + mIgnoreNextTap = false; + } + + @Override + public void onTap() { + boolean ignoreTap = mIgnoreNextTap; + mIgnoreNextTap = false; + if (!ignoreTap) { + if (mAnim != null) { + mAnim.cancel(); + } + mViewtoToggle.setVisibility(View.VISIBLE); + mAnim = mViewtoToggle.animate(); + mAnim.alpha(1f) + .setDuration(150) + .setInterpolator(new DecelerateInterpolator(0.75f)); + mAnim.start(); + } + } +} diff --git a/WallpaperPicker/src/com/android/launcher3/WallpaperCropActivity.java b/WallpaperPicker/src/com/android/launcher3/WallpaperCropActivity.java index eb473804f..890d1ffe6 100644 --- a/WallpaperPicker/src/com/android/launcher3/WallpaperCropActivity.java +++ b/WallpaperPicker/src/com/android/launcher3/WallpaperCropActivity.java @@ -19,6 +19,7 @@ package com.android.launcher3; import android.annotation.TargetApi; import android.app.ActionBar; import android.app.Activity; +import android.app.WallpaperManager; import android.content.Intent; import android.content.res.Configuration; import android.content.res.Resources; @@ -26,6 +27,7 @@ import android.graphics.Bitmap; import android.graphics.Matrix; import android.graphics.Point; import android.graphics.RectF; +import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Build; import android.os.Bundle; @@ -116,8 +118,7 @@ public class WallpaperCropActivity extends BaseActivity implements Handler.Callb new View.OnClickListener() { @Override public void onClick(View v) { - boolean finishActivityWhenDone = true; - cropImageAndSetWallpaper(imageUri, null, finishActivityWhenDone); + cropImageAndSetWallpaper(imageUri, null); } }); mSetWallpaperButton = findViewById(R.id.set_wallpaper_button); @@ -215,7 +216,7 @@ public class WallpaperCropActivity extends BaseActivity implements Handler.Callb } @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) - protected boolean isActivityDestroyed() { + public boolean isActivityDestroyed() { return Utilities.ATLEAST_JB_MR1 && isDestroyed(); } @@ -257,6 +258,7 @@ public class WallpaperCropActivity extends BaseActivity implements Handler.Callb mProgressView.setVisibility(View.GONE); } + @TargetApi(Build.VERSION_CODES.KITKAT) public final void setCropViewTileSource(BitmapSource bitmapSource, boolean touchEnabled, boolean moveToLeft, CropViewScaleProvider scaleProvider, Runnable postExecute) { final LoadRequest req = new LoadRequest(); @@ -266,6 +268,21 @@ public class WallpaperCropActivity extends BaseActivity implements Handler.Callb req.postExecute = postExecute; req.scaleProvider = scaleProvider; mCurrentLoadRequest = req; + if (bitmapSource == null) { + // Load the default wallpaper + Drawable defaultWallpaper = WallpaperManager.getInstance(this) + .getBuiltInDrawable(mCropView.getWidth(), mCropView.getHeight(), + false, 0.5f, 0.5f); + if (defaultWallpaper == null) { + Log.w(LOGTAG, "Null default wallpaper encountered."); + mCropView.setTileSource(null, null); + return; + } + req.result = new DrawableTileSource(this, + defaultWallpaper, DrawableTileSource.MAX_PREVIEW_SIZE); + onLoadRequestComplete(req, true); + return; + } // Remove any pending requests mLoaderHandler.removeMessages(MSG_LOAD_IMAGE); @@ -288,27 +305,17 @@ public class WallpaperCropActivity extends BaseActivity implements Handler.Callb return getResources().getBoolean(R.bool.allow_rotation); } - protected void setWallpaper(Uri uri, final boolean finishActivityWhenDone) { + public void setWallpaper(Uri uri) { int rotation = BitmapUtils.getRotationFromExif(getContext(), uri); BitmapCropTask cropTask = new BitmapCropTask( getContext(), uri, null, rotation, 0, 0, true, false, null); - final Point bounds = cropTask.getImageBounds(); - Runnable onEndCrop = new Runnable() { - public void run() { - WallpaperUtils.saveWallpaperDimensions(bounds.x, bounds.y, WallpaperCropActivity.this); - if (finishActivityWhenDone) { - setResult(Activity.RESULT_OK); - finish(); - } - } - }; + CropAndFinishRunnable onEndCrop = new CropAndFinishRunnable(cropTask.getImageBounds()); cropTask.setOnEndRunnable(onEndCrop); cropTask.setNoCrop(true); cropTask.execute(); } - protected void cropImageAndSetWallpaper( - Resources res, int resId, final boolean finishActivityWhenDone) { + public void cropImageAndSetWallpaper(Resources res, int resId) { // crop this image and scale it down to the default wallpaper size for // this device int rotation = BitmapUtils.getRotationFromExif(res, resId, this); @@ -317,25 +324,17 @@ public class WallpaperCropActivity extends BaseActivity implements Handler.Callb getWindowManager()); RectF crop = Utils.getMaxCropRect( inSize.x, inSize.y, outSize.x, outSize.y, false); - Runnable onEndCrop = new Runnable() { - public void run() { - // Passing 0, 0 will cause launcher to revert to using the - // default wallpaper size - WallpaperUtils.saveWallpaperDimensions(0, 0, WallpaperCropActivity.this); - if (finishActivityWhenDone) { - setResult(Activity.RESULT_OK); - finish(); - } - } - }; + // Passing 0, 0 will cause launcher to revert to using the + // default wallpaper size + CropAndFinishRunnable onEndCrop = new CropAndFinishRunnable(new Point(0, 0)); BitmapCropTask cropTask = new BitmapCropTask(getContext(), res, resId, crop, rotation, outSize.x, outSize.y, true, false, onEndCrop); cropTask.execute(); } @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) - protected void cropImageAndSetWallpaper(Uri uri, - BitmapCropTask.OnBitmapCroppedHandler onBitmapCroppedHandler, final boolean finishActivityWhenDone) { + public void cropImageAndSetWallpaper(Uri uri, + BitmapCropTask.OnBitmapCroppedHandler onBitmapCroppedHandler) { boolean centerCrop = getResources().getBoolean(R.bool.center_crop); // Get the crop boolean ltr = mCropView.getLayoutDirection() == View.LAYOUT_DIRECTION_LTR; @@ -408,18 +407,11 @@ public class WallpaperCropActivity extends BaseActivity implements Handler.Callb cropRect.top -= expandHeight; cropRect.bottom += expandHeight; } + final int outWidth = (int) Math.round(cropRect.width() * cropScale); final int outHeight = (int) Math.round(cropRect.height() * cropScale); + CropAndFinishRunnable onEndCrop = new CropAndFinishRunnable(new Point(outWidth, outHeight)); - Runnable onEndCrop = new Runnable() { - public void run() { - WallpaperUtils.saveWallpaperDimensions(outWidth, outHeight, WallpaperCropActivity.this); - if (finishActivityWhenDone) { - setResult(Activity.RESULT_OK); - finish(); - } - } - }; BitmapCropTask cropTask = new BitmapCropTask(getContext(), uri, cropRect, cropRotation, outWidth, outHeight, true, false, onEndCrop); if (onBitmapCroppedHandler != null) { @@ -428,6 +420,22 @@ public class WallpaperCropActivity extends BaseActivity implements Handler.Callb cropTask.execute(); } + private class CropAndFinishRunnable implements Runnable { + private final Point mBounds; + + public CropAndFinishRunnable(Point bounds) { + mBounds = bounds; + } + + @Override + public void run() { + WallpaperUtils.saveWallpaperDimensions(mBounds.x, mBounds.y, + WallpaperCropActivity.this); + setResult(Activity.RESULT_OK); + finish(); + } + } + static class LoadRequest { BitmapSource src; boolean touchEnabled; @@ -438,7 +446,7 @@ public class WallpaperCropActivity extends BaseActivity implements Handler.Callb TileSource result; } - interface CropViewScaleProvider { + public interface CropViewScaleProvider { float getScale(TileSource src); } } diff --git a/WallpaperPicker/src/com/android/launcher3/WallpaperPickerActivity.java b/WallpaperPicker/src/com/android/launcher3/WallpaperPickerActivity.java index f37ec2d60..f44c88ebf 100644 --- a/WallpaperPicker/src/com/android/launcher3/WallpaperPickerActivity.java +++ b/WallpaperPicker/src/com/android/launcher3/WallpaperPickerActivity.java @@ -16,38 +16,21 @@ package com.android.launcher3; -import android.Manifest; import android.animation.LayoutTransition; -import android.annotation.TargetApi; +import android.annotation.SuppressLint; import android.app.ActionBar; import android.app.Activity; -import android.app.WallpaperManager; -import android.content.Context; import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.res.Resources; -import android.database.Cursor; -import android.database.DataSetObserver; import android.graphics.Bitmap; import android.graphics.BitmapFactory; -import android.graphics.Canvas; -import android.graphics.Matrix; -import android.graphics.Point; -import android.graphics.PorterDuff; -import android.graphics.RectF; import android.graphics.drawable.BitmapDrawable; -import android.graphics.drawable.Drawable; import android.net.Uri; -import android.os.AsyncTask; -import android.os.Build; import android.os.Bundle; -import android.os.Process; -import android.provider.MediaStore; import android.util.Log; -import android.util.Pair; import android.view.ActionMode; -import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; @@ -55,36 +38,28 @@ import android.view.MotionEvent; import android.view.View; import android.view.View.OnClickListener; import android.view.View.OnLayoutChangeListener; +import android.view.View.OnLongClickListener; import android.view.ViewGroup; -import android.view.ViewPropertyAnimator; import android.view.ViewTreeObserver; import android.view.ViewTreeObserver.OnGlobalLayoutListener; import android.view.WindowManager; -import android.view.animation.AccelerateInterpolator; -import android.view.animation.DecelerateInterpolator; -import android.widget.ArrayAdapter; -import android.widget.BaseAdapter; -import android.widget.FrameLayout; import android.widget.HorizontalScrollView; -import android.widget.ImageView; import android.widget.LinearLayout; -import android.widget.Toast; - -import com.android.gallery3d.common.BitmapCropTask; -import com.android.gallery3d.common.BitmapUtils; -import com.android.gallery3d.common.Utils; import com.android.launcher3.util.Thunk; -import com.android.launcher3.util.WallpaperUtils; -import com.android.photos.BitmapRegionTileSource; -import com.android.photos.BitmapRegionTileSource.BitmapSource; -import com.android.photos.views.TiledImageRenderer.TileSource; - +import com.android.launcher3.wallpapertileinfo.DefaultWallpaperInfo; +import com.android.launcher3.wallpapertileinfo.FileWallpaperInfo; +import com.android.launcher3.wallpapertileinfo.LiveWallpaperInfo; +import com.android.launcher3.wallpapertileinfo.PickImageInfo; +import com.android.launcher3.wallpapertileinfo.ResourceWallpaperInfo; +import com.android.launcher3.wallpapertileinfo.ThirdPartyWallpaperInfo; +import com.android.launcher3.wallpapertileinfo.UriWallpaperInfo; +import com.android.launcher3.wallpapertileinfo.WallpaperTileInfo; import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; import java.util.ArrayList; +import java.util.List; -public class WallpaperPickerActivity extends WallpaperCropActivity { +public class WallpaperPickerActivity extends WallpaperCropActivity + implements OnClickListener, OnLongClickListener, ActionMode.Callback { static final String TAG = "Launcher.WallpaperPickerActivity"; public static final int IMAGE_PICK = 5; @@ -94,241 +69,18 @@ public class WallpaperPickerActivity extends WallpaperCropActivity { private static final int FLAG_POST_DELAY_MILLIS = 200; @Thunk View mSelectedTile; - @Thunk boolean mIgnoreNextTap; - @Thunk OnClickListener mThumbnailOnClickListener; @Thunk LinearLayout mWallpapersView; @Thunk HorizontalScrollView mWallpaperScrollContainer; @Thunk View mWallpaperStrip; - @Thunk ActionMode.Callback mActionModeCallback; @Thunk ActionMode mActionMode; - @Thunk View.OnLongClickListener mLongClickListener; - ArrayList<Uri> mTempWallpaperTiles = new ArrayList<Uri>(); private SavedWallpaperImages mSavedImages; @Thunk int mSelectedIndex = -1; - - public static abstract class WallpaperTileInfo { - protected View mView; - public Drawable mThumb; - - public void setView(View v) { - mView = v; - } - public void onClick(WallpaperPickerActivity a) {} - public void onSave(WallpaperPickerActivity a) {} - public void onDelete(WallpaperPickerActivity a) {} - public boolean isSelectable() { return false; } - public boolean isNamelessWallpaper() { return false; } - public void onIndexUpdated(CharSequence label) { - if (isNamelessWallpaper()) { - mView.setContentDescription(label); - } - } - } - - public static class PickImageInfo extends WallpaperTileInfo { - @Override - public void onClick(WallpaperPickerActivity a) { - Intent intent = new Intent(Intent.ACTION_GET_CONTENT); - intent.setType("image/*"); - a.startActivityForResultSafely(intent, IMAGE_PICK); - } - } - - public static class UriWallpaperInfo extends WallpaperTileInfo { - private Uri mUri; - public UriWallpaperInfo(Uri uri) { - mUri = uri; - } - @Override - public void onClick(final WallpaperPickerActivity a) { - a.setWallpaperButtonEnabled(false); - final BitmapRegionTileSource.UriBitmapSource bitmapSource = - new BitmapRegionTileSource.UriBitmapSource(a.getContext(), mUri); - a.setCropViewTileSource(bitmapSource, true, false, null, new Runnable() { - - @Override - public void run() { - if (bitmapSource.getLoadingState() == BitmapSource.State.LOADED) { - a.selectTile(mView); - a.setWallpaperButtonEnabled(true); - } else { - ViewGroup parent = (ViewGroup) mView.getParent(); - if (parent != null) { - parent.removeView(mView); - Toast.makeText(a.getContext(), R.string.image_load_fail, - Toast.LENGTH_SHORT).show(); - } - } - } - }); - } - @Override - public void onSave(final WallpaperPickerActivity a) { - boolean finishActivityWhenDone = true; - BitmapCropTask.OnBitmapCroppedHandler h = new BitmapCropTask.OnBitmapCroppedHandler() { - public void onBitmapCropped(byte[] imageBytes) { - Point thumbSize = getDefaultThumbnailSize(a.getResources()); - // rotation is set to 0 since imageBytes has already been correctly rotated - Bitmap thumb = createThumbnail( - thumbSize, null, null, imageBytes, null, 0, 0, true); - a.getSavedImages().writeImage(thumb, imageBytes); - } - }; - a.cropImageAndSetWallpaper(mUri, h, finishActivityWhenDone); - } - @Override - public boolean isSelectable() { - return true; - } - @Override - public boolean isNamelessWallpaper() { - return true; - } - } - - public static class FileWallpaperInfo extends WallpaperTileInfo { - private File mFile; - - public FileWallpaperInfo(File target, Drawable thumb) { - mFile = target; - mThumb = thumb; - } - @Override - public void onClick(final WallpaperPickerActivity a) { - a.setWallpaperButtonEnabled(false); - final BitmapRegionTileSource.FilePathBitmapSource bitmapSource = - new BitmapRegionTileSource.FilePathBitmapSource(mFile.getAbsolutePath()); - a.setCropViewTileSource(bitmapSource, false, true, null, new Runnable() { - - @Override - public void run() { - if (bitmapSource.getLoadingState() == BitmapSource.State.LOADED) { - a.setWallpaperButtonEnabled(true); - } - } - }); - } - @Override - public void onSave(WallpaperPickerActivity a) { - a.setWallpaper(Uri.fromFile(mFile), true); - } - @Override - public boolean isSelectable() { - return true; - } - @Override - public boolean isNamelessWallpaper() { - return true; - } - } - - public static class ResourceWallpaperInfo extends WallpaperTileInfo { - private Resources mResources; - private int mResId; - - public ResourceWallpaperInfo(Resources res, int resId, Drawable thumb) { - mResources = res; - mResId = resId; - mThumb = thumb; - } - @Override - public void onClick(final WallpaperPickerActivity a) { - a.setWallpaperButtonEnabled(false); - final BitmapRegionTileSource.ResourceBitmapSource bitmapSource = - new BitmapRegionTileSource.ResourceBitmapSource(mResources, mResId, a); - a.setCropViewTileSource(bitmapSource, false, false, new CropViewScaleProvider() { - - @Override - public float getScale(TileSource src) { - Point wallpaperSize = WallpaperUtils.getDefaultWallpaperSize( - a.getResources(), a.getWindowManager()); - RectF crop = Utils.getMaxCropRect( - src.getImageWidth(), src.getImageHeight(), - wallpaperSize.x, wallpaperSize.y, false); - return wallpaperSize.x / crop.width(); - } - }, new Runnable() { - - @Override - public void run() { - if (bitmapSource.getLoadingState() == BitmapSource.State.LOADED) { - a.setWallpaperButtonEnabled(true); - } - } - }); - } - @Override - public void onSave(WallpaperPickerActivity a) { - boolean finishActivityWhenDone = true; - a.cropImageAndSetWallpaper(mResources, mResId, finishActivityWhenDone); - } - @Override - public boolean isSelectable() { - return true; - } - @Override - public boolean isNamelessWallpaper() { - return true; - } - } - - @TargetApi(Build.VERSION_CODES.KITKAT) - public static class DefaultWallpaperInfo extends WallpaperTileInfo { - public DefaultWallpaperInfo(Drawable thumb) { - mThumb = thumb; - } - @Override - public void onClick(WallpaperPickerActivity a) { - CropView c = a.getCropView(); - Drawable defaultWallpaper = WallpaperManager.getInstance(a.getContext()) - .getBuiltInDrawable(c.getWidth(), c.getHeight(), false, 0.5f, 0.5f); - if (defaultWallpaper == null) { - Log.w(TAG, "Null default wallpaper encountered."); - c.setTileSource(null, null); - return; - } - - LoadRequest req = new LoadRequest(); - req.moveToLeft = false; - req.touchEnabled = false; - req.scaleProvider = new CropViewScaleProvider() { - - @Override - public float getScale(TileSource src) { - return 1f; - } - }; - req.result = new DrawableTileSource(a.getContext(), - defaultWallpaper, DrawableTileSource.MAX_PREVIEW_SIZE); - a.onLoadRequestComplete(req, true); - } - @Override - public void onSave(WallpaperPickerActivity a) { - try { - WallpaperManager.getInstance(a.getContext()).clear(); - a.setResult(Activity.RESULT_OK); - } catch (IOException e) { - Log.w("Setting wallpaper to default threw exception", e); - } - a.finish(); - } - @Override - public boolean isSelectable() { - return true; - } - @Override - public boolean isNamelessWallpaper() { - return true; - } - } - /** - * shows the system wallpaper behind the window and hides the {@link - * #mCropView} if visible + * shows the system wallpaper behind the window and hides the {@link #mCropView} if visible * @param visible should the system wallpaper be shown */ protected void setSystemWallpaperVisiblity(final boolean visible) { @@ -370,7 +122,9 @@ public class WallpaperPickerActivity extends WallpaperCropActivity { } } - // called by onCreate; this is subclassed to overwrite WallpaperCropActivity + /** + * called by onCreate; this is sub-classed to overwrite WallpaperCropActivity + */ protected void init() { setContentView(R.layout.wallpaper_picker); @@ -380,137 +134,37 @@ public class WallpaperPickerActivity extends WallpaperCropActivity { mProgressView = findViewById(R.id.loading); mWallpaperScrollContainer = (HorizontalScrollView) findViewById(R.id.wallpaper_scroll_container); mWallpaperStrip = findViewById(R.id.wallpaper_strip); - mCropView.setTouchCallback(new CropView.TouchCallback() { - ViewPropertyAnimator mAnim; - @Override - public void onTouchDown() { - if (mAnim != null) { - mAnim.cancel(); - } - if (mWallpaperStrip.getAlpha() == 1f) { - mIgnoreNextTap = true; - } - mAnim = mWallpaperStrip.animate(); - mAnim.alpha(0f) - .setDuration(150) - .withEndAction(new Runnable() { - public void run() { - mWallpaperStrip.setVisibility(View.INVISIBLE); - } - }); - mAnim.setInterpolator(new AccelerateInterpolator(0.75f)); - mAnim.start(); - } - @Override - public void onTouchUp() { - mIgnoreNextTap = false; - } - @Override - public void onTap() { - boolean ignoreTap = mIgnoreNextTap; - mIgnoreNextTap = false; - if (!ignoreTap) { - if (mAnim != null) { - mAnim.cancel(); - } - mWallpaperStrip.setVisibility(View.VISIBLE); - mAnim = mWallpaperStrip.animate(); - mAnim.alpha(1f) - .setDuration(150) - .setInterpolator(new DecelerateInterpolator(0.75f)); - mAnim.start(); - } - } - }); + mCropView.setTouchCallback(new ToggleOnTapCallback(mWallpaperStrip)); - mThumbnailOnClickListener = new OnClickListener() { - public void onClick(View v) { - if (mActionMode != null) { - // When CAB is up, clicking toggles the item instead - if (v.isLongClickable()) { - mLongClickListener.onLongClick(v); - } - return; - } - setWallpaperButtonEnabled(true); - WallpaperTileInfo info = (WallpaperTileInfo) v.getTag(); - if (info.isSelectable() && v.getVisibility() == View.VISIBLE) { - selectTile(v); - } - info.onClick(WallpaperPickerActivity.this); - } - }; - mLongClickListener = new View.OnLongClickListener() { - // Called when the user long-clicks on someView - public boolean onLongClick(View view) { - CheckableFrameLayout c = (CheckableFrameLayout) view; - c.toggle(); - - if (mActionMode != null) { - mActionMode.invalidate(); - } else { - // Start the CAB using the ActionMode.Callback defined below - mActionMode = startActionMode(mActionModeCallback); - int childCount = mWallpapersView.getChildCount(); - for (int i = 0; i < childCount; i++) { - mWallpapersView.getChildAt(i).setSelected(false); - } - } - return true; - } - }; + mWallpapersView = (LinearLayout) findViewById(R.id.wallpaper_list); + // Populate the saved wallpapers + mSavedImages = new SavedWallpaperImages(getContext()); + populateWallpapers(mWallpapersView, mSavedImages.loadThumbnailsAndImageIdList(), true); // Populate the built-in wallpapers ArrayList<WallpaperTileInfo> wallpapers = findBundledWallpapers(); - mWallpapersView = (LinearLayout) findViewById(R.id.wallpaper_list); - SimpleWallpapersAdapter ia = new SimpleWallpapersAdapter(getContext(), wallpapers); - populateWallpapersFromAdapter(mWallpapersView, ia, false); + populateWallpapers(mWallpapersView, wallpapers, false); - // Populate the saved wallpapers - mSavedImages = new SavedWallpaperImages(getContext()); - mSavedImages.loadThumbnailsAndImageIdList(); - populateWallpapersFromAdapter(mWallpapersView, mSavedImages, true); + // Load live wallpapers asynchronously + new LiveWallpaperInfo.LoaderTask(this) { - // Populate the live wallpapers - final LinearLayout liveWallpapersView = - (LinearLayout) findViewById(R.id.live_wallpaper_list); - final LiveWallpaperListAdapter a = new LiveWallpaperListAdapter(getContext()); - a.registerDataSetObserver(new DataSetObserver() { - public void onChanged() { - liveWallpapersView.removeAllViews(); - populateWallpapersFromAdapter(liveWallpapersView, a, false); + @Override + protected void onPostExecute(List<LiveWallpaperInfo> result) { + populateWallpapers((LinearLayout) findViewById(R.id.live_wallpaper_list), + result, false); initializeScrollForRtl(); updateTileIndices(); } - }); + }.execute(); // Populate the third-party wallpaper pickers - final LinearLayout thirdPartyWallpapersView = - (LinearLayout) findViewById(R.id.third_party_wallpaper_list); - final ThirdPartyWallpaperPickerListAdapter ta = - new ThirdPartyWallpaperPickerListAdapter(getContext()); - populateWallpapersFromAdapter(thirdPartyWallpapersView, ta, false); + populateWallpapers((LinearLayout) findViewById(R.id.third_party_wallpaper_list), + ThirdPartyWallpaperInfo.getAll(this), false); // Add a tile for the Gallery LinearLayout masterWallpaperList = (LinearLayout) findViewById(R.id.master_wallpaper_list); - FrameLayout pickImageTile = (FrameLayout) getLayoutInflater(). - inflate(R.layout.wallpaper_picker_image_picker_item, masterWallpaperList, false); - masterWallpaperList.addView(pickImageTile, 0); - - // Make its background the last photo taken on external storage - Bitmap lastPhoto = getThumbnailOfLastPhoto(); - if (lastPhoto != null) { - ImageView galleryThumbnailBg = - (ImageView) pickImageTile.findViewById(R.id.wallpaper_image); - galleryThumbnailBg.setImageBitmap(lastPhoto); - int colorOverlay = getResources().getColor(R.color.wallpaper_picker_translucent_gray); - galleryThumbnailBg.setColorFilter(colorOverlay, PorterDuff.Mode.SRC_ATOP); - } - - PickImageInfo pickImageInfo = new PickImageInfo(); - pickImageTile.setTag(pickImageInfo); - pickImageInfo.setView(pickImageTile); - pickImageTile.setOnClickListener(mThumbnailOnClickListener); + masterWallpaperList.addView( + createTileView(masterWallpaperList, new PickImageInfo(), false), 0); // Select the first item; wait for a layout pass so that we initialize the dimensions of // cropView or the defaultWallpaperView first @@ -520,8 +174,7 @@ public class WallpaperPickerActivity extends WallpaperCropActivity { int oldLeft, int oldTop, int oldRight, int oldBottom) { if ((right - left) > 0 && (bottom - top) > 0) { if (mSelectedIndex >= 0 && mSelectedIndex < mWallpapersView.getChildCount()) { - mThumbnailOnClickListener.onClick( - mWallpapersView.getChildAt(mSelectedIndex)); + onClick(mWallpapersView.getChildAt(mSelectedIndex)); setSystemWallpaperVisiblity(false); } v.removeOnLayoutChangeListener(this); @@ -565,102 +218,54 @@ public class WallpaperPickerActivity extends WallpaperCropActivity { } }); mSetWallpaperButton = findViewById(R.id.set_wallpaper_button); + } - // CAB for deleting items - mActionModeCallback = new ActionMode.Callback() { - // Called when the action mode is created; startActionMode() was called - @Override - public boolean onCreateActionMode(ActionMode mode, Menu menu) { - // Inflate a menu resource providing context menu items - MenuInflater inflater = mode.getMenuInflater(); - inflater.inflate(R.menu.cab_delete_wallpapers, menu); - return true; - } - - private int numCheckedItems() { - int childCount = mWallpapersView.getChildCount(); - int numCheckedItems = 0; - for (int i = 0; i < childCount; i++) { - CheckableFrameLayout c = (CheckableFrameLayout) mWallpapersView.getChildAt(i); - if (c.isChecked()) { - numCheckedItems++; - } - } - return numCheckedItems; - } - - // Called each time the action mode is shown. Always called after onCreateActionMode, - // but may be called multiple times if the mode is invalidated. - @Override - public boolean onPrepareActionMode(ActionMode mode, Menu menu) { - int numCheckedItems = numCheckedItems(); - if (numCheckedItems == 0) { - mode.finish(); - return true; - } else { - mode.setTitle(getResources().getQuantityString( - R.plurals.number_of_items_selected, numCheckedItems, numCheckedItems)); - return true; - } + /** + * Called when a wallpaper tile is clicked + */ + @Override + public void onClick(View v) { + if (mActionMode != null) { + // When CAB is up, clicking toggles the item instead + if (v.isLongClickable()) { + onLongClick(v); } + return; + } + setWallpaperButtonEnabled(true); + WallpaperTileInfo info = (WallpaperTileInfo) v.getTag(); + if (info.isSelectable() && v.getVisibility() == View.VISIBLE) { + selectTile(v); + } + info.onClick(this); + } - // Called when the user selects a contextual menu item - @Override - public boolean onActionItemClicked(ActionMode mode, MenuItem item) { - int itemId = item.getItemId(); - if (itemId == R.id.menu_delete) { - int childCount = mWallpapersView.getChildCount(); - ArrayList<View> viewsToRemove = new ArrayList<View>(); - boolean selectedTileRemoved = false; - for (int i = 0; i < childCount; i++) { - CheckableFrameLayout c = - (CheckableFrameLayout) mWallpapersView.getChildAt(i); - if (c.isChecked()) { - WallpaperTileInfo info = (WallpaperTileInfo) c.getTag(); - info.onDelete(WallpaperPickerActivity.this); - viewsToRemove.add(c); - if (i == mSelectedIndex) { - selectedTileRemoved = true; - } - } - } - for (View v : viewsToRemove) { - mWallpapersView.removeView(v); - } - if (selectedTileRemoved) { - mSelectedIndex = -1; - mSelectedTile = null; - setSystemWallpaperVisiblity(true); - } - updateTileIndices(); - mode.finish(); // Action picked, so close the CAB - return true; - } else { - return false; - } - } + /** + * Called when a view is long clicked + */ + @Override + public boolean onLongClick(View v) { + CheckableFrameLayout c = (CheckableFrameLayout) v; + c.toggle(); - // Called when the user exits the action mode - @Override - public void onDestroyActionMode(ActionMode mode) { - int childCount = mWallpapersView.getChildCount(); - for (int i = 0; i < childCount; i++) { - CheckableFrameLayout c = (CheckableFrameLayout) mWallpapersView.getChildAt(i); - c.setChecked(false); - } - if (mSelectedTile != null) { - mSelectedTile.setSelected(true); - } - mActionMode = null; + if (mActionMode != null) { + mActionMode.invalidate(); + } else { + // Start the CAB using the ActionMode.Callback defined below + mActionMode = startActionMode(this); + int childCount = mWallpapersView.getChildCount(); + for (int i = 0; i < childCount; i++) { + mWallpapersView.getChildAt(i).setSelected(false); } - }; + } + return true; } public void setWallpaperButtonEnabled(boolean enabled) { mSetWallpaperButton.setEnabled(enabled); } - @Thunk void selectTile(View v) { + public void selectTile(View v) { if (mSelectedTile != null) { mSelectedTile.setSelected(false); mSelectedTile = null; @@ -688,35 +293,6 @@ public class WallpaperPickerActivity extends WallpaperCropActivity { } } - protected Bitmap getThumbnailOfLastPhoto() { - boolean canReadExternalStorage = getActivity().checkPermission( - Manifest.permission.READ_EXTERNAL_STORAGE, Process.myPid(), Process.myUid()) == - PackageManager.PERMISSION_GRANTED; - - if (!canReadExternalStorage) { - // MediaStore.Images.Media.EXTERNAL_CONTENT_URI requires - // the READ_EXTERNAL_STORAGE permission - return null; - } - - Cursor cursor = MediaStore.Images.Media.query(getContext().getContentResolver(), - MediaStore.Images.Media.EXTERNAL_CONTENT_URI, - new String[] { MediaStore.Images.ImageColumns._ID, - MediaStore.Images.ImageColumns.DATE_TAKEN}, - null, null, MediaStore.Images.ImageColumns.DATE_TAKEN + " DESC LIMIT 1"); - - Bitmap thumb = null; - if (cursor != null) { - if (cursor.moveToNext()) { - int id = cursor.getInt(0); - thumb = MediaStore.Images.Thumbnails.getThumbnail(getContext().getContentResolver(), - id, MediaStore.Images.Thumbnails.MINI_KIND, null); - } - cursor.close(); - } - return thumb; - } - public void onStop() { super.onStop(); mWallpaperStrip = findViewById(R.id.wallpaper_strip); @@ -739,21 +315,6 @@ public class WallpaperPickerActivity extends WallpaperCropActivity { mSelectedIndex = savedInstanceState.getInt(SELECTED_INDEX, -1); } - @Thunk void populateWallpapersFromAdapter(ViewGroup parent, BaseAdapter adapter, - boolean addLongPressHandler) { - for (int i = 0; i < adapter.getCount(); i++) { - FrameLayout thumbnail = (FrameLayout) adapter.getView(i, null, parent); - parent.addView(thumbnail, i); - WallpaperTileInfo info = (WallpaperTileInfo) adapter.getItem(i); - thumbnail.setTag(info); - info.setView(thumbnail); - if (addLongPressHandler) { - addLongPressHandler(thumbnail); - } - thumbnail.setOnClickListener(mThumbnailOnClickListener); - } - } - @Thunk void updateTileIndices() { LinearLayout masterWallpaperList = (LinearLayout) findViewById(R.id.master_wallpaper_list); final int childCount = masterWallpaperList.getChildCount(); @@ -795,126 +356,71 @@ public class WallpaperPickerActivity extends WallpaperCropActivity { } } - @Thunk static Point getDefaultThumbnailSize(Resources res) { - return new Point(res.getDimensionPixelSize(R.dimen.wallpaperThumbnailWidth), - res.getDimensionPixelSize(R.dimen.wallpaperThumbnailHeight)); - - } - - @Thunk static Bitmap createThumbnail(Point size, Context context, Uri uri, byte[] imageBytes, - Resources res, int resId, int rotation, boolean leftAligned) { - int width = size.x; - int height = size.y; - - BitmapCropTask cropTask; - if (uri != null) { - cropTask = new BitmapCropTask( - context, uri, null, rotation, width, height, false, true, null); - } else if (imageBytes != null) { - cropTask = new BitmapCropTask( - imageBytes, null, rotation, width, height, false, true, null); - } else { - cropTask = new BitmapCropTask( - context, res, resId, null, rotation, width, height, false, true, null); - } - Point bounds = cropTask.getImageBounds(); - if (bounds == null || bounds.x == 0 || bounds.y == 0) { - return null; - } - - Matrix rotateMatrix = new Matrix(); - rotateMatrix.setRotate(rotation); - float[] rotatedBounds = new float[] { bounds.x, bounds.y }; - rotateMatrix.mapPoints(rotatedBounds); - rotatedBounds[0] = Math.abs(rotatedBounds[0]); - rotatedBounds[1] = Math.abs(rotatedBounds[1]); - - RectF cropRect = Utils.getMaxCropRect( - (int) rotatedBounds[0], (int) rotatedBounds[1], width, height, leftAligned); - cropTask.setCropBounds(cropRect); - - if (cropTask.cropBitmap()) { - return cropTask.getCroppedBitmap(); - } else { - return null; - } - } - private void addTemporaryWallpaperTile(final Uri uri, boolean fromRestore) { + // Add a tile for the image picked from Gallery, reusing the existing tile if there is one. - FrameLayout existingImageThumbnail = null; + View existingTile = null; int indexOfExistingTile = 0; for (; indexOfExistingTile < mWallpapersView.getChildCount(); indexOfExistingTile++) { - FrameLayout thumbnail = (FrameLayout) mWallpapersView.getChildAt(indexOfExistingTile); + View thumbnail = mWallpapersView.getChildAt(indexOfExistingTile); Object tag = thumbnail.getTag(); if (tag instanceof UriWallpaperInfo && ((UriWallpaperInfo) tag).mUri.equals(uri)) { - existingImageThumbnail = thumbnail; + existingTile = thumbnail; break; } } - final FrameLayout pickedImageThumbnail; - if (existingImageThumbnail != null) { - pickedImageThumbnail = existingImageThumbnail; + final View pickedImageThumbnail; + final UriWallpaperInfo info; + if (existingTile != null) { + pickedImageThumbnail = existingTile; // Always move the existing wallpaper to the front so user can see it without scrolling. mWallpapersView.removeViewAt(indexOfExistingTile); - mWallpapersView.addView(existingImageThumbnail, 0); + mWallpapersView.addView(pickedImageThumbnail, 0); + info = (UriWallpaperInfo) pickedImageThumbnail.getTag(); } else { // This is the first time this temporary wallpaper has been added - pickedImageThumbnail = (FrameLayout) getLayoutInflater() - .inflate(R.layout.wallpaper_picker_item, mWallpapersView, false); - pickedImageThumbnail.setVisibility(View.GONE); + info = new UriWallpaperInfo(uri); + pickedImageThumbnail = createTileView(mWallpapersView, info, true); mWallpapersView.addView(pickedImageThumbnail, 0); mTempWallpaperTiles.add(uri); } + info.loadThumbnaleAsync(this); - // Load the thumbnail - final ImageView image = (ImageView) pickedImageThumbnail.findViewById(R.id.wallpaper_image); - final Point defaultSize = getDefaultThumbnailSize(this.getResources()); - final Context context = getContext(); - new AsyncTask<Void, Bitmap, Bitmap>() { - protected Bitmap doInBackground(Void...args) { - try { - int rotation = BitmapUtils.getRotationFromExif(context, uri); - return createThumbnail(defaultSize, context, uri, null, null, 0, rotation, - false); - } catch (SecurityException securityException) { - if (isActivityDestroyed()) { - // Temporarily granted permissions are revoked when the activity - // finishes, potentially resulting in a SecurityException here. - // Even though {@link #isDestroyed} might also return true in different - // situations where the configuration changes, we are fine with - // catching these cases here as well. - cancel(false); - } else { - // otherwise it had a different cause and we throw it further - throw securityException; - } - return null; - } - } - protected void onPostExecute(Bitmap thumb) { - if (!isCancelled() && thumb != null) { - image.setImageBitmap(thumb); - Drawable thumbDrawable = image.getDrawable(); - thumbDrawable.setDither(true); - pickedImageThumbnail.setVisibility(View.VISIBLE); - } else { - Log.e(TAG, "Error loading thumbnail for uri=" + uri); - } - } - }.execute(); - - UriWallpaperInfo info = new UriWallpaperInfo(uri); - pickedImageThumbnail.setTag(info); - info.setView(pickedImageThumbnail); - addLongPressHandler(pickedImageThumbnail); updateTileIndices(); - pickedImageThumbnail.setOnClickListener(mThumbnailOnClickListener); if (!fromRestore) { - mThumbnailOnClickListener.onClick(pickedImageThumbnail); + onClick(existingTile); + } + } + + @Thunk void populateWallpapers(ViewGroup parent, List<? extends WallpaperTileInfo> wallpapers, + boolean addLongPressHandler) { + for (WallpaperTileInfo info : wallpapers) { + parent.addView(createTileView(parent, info, addLongPressHandler)); } } + private View createTileView(ViewGroup parent, WallpaperTileInfo info, boolean addLongPress) { + View view = info.createView(this, getLayoutInflater(), parent); + view.setTag(info); + + if (addLongPress) { + view.setOnLongClickListener(this); + + // Enable stylus button to also trigger long click. + final StylusEventHelper stylusEventHelper = + new StylusEventHelper(new SimpleOnStylusPressListener(view), view); + view.setOnTouchListener(new View.OnTouchListener() { + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View view, MotionEvent event) { + return stylusEventHelper.onMotionEvent(event); + } + }); + } + view.setOnClickListener(this); + return view; + } + public void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == IMAGE_PICK && resultCode == Activity.RESULT_OK) { if (data != null && data.getData() != null) { @@ -929,20 +435,6 @@ public class WallpaperPickerActivity extends WallpaperCropActivity { } } - private void addLongPressHandler(View v) { - v.setOnLongClickListener(mLongClickListener); - - // Enable stylus button to also trigger long click. - final StylusEventHelper stylusEventHelper = - new StylusEventHelper(new SimpleOnStylusPressListener(v), v); - v.setOnTouchListener(new View.OnTouchListener() { - @Override - public boolean onTouch(View view, MotionEvent event) { - return stylusEventHelper.onMotionEvent(event); - } - }); - } - private ArrayList<WallpaperTileInfo> findBundledWallpapers() { final PackageManager pm = getContext().getPackageManager(); final ArrayList<WallpaperTileInfo> bundled = new ArrayList<WallpaperTileInfo>(24); @@ -979,26 +471,28 @@ public class WallpaperPickerActivity extends WallpaperCropActivity { File thumbnail = new File(systemDir, name + "_small" + extension); Bitmap thumb = BitmapFactory.decodeFile(thumbnail.getAbsolutePath()); if (thumb != null) { - bundled.add(new FileWallpaperInfo(file, new BitmapDrawable(thumb))); + bundled.add(new FileWallpaperInfo( + file, new BitmapDrawable(getResources(), thumb))); } } } } - Pair<ApplicationInfo, Integer> r = getWallpaperArrayResourceId(); - if (r != null) { - try { - Resources wallpaperRes = getContext().getPackageManager() - .getResourcesForApplication(r.first); - addWallpapers(bundled, wallpaperRes, r.first.packageName, r.second); - } catch (PackageManager.NameNotFoundException e) { - } - } + // Context.getPackageName() may return the "original" package name, + // com.android.launcher3; Resources needs the real package name, + // com.android.launcher3. So we ask Resources for what it thinks the + // package name should be. + try { + final String packageName = getResources().getResourcePackageName(R.array.wallpapers); + ApplicationInfo info = getPackageManager().getApplicationInfo(packageName, 0); + Resources wallpaperRes = getContext().getPackageManager() + .getResourcesForApplication(info); + addWallpapers(bundled, wallpaperRes, info.packageName, R.array.wallpapers); + } catch (PackageManager.NameNotFoundException e) { } if (partner == null || !partner.hideDefaultWallpaper()) { // Add an entry for the default wallpaper (stored in system resources) - WallpaperTileInfo defaultWallpaperInfo = Utilities.ATLEAST_KITKAT - ? getDefaultWallpaper() : getPreKKDefaultWallpaperInfo(); + WallpaperTileInfo defaultWallpaperInfo = DefaultWallpaperInfo.get(this); if (defaultWallpaperInfo != null) { bundled.add(0, defaultWallpaperInfo); } @@ -1006,109 +500,6 @@ public class WallpaperPickerActivity extends WallpaperCropActivity { return bundled; } - private boolean writeImageToFileAsJpeg(File f, Bitmap b) { - try { - f.createNewFile(); - FileOutputStream thumbFileStream = - getContext().openFileOutput(f.getName(), Context.MODE_PRIVATE); - b.compress(Bitmap.CompressFormat.JPEG, 95, thumbFileStream); - thumbFileStream.close(); - return true; - } catch (IOException e) { - Log.e(TAG, "Error while writing bitmap to file " + e); - f.delete(); - } - return false; - } - - private File getDefaultThumbFile() { - return new File(getContext().getFilesDir(), Build.VERSION.SDK_INT - + "_" + LauncherFiles.DEFAULT_WALLPAPER_THUMBNAIL); - } - - private boolean saveDefaultWallpaperThumb(Bitmap b) { - // Delete old thumbnails. - new File(getContext().getFilesDir(), LauncherFiles.DEFAULT_WALLPAPER_THUMBNAIL_OLD).delete(); - new File(getContext().getFilesDir(), LauncherFiles.DEFAULT_WALLPAPER_THUMBNAIL).delete(); - - for (int i = Build.VERSION_CODES.JELLY_BEAN; i < Build.VERSION.SDK_INT; i++) { - new File(getContext().getFilesDir(), i + "_" - + LauncherFiles.DEFAULT_WALLPAPER_THUMBNAIL).delete(); - } - return writeImageToFileAsJpeg(getDefaultThumbFile(), b); - } - - private ResourceWallpaperInfo getPreKKDefaultWallpaperInfo() { - Resources sysRes = Resources.getSystem(); - int resId = sysRes.getIdentifier("default_wallpaper", "drawable", "android"); - - File defaultThumbFile = getDefaultThumbFile(); - Bitmap thumb = null; - boolean defaultWallpaperExists = false; - if (defaultThumbFile.exists()) { - thumb = BitmapFactory.decodeFile(defaultThumbFile.getAbsolutePath()); - defaultWallpaperExists = true; - } else { - Resources res = getResources(); - Point defaultThumbSize = getDefaultThumbnailSize(res); - int rotation = BitmapUtils.getRotationFromExif(res, resId, this); - thumb = createThumbnail( - defaultThumbSize, getContext(), null, null, sysRes, resId, rotation, false); - if (thumb != null) { - defaultWallpaperExists = saveDefaultWallpaperThumb(thumb); - } - } - if (defaultWallpaperExists) { - return new ResourceWallpaperInfo(sysRes, resId, new BitmapDrawable(thumb)); - } - return null; - } - - @TargetApi(Build.VERSION_CODES.KITKAT) - private DefaultWallpaperInfo getDefaultWallpaper() { - File defaultThumbFile = getDefaultThumbFile(); - Bitmap thumb = null; - boolean defaultWallpaperExists = false; - if (defaultThumbFile.exists()) { - thumb = BitmapFactory.decodeFile(defaultThumbFile.getAbsolutePath()); - defaultWallpaperExists = true; - } else { - Resources res = getResources(); - Point defaultThumbSize = getDefaultThumbnailSize(res); - Drawable wallpaperDrawable = WallpaperManager.getInstance(getContext()).getBuiltInDrawable( - defaultThumbSize.x, defaultThumbSize.y, true, 0.5f, 0.5f); - if (wallpaperDrawable != null) { - thumb = Bitmap.createBitmap( - defaultThumbSize.x, defaultThumbSize.y, Bitmap.Config.ARGB_8888); - Canvas c = new Canvas(thumb); - wallpaperDrawable.setBounds(0, 0, defaultThumbSize.x, defaultThumbSize.y); - wallpaperDrawable.draw(c); - c.setBitmap(null); - } - if (thumb != null) { - defaultWallpaperExists = saveDefaultWallpaperThumb(thumb); - } - } - if (defaultWallpaperExists) { - return new DefaultWallpaperInfo(new BitmapDrawable(thumb)); - } - return null; - } - - public Pair<ApplicationInfo, Integer> getWallpaperArrayResourceId() { - // Context.getPackageName() may return the "original" package name, - // com.android.launcher3; Resources needs the real package name, - // com.android.launcher3. So we ask Resources for what it thinks the - // package name should be. - final String packageName = getResources().getResourcePackageName(R.array.wallpapers); - try { - ApplicationInfo info = getContext().getPackageManager().getApplicationInfo(packageName, 0); - return new Pair<ApplicationInfo, Integer>(info, R.array.wallpapers); - } catch (PackageManager.NameNotFoundException e) { - return null; - } - } - private void addWallpapers(ArrayList<WallpaperTileInfo> known, Resources res, String packageName, int listResId) { final String[] extras = res.getStringArray(listResId); @@ -1129,61 +520,111 @@ public class WallpaperPickerActivity extends WallpaperCropActivity { } } - public CropView getCropView() { - return mCropView; - } - public SavedWallpaperImages getSavedImages() { return mSavedImages; } - private static class SimpleWallpapersAdapter extends ArrayAdapter<WallpaperTileInfo> { - private final LayoutInflater mLayoutInflater; - - SimpleWallpapersAdapter(Context context, ArrayList<WallpaperTileInfo> wallpapers) { - super(context, R.layout.wallpaper_picker_item, wallpapers); - mLayoutInflater = LayoutInflater.from(context); - } + public void startActivityForResultSafely(Intent intent, int requestCode) { + Utilities.startActivityForResultSafely(getActivity(), intent, requestCode); + } - public View getView(int position, View convertView, ViewGroup parent) { - Drawable thumb = getItem(position).mThumb; - if (thumb == null) { - Log.e(TAG, "Error decoding thumbnail for wallpaper #" + position); - } - return createImageTileView(mLayoutInflater, convertView, parent, thumb); - } + @Override + public boolean enableRotation() { + return super.enableRotation() || + getContentResolver().call(LauncherSettings.Settings.CONTENT_URI, + LauncherSettings.Settings.METHOD_GET_BOOLEAN, + Utilities.ALLOW_ROTATION_PREFERENCE_KEY, new Bundle()) + .getBoolean(LauncherSettings.Settings.EXTRA_VALUE); } - public static View createImageTileView(LayoutInflater layoutInflater, - View convertView, ViewGroup parent, Drawable thumb) { - View view; + // CAB for deleting items + /** + * Called when the action mode is created; startActionMode() was called + */ + @Override + public boolean onCreateActionMode(ActionMode mode, Menu menu) { + // Inflate a menu resource providing context menu items + MenuInflater inflater = mode.getMenuInflater(); + inflater.inflate(R.menu.cab_delete_wallpapers, menu); + return true; + } - if (convertView == null) { - view = layoutInflater.inflate(R.layout.wallpaper_picker_item, parent, false); - } else { - view = convertView; + /** + * Called each time the action mode is shown. Always called after onCreateActionMode, + * but may be called multiple times if the mode is invalidated. + */ + @Override + public boolean onPrepareActionMode(ActionMode mode, Menu menu) { + int childCount = mWallpapersView.getChildCount(); + int numCheckedItems = 0; + for (int i = 0; i < childCount; i++) { + CheckableFrameLayout c = (CheckableFrameLayout) mWallpapersView.getChildAt(i); + if (c.isChecked()) { + numCheckedItems++; + } } - ImageView image = (ImageView) view.findViewById(R.id.wallpaper_image); - - if (thumb != null) { - image.setImageDrawable(thumb); - thumb.setDither(true); + if (numCheckedItems == 0) { + mode.finish(); + return true; + } else { + mode.setTitle(getResources().getQuantityString( + R.plurals.number_of_items_selected, numCheckedItems, numCheckedItems)); + return true; } - - return view; } - public void startActivityForResultSafely(Intent intent, int requestCode) { - Utilities.startActivityForResultSafely(getActivity(), intent, requestCode); + /** + * Called when the user selects a contextual menu item + */ + @Override + public boolean onActionItemClicked(ActionMode mode, MenuItem item) { + int itemId = item.getItemId(); + if (itemId == R.id.menu_delete) { + int childCount = mWallpapersView.getChildCount(); + ArrayList<View> viewsToRemove = new ArrayList<View>(); + boolean selectedTileRemoved = false; + for (int i = 0; i < childCount; i++) { + CheckableFrameLayout c = + (CheckableFrameLayout) mWallpapersView.getChildAt(i); + if (c.isChecked()) { + WallpaperTileInfo info = (WallpaperTileInfo) c.getTag(); + info.onDelete(WallpaperPickerActivity.this); + viewsToRemove.add(c); + if (i == mSelectedIndex) { + selectedTileRemoved = true; + } + } + } + for (View v : viewsToRemove) { + mWallpapersView.removeView(v); + } + if (selectedTileRemoved) { + mSelectedIndex = -1; + mSelectedTile = null; + setSystemWallpaperVisiblity(true); + } + updateTileIndices(); + mode.finish(); // Action picked, so close the CAB + return true; + } else { + return false; + } } + /** + * Called when the user exits the action mode + */ @Override - public boolean enableRotation() { - return super.enableRotation() || - getContentResolver().call(LauncherSettings.Settings.CONTENT_URI, - LauncherSettings.Settings.METHOD_GET_BOOLEAN, - Utilities.ALLOW_ROTATION_PREFERENCE_KEY, new Bundle()) - .getBoolean(LauncherSettings.Settings.EXTRA_VALUE); + public void onDestroyActionMode(ActionMode mode) { + int childCount = mWallpapersView.getChildCount(); + for (int i = 0; i < childCount; i++) { + CheckableFrameLayout c = (CheckableFrameLayout) mWallpapersView.getChildAt(i); + c.setChecked(false); + } + if (mSelectedTile != null) { + mSelectedTile.setSelected(true); + } + mActionMode = null; } } diff --git a/WallpaperPicker/src/com/android/launcher3/wallpapertileinfo/DefaultWallpaperInfo.java b/WallpaperPicker/src/com/android/launcher3/wallpapertileinfo/DefaultWallpaperInfo.java new file mode 100644 index 000000000..49310b089 --- /dev/null +++ b/WallpaperPicker/src/com/android/launcher3/wallpapertileinfo/DefaultWallpaperInfo.java @@ -0,0 +1,159 @@ +package com.android.launcher3.wallpapertileinfo; + +import android.annotation.TargetApi; +import android.app.Activity; +import android.app.WallpaperManager; +import android.content.Context; +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.Canvas; +import android.graphics.Point; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.Drawable; +import android.os.Build; +import android.util.Log; + +import com.android.gallery3d.common.BitmapUtils; +import com.android.launcher3.LauncherFiles; +import com.android.launcher3.Utilities; +import com.android.launcher3.WallpaperCropActivity.CropViewScaleProvider; +import com.android.launcher3.WallpaperPickerActivity; +import com.android.photos.views.TiledImageRenderer.TileSource; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; + +public class DefaultWallpaperInfo extends DrawableThumbWallpaperInfo { + + private static final String TAG = "DefaultWallpaperInfo"; + + public DefaultWallpaperInfo(Drawable thumb) { + super(thumb); + } + + @Override + public void onClick(WallpaperPickerActivity a) { + a.setCropViewTileSource(null, false, false, new CropViewScaleProvider() { + + @Override + public float getScale(TileSource src) { + return 1f; + } + }, null); + } + + @Override + public void onSave(WallpaperPickerActivity a) { + try { + WallpaperManager.getInstance(a.getContext()).clear(); + a.setResult(Activity.RESULT_OK); + } catch (IOException e) { + Log.w(TAG, "Setting wallpaper to default threw exception", e); + } + a.finish(); + } + + @Override + public boolean isSelectable() { + return true; + } + + @Override + public boolean isNamelessWallpaper() { + return true; + } + + /** + * @return the system default wallpaper tile or null + */ + public static WallpaperTileInfo get(Context context) { + return Utilities.ATLEAST_KITKAT + ? getDefaultWallpaper(context) : getPreKKDefaultWallpaperInfo(context); + } + + @TargetApi(Build.VERSION_CODES.KITKAT) + private static DefaultWallpaperInfo getDefaultWallpaper(Context context) { + File defaultThumbFile = getDefaultThumbFile(context); + Bitmap thumb = null; + boolean defaultWallpaperExists = false; + Resources res = context.getResources(); + + if (defaultThumbFile.exists()) { + thumb = BitmapFactory.decodeFile(defaultThumbFile.getAbsolutePath()); + defaultWallpaperExists = true; + } else { + Point defaultThumbSize = getDefaultThumbSize(res); + Drawable wallpaperDrawable = WallpaperManager.getInstance(context).getBuiltInDrawable( + defaultThumbSize.x, defaultThumbSize.y, true, 0.5f, 0.5f); + if (wallpaperDrawable != null) { + thumb = Bitmap.createBitmap( + defaultThumbSize.x, defaultThumbSize.y, Bitmap.Config.ARGB_8888); + Canvas c = new Canvas(thumb); + wallpaperDrawable.setBounds(0, 0, defaultThumbSize.x, defaultThumbSize.y); + wallpaperDrawable.draw(c); + c.setBitmap(null); + } + if (thumb != null) { + defaultWallpaperExists = saveDefaultWallpaperThumb(context, thumb); + } + } + if (defaultWallpaperExists) { + return new DefaultWallpaperInfo(new BitmapDrawable(res, thumb)); + } + return null; + } + + private static ResourceWallpaperInfo getPreKKDefaultWallpaperInfo(Context context) { + Resources sysRes = Resources.getSystem(); + Resources res = context.getResources(); + + int resId = sysRes.getIdentifier("default_wallpaper", "drawable", "android"); + + File defaultThumbFile = getDefaultThumbFile(context); + Bitmap thumb = null; + boolean defaultWallpaperExists = false; + if (defaultThumbFile.exists()) { + thumb = BitmapFactory.decodeFile(defaultThumbFile.getAbsolutePath()); + defaultWallpaperExists = true; + } else { + int rotation = BitmapUtils.getRotationFromExif(res, resId, context); + thumb = createThumbnail(context, null, null, sysRes, resId, rotation, false); + if (thumb != null) { + defaultWallpaperExists = saveDefaultWallpaperThumb(context, thumb); + } + } + if (defaultWallpaperExists) { + return new ResourceWallpaperInfo(sysRes, resId, new BitmapDrawable(res, thumb)); + } + return null; + } + + private static File getDefaultThumbFile(Context context) { + return new File(context.getFilesDir(), Build.VERSION.SDK_INT + + "_" + LauncherFiles.DEFAULT_WALLPAPER_THUMBNAIL); + } + + private static boolean saveDefaultWallpaperThumb(Context c, Bitmap b) { + // Delete old thumbnails. + new File(c.getFilesDir(), LauncherFiles.DEFAULT_WALLPAPER_THUMBNAIL_OLD).delete(); + new File(c.getFilesDir(), LauncherFiles.DEFAULT_WALLPAPER_THUMBNAIL).delete(); + + for (int i = Build.VERSION_CODES.JELLY_BEAN; i < Build.VERSION.SDK_INT; i++) { + new File(c.getFilesDir(), i + "_" + LauncherFiles.DEFAULT_WALLPAPER_THUMBNAIL).delete(); + } + File f = getDefaultThumbFile(c); + try { + f.createNewFile(); + FileOutputStream thumbFileStream = c.openFileOutput(f.getName(), Context.MODE_PRIVATE); + b.compress(Bitmap.CompressFormat.JPEG, 95, thumbFileStream); + thumbFileStream.close(); + return true; + } catch (IOException e) { + Log.e(TAG, "Error while writing bitmap to file " + e); + f.delete(); + return false; + } + } +}
\ No newline at end of file diff --git a/WallpaperPicker/src/com/android/launcher3/wallpapertileinfo/DrawableThumbWallpaperInfo.java b/WallpaperPicker/src/com/android/launcher3/wallpapertileinfo/DrawableThumbWallpaperInfo.java new file mode 100644 index 000000000..a55375ddf --- /dev/null +++ b/WallpaperPicker/src/com/android/launcher3/wallpapertileinfo/DrawableThumbWallpaperInfo.java @@ -0,0 +1,37 @@ +package com.android.launcher3.wallpapertileinfo; + +import android.content.Context; +import android.graphics.drawable.Drawable; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; + +import com.android.launcher3.R; + +/** + * WallpaperTileInfo which uses drawable as the thumbnail. + */ +public abstract class DrawableThumbWallpaperInfo extends WallpaperTileInfo { + + private final Drawable mThumb; + + DrawableThumbWallpaperInfo(Drawable thumb) { + mThumb = thumb; + } + + @Override + public View createView(Context context, LayoutInflater inflator, ViewGroup parent) { + mView = inflator.inflate(R.layout.wallpaper_picker_item, parent, false); + setThumb(mThumb); + return mView; + } + + public void setThumb(Drawable thumb) { + if (mView != null && thumb != null) { + thumb.setDither(true); + ImageView image = (ImageView) mView.findViewById(R.id.wallpaper_image); + image.setImageDrawable(thumb); + } + } +} diff --git a/WallpaperPicker/src/com/android/launcher3/wallpapertileinfo/FileWallpaperInfo.java b/WallpaperPicker/src/com/android/launcher3/wallpapertileinfo/FileWallpaperInfo.java new file mode 100644 index 000000000..be93e1378 --- /dev/null +++ b/WallpaperPicker/src/com/android/launcher3/wallpapertileinfo/FileWallpaperInfo.java @@ -0,0 +1,51 @@ +package com.android.launcher3.wallpapertileinfo; + +import android.graphics.drawable.Drawable; +import android.net.Uri; + +import com.android.launcher3.WallpaperPickerActivity; +import com.android.photos.BitmapRegionTileSource; +import com.android.photos.BitmapRegionTileSource.BitmapSource; + +import java.io.File; + +public class FileWallpaperInfo extends DrawableThumbWallpaperInfo { + + private final File mFile; + + public FileWallpaperInfo(File target, Drawable thumb) { + super(thumb); + mFile = target; + } + + @Override + public void onClick(final WallpaperPickerActivity a) { + a.setWallpaperButtonEnabled(false); + final BitmapRegionTileSource.FilePathBitmapSource bitmapSource = + new BitmapRegionTileSource.FilePathBitmapSource(mFile.getAbsolutePath()); + a.setCropViewTileSource(bitmapSource, false, true, null, new Runnable() { + + @Override + public void run() { + if (bitmapSource.getLoadingState() == BitmapSource.State.LOADED) { + a.setWallpaperButtonEnabled(true); + } + } + }); + } + + @Override + public void onSave(WallpaperPickerActivity a) { + a.setWallpaper(Uri.fromFile(mFile)); + } + + @Override + public boolean isSelectable() { + return true; + } + + @Override + public boolean isNamelessWallpaper() { + return true; + } +}
\ No newline at end of file diff --git a/WallpaperPicker/src/com/android/launcher3/wallpapertileinfo/LiveWallpaperInfo.java b/WallpaperPicker/src/com/android/launcher3/wallpapertileinfo/LiveWallpaperInfo.java new file mode 100644 index 000000000..d800ba6e1 --- /dev/null +++ b/WallpaperPicker/src/com/android/launcher3/wallpapertileinfo/LiveWallpaperInfo.java @@ -0,0 +1,118 @@ +package com.android.launcher3.wallpapertileinfo; + +import android.app.WallpaperInfo; +import android.app.WallpaperManager; +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.graphics.drawable.Drawable; +import android.os.AsyncTask; +import android.service.wallpaper.WallpaperService; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import com.android.launcher3.R; +import com.android.launcher3.WallpaperPickerActivity; + +import org.xmlpull.v1.XmlPullParserException; + +import java.io.IOException; +import java.text.Collator; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +public class LiveWallpaperInfo extends WallpaperTileInfo { + + private static final String TAG = "LiveWallpaperTile"; + + private Drawable mThumbnail; + private WallpaperInfo mInfo; + + public LiveWallpaperInfo(Drawable thumbnail, WallpaperInfo info, Intent intent) { + mThumbnail = thumbnail; + mInfo = info; + } + + @Override + public void onClick(WallpaperPickerActivity a) { + Intent preview = new Intent(WallpaperManager.ACTION_CHANGE_LIVE_WALLPAPER); + preview.putExtra(WallpaperManager.EXTRA_LIVE_WALLPAPER_COMPONENT, + mInfo.getComponent()); + a.startActivityForResultSafely(preview, + WallpaperPickerActivity.PICK_WALLPAPER_THIRD_PARTY_ACTIVITY); + } + + @Override + public View createView(Context context, LayoutInflater inflator, ViewGroup parent) { + mView = inflator.inflate(R.layout.wallpaper_picker_live_wallpaper_item, parent, false); + + ImageView image = (ImageView) mView.findViewById(R.id.wallpaper_image); + ImageView icon = (ImageView) mView.findViewById(R.id.wallpaper_icon); + if (mThumbnail != null) { + image.setImageDrawable(mThumbnail); + icon.setVisibility(View.GONE); + } else { + icon.setImageDrawable(mInfo.loadIcon(context.getPackageManager())); + icon.setVisibility(View.VISIBLE); + } + + TextView label = (TextView) mView.findViewById(R.id.wallpaper_item_label); + label.setText(mInfo.loadLabel(context.getPackageManager())); + return mView; + } + + /** + * An async task to load various live wallpaper tiles. + */ + public static class LoaderTask extends AsyncTask<Void, Void, List<LiveWallpaperInfo>> { + private final Context mContext; + + public LoaderTask(Context context) { + mContext = context; + } + + @Override + protected List<LiveWallpaperInfo> doInBackground(Void... params) { + final PackageManager pm = mContext.getPackageManager(); + + List<ResolveInfo> list = pm.queryIntentServices( + new Intent(WallpaperService.SERVICE_INTERFACE), + PackageManager.GET_META_DATA); + + Collections.sort(list, new Comparator<ResolveInfo>() { + final Collator mCollator = Collator.getInstance(); + + public int compare(ResolveInfo info1, ResolveInfo info2) { + return mCollator.compare(info1.loadLabel(pm), info2.loadLabel(pm)); + } + }); + + List<LiveWallpaperInfo> result = new ArrayList<>(); + + for (ResolveInfo resolveInfo : list) { + WallpaperInfo info = null; + try { + info = new WallpaperInfo(mContext, resolveInfo); + } catch (XmlPullParserException | IOException e) { + Log.w(TAG, "Skipping wallpaper " + resolveInfo.serviceInfo, e); + continue; + } + + + Drawable thumb = info.loadThumbnail(pm); + Intent launchIntent = new Intent(WallpaperService.SERVICE_INTERFACE); + launchIntent.setClassName(info.getPackageName(), info.getServiceName()); + result.add(new LiveWallpaperInfo(thumb, info, launchIntent)); + } + + return result; + } + } +}
\ No newline at end of file diff --git a/WallpaperPicker/src/com/android/launcher3/wallpapertileinfo/PickImageInfo.java b/WallpaperPicker/src/com/android/launcher3/wallpapertileinfo/PickImageInfo.java new file mode 100644 index 000000000..9d8cc1cd7 --- /dev/null +++ b/WallpaperPicker/src/com/android/launcher3/wallpapertileinfo/PickImageInfo.java @@ -0,0 +1,74 @@ +package com.android.launcher3.wallpapertileinfo; + +import android.Manifest; +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.database.Cursor; +import android.graphics.Bitmap; +import android.graphics.PorterDuff; +import android.os.Process; +import android.provider.MediaStore; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; + +import com.android.launcher3.R; +import com.android.launcher3.WallpaperPickerActivity; + +public class PickImageInfo extends WallpaperTileInfo { + + @Override + public void onClick(WallpaperPickerActivity a) { + Intent intent = new Intent(Intent.ACTION_GET_CONTENT).setType("image/*"); + a.startActivityForResultSafely(intent, WallpaperPickerActivity.IMAGE_PICK); + } + + @Override + public View createView(Context context, LayoutInflater inflator, ViewGroup parent) { + mView = inflator.inflate(R.layout.wallpaper_picker_image_picker_item, parent, false); + + // Make its background the last photo taken on external storage + Bitmap lastPhoto = getThumbnailOfLastPhoto(context); + if (lastPhoto != null) { + ImageView galleryThumbnailBg = + (ImageView) mView.findViewById(R.id.wallpaper_image); + galleryThumbnailBg.setImageBitmap(lastPhoto); + int colorOverlay = context.getResources().getColor(R.color.wallpaper_picker_translucent_gray); + galleryThumbnailBg.setColorFilter(colorOverlay, PorterDuff.Mode.SRC_ATOP); + } + + mView.setTag(this); + return mView; + } + + private Bitmap getThumbnailOfLastPhoto(Context context) { + boolean canReadExternalStorage = context.checkPermission( + Manifest.permission.READ_EXTERNAL_STORAGE, Process.myPid(), Process.myUid()) == + PackageManager.PERMISSION_GRANTED; + + if (!canReadExternalStorage) { + // MediaStore.Images.Media.EXTERNAL_CONTENT_URI requires + // the READ_EXTERNAL_STORAGE permission + return null; + } + + Cursor cursor = MediaStore.Images.Media.query(context.getContentResolver(), + MediaStore.Images.Media.EXTERNAL_CONTENT_URI, + new String[] { MediaStore.Images.ImageColumns._ID, + MediaStore.Images.ImageColumns.DATE_TAKEN}, + null, null, MediaStore.Images.ImageColumns.DATE_TAKEN + " DESC LIMIT 1"); + + Bitmap thumb = null; + if (cursor != null) { + if (cursor.moveToNext()) { + int id = cursor.getInt(0); + thumb = MediaStore.Images.Thumbnails.getThumbnail(context.getContentResolver(), + id, MediaStore.Images.Thumbnails.MINI_KIND, null); + } + cursor.close(); + } + return thumb; + } +}
\ No newline at end of file diff --git a/WallpaperPicker/src/com/android/launcher3/wallpapertileinfo/ResourceWallpaperInfo.java b/WallpaperPicker/src/com/android/launcher3/wallpapertileinfo/ResourceWallpaperInfo.java new file mode 100644 index 000000000..6f28311df --- /dev/null +++ b/WallpaperPicker/src/com/android/launcher3/wallpapertileinfo/ResourceWallpaperInfo.java @@ -0,0 +1,68 @@ +package com.android.launcher3.wallpapertileinfo; + +import android.content.res.Resources; +import android.graphics.Point; +import android.graphics.RectF; +import android.graphics.drawable.Drawable; + +import com.android.gallery3d.common.Utils; +import com.android.launcher3.WallpaperCropActivity.CropViewScaleProvider; +import com.android.launcher3.WallpaperPickerActivity; +import com.android.launcher3.util.WallpaperUtils; +import com.android.photos.BitmapRegionTileSource; +import com.android.photos.BitmapRegionTileSource.BitmapSource; +import com.android.photos.views.TiledImageRenderer.TileSource; + +public class ResourceWallpaperInfo extends DrawableThumbWallpaperInfo { + + private final Resources mResources; + private final int mResId; + + public ResourceWallpaperInfo(Resources res, int resId, Drawable thumb) { + super(thumb); + mResources = res; + mResId = resId; + } + + @Override + public void onClick(final WallpaperPickerActivity a) { + a.setWallpaperButtonEnabled(false); + final BitmapRegionTileSource.ResourceBitmapSource bitmapSource = + new BitmapRegionTileSource.ResourceBitmapSource(mResources, mResId, a); + a.setCropViewTileSource(bitmapSource, false, false, new CropViewScaleProvider() { + + @Override + public float getScale(TileSource src) { + Point wallpaperSize = WallpaperUtils.getDefaultWallpaperSize( + a.getResources(), a.getWindowManager()); + RectF crop = Utils.getMaxCropRect( + src.getImageWidth(), src.getImageHeight(), + wallpaperSize.x, wallpaperSize.y, false); + return wallpaperSize.x / crop.width(); + } + }, new Runnable() { + + @Override + public void run() { + if (bitmapSource.getLoadingState() == BitmapSource.State.LOADED) { + a.setWallpaperButtonEnabled(true); + } + } + }); + } + + @Override + public void onSave(WallpaperPickerActivity a) { + a.cropImageAndSetWallpaper(mResources, mResId); + } + + @Override + public boolean isSelectable() { + return true; + } + + @Override + public boolean isNamelessWallpaper() { + return true; + } +}
\ No newline at end of file diff --git a/WallpaperPicker/src/com/android/launcher3/wallpapertileinfo/ThirdPartyWallpaperInfo.java b/WallpaperPicker/src/com/android/launcher3/wallpapertileinfo/ThirdPartyWallpaperInfo.java new file mode 100644 index 000000000..e7ea511e8 --- /dev/null +++ b/WallpaperPicker/src/com/android/launcher3/wallpapertileinfo/ThirdPartyWallpaperInfo.java @@ -0,0 +1,76 @@ +package com.android.launcher3.wallpapertileinfo; + +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.graphics.Rect; +import android.graphics.drawable.Drawable; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import com.android.launcher3.R; +import com.android.launcher3.WallpaperPickerActivity; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; + +public class ThirdPartyWallpaperInfo extends WallpaperTileInfo { + + private final ResolveInfo mResolveInfo; + private final int mIconSize; + + public ThirdPartyWallpaperInfo(ResolveInfo resolveInfo, int iconSize) { + mResolveInfo = resolveInfo; + mIconSize = iconSize; + } + + @Override + public void onClick(WallpaperPickerActivity a) { + final ComponentName itemComponentName = new ComponentName( + mResolveInfo.activityInfo.packageName, mResolveInfo.activityInfo.name); + Intent launchIntent = new Intent(Intent.ACTION_SET_WALLPAPER) + .setComponent(itemComponentName); + a.startActivityForResultSafely( + launchIntent, WallpaperPickerActivity.PICK_WALLPAPER_THIRD_PARTY_ACTIVITY); + } + + @Override + public View createView(Context context, LayoutInflater inflator, ViewGroup parent) { + mView = inflator.inflate(R.layout.wallpaper_picker_third_party_item, parent, false); + + TextView label = (TextView) mView.findViewById(R.id.wallpaper_item_label); + label.setText(mResolveInfo.loadLabel(context.getPackageManager())); + Drawable icon = mResolveInfo.loadIcon(context.getPackageManager()); + icon.setBounds(new Rect(0, 0, mIconSize, mIconSize)); + label.setCompoundDrawables(null, icon, null, null); + return mView; + } + + public static List<ThirdPartyWallpaperInfo> getAll(Context context) { + ArrayList<ThirdPartyWallpaperInfo> result = new ArrayList<>(); + int iconSize = context.getResources().getDimensionPixelSize(R.dimen.wallpaperItemIconSize); + + final PackageManager pm = context.getPackageManager(); + Intent pickImageIntent = new Intent(Intent.ACTION_GET_CONTENT).setType("image/*"); + HashSet<String> excludePackages = new HashSet<>(); + // Exclude packages which contain an image picker + for (ResolveInfo info : pm.queryIntentActivities(pickImageIntent, 0)) { + excludePackages.add(info.activityInfo.packageName); + } + excludePackages.add(context.getPackageName()); + excludePackages.add("com.android.wallpaper.livepicker"); + + final Intent pickWallpaperIntent = new Intent(Intent.ACTION_SET_WALLPAPER); + for (ResolveInfo info : pm.queryIntentActivities(pickWallpaperIntent, 0)) { + if (!excludePackages.contains(info.activityInfo.packageName)) { + result.add(new ThirdPartyWallpaperInfo(info, iconSize)); + } + } + return result; + } +}
\ No newline at end of file diff --git a/WallpaperPicker/src/com/android/launcher3/wallpapertileinfo/UriWallpaperInfo.java b/WallpaperPicker/src/com/android/launcher3/wallpapertileinfo/UriWallpaperInfo.java new file mode 100644 index 000000000..3e76fb886 --- /dev/null +++ b/WallpaperPicker/src/com/android/launcher3/wallpapertileinfo/UriWallpaperInfo.java @@ -0,0 +1,108 @@ +package com.android.launcher3.wallpapertileinfo; + +import android.graphics.Bitmap; +import android.graphics.drawable.BitmapDrawable; +import android.net.Uri; +import android.os.AsyncTask; +import android.util.Log; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Toast; + +import com.android.gallery3d.common.BitmapCropTask; +import com.android.gallery3d.common.BitmapUtils; +import com.android.launcher3.R; +import com.android.launcher3.WallpaperPickerActivity; +import com.android.photos.BitmapRegionTileSource; +import com.android.photos.BitmapRegionTileSource.BitmapSource; + +public class UriWallpaperInfo extends DrawableThumbWallpaperInfo { + + private static final String TAG = "UriWallpaperInfo"; + + public final Uri mUri; + + public UriWallpaperInfo(Uri uri) { + super(null); + mUri = uri; + } + + @Override + public void onClick(final WallpaperPickerActivity a) { + a.setWallpaperButtonEnabled(false); + final BitmapRegionTileSource.UriBitmapSource bitmapSource = + new BitmapRegionTileSource.UriBitmapSource(a.getContext(), mUri); + a.setCropViewTileSource(bitmapSource, true, false, null, new Runnable() { + + @Override + public void run() { + if (bitmapSource.getLoadingState() == BitmapSource.State.LOADED) { + a.selectTile(mView); + a.setWallpaperButtonEnabled(true); + } else { + ViewGroup parent = (ViewGroup) mView.getParent(); + if (parent != null) { + parent.removeView(mView); + Toast.makeText(a.getContext(), R.string.image_load_fail, + Toast.LENGTH_SHORT).show(); + } + } + } + }); + } + + @Override + public void onSave(final WallpaperPickerActivity a) { + BitmapCropTask.OnBitmapCroppedHandler h = new BitmapCropTask.OnBitmapCroppedHandler() { + public void onBitmapCropped(byte[] imageBytes) { + // rotation is set to 0 since imageBytes has already been correctly rotated + Bitmap thumb = createThumbnail(a, null, imageBytes, null, 0, 0, true); + a.getSavedImages().writeImage(thumb, imageBytes); + } + }; + a.cropImageAndSetWallpaper(mUri, h); + } + + @Override + public boolean isSelectable() { + return true; + } + + @Override + public boolean isNamelessWallpaper() { + return true; + } + + public void loadThumbnaleAsync(final WallpaperPickerActivity activity) { + mView.setVisibility(View.GONE); + new AsyncTask<Void, Void, Bitmap>() { + protected Bitmap doInBackground(Void...args) { + try { + int rotation = BitmapUtils.getRotationFromExif(activity, mUri); + return createThumbnail(activity, mUri, null, null, 0, rotation, false); + } catch (SecurityException securityException) { + if (activity.isActivityDestroyed()) { + // Temporarily granted permissions are revoked when the activity + // finishes, potentially resulting in a SecurityException here. + // Even though {@link #isDestroyed} might also return true in different + // situations where the configuration changes, we are fine with + // catching these cases here as well. + cancel(false); + } else { + // otherwise it had a different cause and we throw it further + throw securityException; + } + return null; + } + } + protected void onPostExecute(Bitmap thumb) { + if (!isCancelled() && thumb != null) { + setThumb(new BitmapDrawable(activity.getResources(), thumb)); + mView.setVisibility(View.VISIBLE); + } else { + Log.e(TAG, "Error loading thumbnail for uri=" + mUri); + } + } + }.execute(); + } +}
\ No newline at end of file diff --git a/WallpaperPicker/src/com/android/launcher3/wallpapertileinfo/WallpaperTileInfo.java b/WallpaperPicker/src/com/android/launcher3/wallpapertileinfo/WallpaperTileInfo.java new file mode 100644 index 000000000..5fc317c3a --- /dev/null +++ b/WallpaperPicker/src/com/android/launcher3/wallpapertileinfo/WallpaperTileInfo.java @@ -0,0 +1,87 @@ +package com.android.launcher3.wallpapertileinfo; + +import android.content.Context; +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.Matrix; +import android.graphics.Point; +import android.graphics.RectF; +import android.net.Uri; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import com.android.gallery3d.common.BitmapCropTask; +import com.android.gallery3d.common.Utils; +import com.android.launcher3.R; +import com.android.launcher3.WallpaperPickerActivity; + +public abstract class WallpaperTileInfo { + + protected View mView; + + public void onClick(WallpaperPickerActivity a) {} + + public void onSave(WallpaperPickerActivity a) {} + + public void onDelete(WallpaperPickerActivity a) {} + + public boolean isSelectable() { return false; } + + public boolean isNamelessWallpaper() { return false; } + + public void onIndexUpdated(CharSequence label) { + if (isNamelessWallpaper()) { + mView.setContentDescription(label); + } + } + + public abstract View createView(Context context, LayoutInflater inflator, ViewGroup parent); + + protected static Point getDefaultThumbSize(Resources res) { + return new Point(res.getDimensionPixelSize(R.dimen.wallpaperThumbnailWidth), + res.getDimensionPixelSize(R.dimen.wallpaperThumbnailHeight)); + + } + + protected static Bitmap createThumbnail(Context context, Uri uri, byte[] imageBytes, + Resources res, int resId, int rotation, boolean leftAligned) { + Point size = getDefaultThumbSize(context.getResources()); + int width = size.x; + int height = size.y; + + BitmapCropTask cropTask; + if (uri != null) { + cropTask = new BitmapCropTask( + context, uri, null, rotation, width, height, false, true, null); + } else if (imageBytes != null) { + cropTask = new BitmapCropTask( + imageBytes, null, rotation, width, height, false, true, null); + } else { + cropTask = new BitmapCropTask( + context, res, resId, null, rotation, width, height, false, true, null); + } + Point bounds = cropTask.getImageBounds(); + if (bounds == null || bounds.x == 0 || bounds.y == 0) { + return null; + } + + Matrix rotateMatrix = new Matrix(); + rotateMatrix.setRotate(rotation); + float[] rotatedBounds = new float[] { bounds.x, bounds.y }; + rotateMatrix.mapPoints(rotatedBounds); + rotatedBounds[0] = Math.abs(rotatedBounds[0]); + rotatedBounds[1] = Math.abs(rotatedBounds[1]); + + RectF cropRect = Utils.getMaxCropRect( + (int) rotatedBounds[0], (int) rotatedBounds[1], width, height, leftAligned); + cropTask.setCropBounds(cropRect); + + if (cropTask.cropBitmap()) { + return cropTask.getCroppedBitmap(); + } else { + return null; + } + } + +}
\ No newline at end of file |