Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e4c28f8e authored by Sunny Goyal's avatar Sunny Goyal
Browse files

Refactoring wallpaper picker activity

  > Moving different tiles to individual classes
  > Moving some utility methods to corresponding tile classes
  > No functionality change

Change-Id: I493cf309f4e3d817a9300be004c475d208f8dadb
parent 1ea392f0
Loading
Loading
Loading
Loading
+0 −203
Original line number Diff line number Diff line
/*
 * 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++;
            }
        }
    }
}
+29 −66
Original line number Diff line number Diff line
@@ -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();
    }

    public SavedWallpaperTile getItem(int position) {
        return mImages.get(position);
    }

    public long getItemId(int position) {
        return position;
        c.close();
        return result;
    }

    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) {
+0 −136
Original line number Diff line number Diff line
/*
 * 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;
    }
}
+67 −0
Original line number Diff line number Diff line
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();
        }
    }
}
+47 −39

File changed.

Preview size limit exceeded, changes collapsed.

Loading