12a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski/*
22a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski * Copyright (C) 2010 The Android Open Source Project
32a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski *
42a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski * Licensed under the Apache License, Version 2.0 (the "License");
52a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski * you may not use this file except in compliance with the License.
62a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski * You may obtain a copy of the License at
72a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski *
82a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski *      http://www.apache.org/licenses/LICENSE-2.0
92a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski *
102a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski * Unless required by applicable law or agreed to in writing, software
112a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski * distributed under the License is distributed on an "AS IS" BASIS,
122a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski * See the License for the specific language governing permissions and
142a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski * limitations under the License.
152a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski */
162a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinskipackage com.android.launcher2;
172a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski
182a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinskiimport android.app.Activity;
192a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinskiimport android.app.Dialog;
202a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinskiimport android.app.DialogFragment;
212a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinskiimport android.app.WallpaperManager;
222a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinskiimport android.content.Context;
232a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinskiimport android.content.DialogInterface;
242a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinskiimport android.content.res.Resources;
252a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinskiimport android.graphics.Bitmap;
262a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinskiimport android.graphics.BitmapFactory;
276be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasaniimport android.graphics.Canvas;
286be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasaniimport android.graphics.ColorFilter;
292a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinskiimport android.graphics.drawable.Drawable;
302a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinskiimport android.os.AsyncTask;
312a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinskiimport android.os.Bundle;
322a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinskiimport android.util.Log;
332a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinskiimport android.view.LayoutInflater;
342a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinskiimport android.view.View;
356be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasaniimport android.view.View.OnClickListener;
3692f3d46cf35e78891f73226e81f8ca7e9a7f4d92Michael Jurkaimport android.view.ViewGroup;
372a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinskiimport android.widget.AdapterView;
382a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinskiimport android.widget.BaseAdapter;
392a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinskiimport android.widget.Gallery;
402a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinskiimport android.widget.ImageView;
412a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinskiimport android.widget.ListAdapter;
422a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinskiimport android.widget.SpinnerAdapter;
432a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski
446be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasaniimport com.android.launcher.R;
456be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani
462a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinskiimport java.io.IOException;
472a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinskiimport java.util.ArrayList;
482a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski
492a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinskipublic class WallpaperChooserDialogFragment extends DialogFragment implements
502a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        AdapterView.OnItemSelectedListener, AdapterView.OnItemClickListener {
512a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski
522a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    private static final String TAG = "Launcher.WallpaperChooserDialogFragment";
532a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    private static final String EMBEDDED_KEY = "com.android.launcher2."
542a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            + "WallpaperChooserDialogFragment.EMBEDDED_KEY";
552a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski
562a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    private boolean mEmbedded;
572a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    private Bitmap mBitmap = null;
582a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski
592a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    private ArrayList<Integer> mThumbs;
602a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    private ArrayList<Integer> mImages;
612a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    private WallpaperLoader mLoader;
626be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani    private WallpaperDrawable mWallpaperDrawable = new WallpaperDrawable();
632a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski
642a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    public static WallpaperChooserDialogFragment newInstance() {
652a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        WallpaperChooserDialogFragment fragment = new WallpaperChooserDialogFragment();
662a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        fragment.setCancelable(true);
672a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        return fragment;
682a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    }
692a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski
702a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    @Override
712a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    public void onCreate(Bundle savedInstanceState) {
722a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        super.onCreate(savedInstanceState);
732a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        if (savedInstanceState != null && savedInstanceState.containsKey(EMBEDDED_KEY)) {
742a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            mEmbedded = savedInstanceState.getBoolean(EMBEDDED_KEY);
752a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        } else {
762a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            mEmbedded = isInLayout();
772a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        }
782a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    }
792a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski
802a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    @Override
812a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    public void onSaveInstanceState(Bundle outState) {
822a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        outState.putBoolean(EMBEDDED_KEY, mEmbedded);
832a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    }
842a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski
8597ea93e52153fe6ab6b6a362a387603ae5eae145Winson Chung    private void cancelLoader() {
862a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        if (mLoader != null && mLoader.getStatus() != WallpaperLoader.Status.FINISHED) {
872a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            mLoader.cancel(true);
882a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            mLoader = null;
892a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        }
902a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    }
912a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski
922a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    @Override
9397ea93e52153fe6ab6b6a362a387603ae5eae145Winson Chung    public void onDetach() {
9497ea93e52153fe6ab6b6a362a387603ae5eae145Winson Chung        super.onDetach();
9597ea93e52153fe6ab6b6a362a387603ae5eae145Winson Chung
9697ea93e52153fe6ab6b6a362a387603ae5eae145Winson Chung        cancelLoader();
9797ea93e52153fe6ab6b6a362a387603ae5eae145Winson Chung    }
9897ea93e52153fe6ab6b6a362a387603ae5eae145Winson Chung
9997ea93e52153fe6ab6b6a362a387603ae5eae145Winson Chung    @Override
10097ea93e52153fe6ab6b6a362a387603ae5eae145Winson Chung    public void onDestroy() {
10197ea93e52153fe6ab6b6a362a387603ae5eae145Winson Chung        super.onDestroy();
10297ea93e52153fe6ab6b6a362a387603ae5eae145Winson Chung
10397ea93e52153fe6ab6b6a362a387603ae5eae145Winson Chung        cancelLoader();
10497ea93e52153fe6ab6b6a362a387603ae5eae145Winson Chung    }
10597ea93e52153fe6ab6b6a362a387603ae5eae145Winson Chung
10697ea93e52153fe6ab6b6a362a387603ae5eae145Winson Chung    @Override
1072a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    public void onDismiss(DialogInterface dialog) {
1082a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        super.onDismiss(dialog);
1092a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        /* On orientation changes, the dialog is effectively "dismissed" so this is called
1102a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski         * when the activity is no longer associated with this dying dialog fragment. We
1112a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski         * should just safely ignore this case by checking if getActivity() returns null
1122a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski         */
1132a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        Activity activity = getActivity();
1142a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        if (activity != null) {
1152a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            activity.finish();
1162a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        }
1172a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    }
1182a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski
1192a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    /* This will only be called when in XLarge mode, since this Fragment is invoked like
1202a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski     * a dialog in that mode
1212a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski     */
1222a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    @Override
1232a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    public Dialog onCreateDialog(Bundle savedInstanceState) {
1243b7d86d02658ec9c2782d7c252e68b2e9c0c07b7Winson Chung        findWallpapers();
1253b7d86d02658ec9c2782d7c252e68b2e9c0c07b7Winson Chung
1266be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani        return null;
1272a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    }
1282a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski
1292a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    @Override
1302a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    public View onCreateView(LayoutInflater inflater, ViewGroup container,
1312a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            Bundle savedInstanceState) {
1322a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        findWallpapers();
1332a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski
1342a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        /* If this fragment is embedded in the layout of this activity, then we should
1352a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski         * generate a view to display. Otherwise, a dialog will be created in
1362a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski         * onCreateDialog()
1372a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski         */
1382a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        if (mEmbedded) {
1392a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            View view = inflater.inflate(R.layout.wallpaper_chooser, container, false);
1403a9fcedbcd235372cd2ab64f825a0b5b3937f59eMichael Jurka            view.setBackground(mWallpaperDrawable);
1412a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski
1422a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            final Gallery gallery = (Gallery) view.findViewById(R.id.gallery);
1432a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            gallery.setCallbackDuringFling(false);
1442a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            gallery.setOnItemSelectedListener(this);
1452a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            gallery.setAdapter(new ImageAdapter(getActivity()));
1462a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski
1472a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            View setButton = view.findViewById(R.id.set);
1482a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            setButton.setOnClickListener(new OnClickListener() {
1492a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski                @Override
1502a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski                public void onClick(View v) {
1512a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski                    selectWallpaper(gallery.getSelectedItemPosition());
1522a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski                }
1532a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            });
1542a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            return view;
1552a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        }
1562a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        return null;
1572a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    }
1582a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski
1592a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    private void selectWallpaper(int position) {
1602a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        try {
1612a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            WallpaperManager wpm = (WallpaperManager) getActivity().getSystemService(
1622a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski                    Context.WALLPAPER_SERVICE);
1632a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            wpm.setResource(mImages.get(position));
1642a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            Activity activity = getActivity();
1652a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            activity.setResult(Activity.RESULT_OK);
1662a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            activity.finish();
1672a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        } catch (IOException e) {
1682a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            Log.e(TAG, "Failed to set wallpaper: " + e);
1692a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        }
1702a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    }
1712a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski
1722a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    // Click handler for the Dialog's GridView
1732a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    @Override
1742a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
1752a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        selectWallpaper(position);
1762a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    }
1772a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski
1782a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    // Selection handler for the embedded Gallery view
1792a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    @Override
1802a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
1812a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        if (mLoader != null && mLoader.getStatus() != WallpaperLoader.Status.FINISHED) {
1822a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            mLoader.cancel();
1832a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        }
1842a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        mLoader = (WallpaperLoader) new WallpaperLoader().execute(position);
1852a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    }
1862a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski
1872a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    @Override
1882a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    public void onNothingSelected(AdapterView<?> parent) {
1892a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    }
1902a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski
1912a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    private void findWallpapers() {
1922a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        mThumbs = new ArrayList<Integer>(24);
1932a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        mImages = new ArrayList<Integer>(24);
1942a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski
1952a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        final Resources resources = getResources();
1962a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        // Context.getPackageName() may return the "original" package name,
1972a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        // com.android.launcher2; Resources needs the real package name,
1982a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        // com.android.launcher. So we ask Resources for what it thinks the
1992a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        // package name should be.
2002a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        final String packageName = resources.getResourcePackageName(R.array.wallpapers);
2012a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski
2022a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        addWallpapers(resources, packageName, R.array.wallpapers);
2032a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        addWallpapers(resources, packageName, R.array.extra_wallpapers);
2042a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    }
2052a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski
2062a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    private void addWallpapers(Resources resources, String packageName, int list) {
2072a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        final String[] extras = resources.getStringArray(list);
2082a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        for (String extra : extras) {
2092a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            int res = resources.getIdentifier(extra, "drawable", packageName);
2102a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            if (res != 0) {
2112a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski                final int thumbRes = resources.getIdentifier(extra + "_small",
2122a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski                        "drawable", packageName);
2132a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski
2142a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski                if (thumbRes != 0) {
2152a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski                    mThumbs.add(thumbRes);
2162a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski                    mImages.add(res);
2172a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski                    // Log.d(TAG, "add: [" + packageName + "]: " + extra + " (" + res + ")");
2182a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski                }
2192a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            }
2202a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        }
2212a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    }
2222a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski
2232a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    private class ImageAdapter extends BaseAdapter implements ListAdapter, SpinnerAdapter {
2242a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        private LayoutInflater mLayoutInflater;
2252a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski
2262a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        ImageAdapter(Activity activity) {
2272a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            mLayoutInflater = activity.getLayoutInflater();
2282a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        }
2292a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski
2302a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        public int getCount() {
2312a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            return mThumbs.size();
2322a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        }
2332a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski
2342a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        public Object getItem(int position) {
2352a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            return position;
2362a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        }
2372a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski
2382a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        public long getItemId(int position) {
2392a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            return position;
2402a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        }
2412a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski
2422a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        public View getView(int position, View convertView, ViewGroup parent) {
243a6612cd45fc77e4f44fcdd1a74833a61bf440720Adam Cohen            View view;
2442a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski
2452a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            if (convertView == null) {
246a6612cd45fc77e4f44fcdd1a74833a61bf440720Adam Cohen                view = mLayoutInflater.inflate(R.layout.wallpaper_item, parent, false);
2472a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            } else {
248a6612cd45fc77e4f44fcdd1a74833a61bf440720Adam Cohen                view = convertView;
2492a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            }
2502a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski
251a6612cd45fc77e4f44fcdd1a74833a61bf440720Adam Cohen            ImageView image = (ImageView) view.findViewById(R.id.wallpaper_image);
252a6612cd45fc77e4f44fcdd1a74833a61bf440720Adam Cohen
2532a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            int thumbRes = mThumbs.get(position);
2542a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            image.setImageResource(thumbRes);
2552a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            Drawable thumbDrawable = image.getDrawable();
2562a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            if (thumbDrawable != null) {
2572a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski                thumbDrawable.setDither(true);
2582a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            } else {
2592a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski                Log.e(TAG, "Error decoding thumbnail resId=" + thumbRes + " for wallpaper #"
2602a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski                        + position);
2612a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            }
2622a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski
263a6612cd45fc77e4f44fcdd1a74833a61bf440720Adam Cohen            return view;
2642a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        }
2652a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    }
2662a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski
2672a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    class WallpaperLoader extends AsyncTask<Integer, Void, Bitmap> {
2682a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        BitmapFactory.Options mOptions;
2692a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski
2702a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        WallpaperLoader() {
2712a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            mOptions = new BitmapFactory.Options();
2722a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            mOptions.inDither = false;
2732a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            mOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;
2742a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        }
2752a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski
2762a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        @Override
2772a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        protected Bitmap doInBackground(Integer... params) {
2782a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            if (isCancelled()) return null;
2792a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            try {
2802a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski                return BitmapFactory.decodeResource(getResources(),
2812a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski                        mImages.get(params[0]), mOptions);
2822a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            } catch (OutOfMemoryError e) {
2832a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski                return null;
2842a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            }
2852a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        }
2862a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski
2872a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        @Override
2882a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        protected void onPostExecute(Bitmap b) {
2892a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            if (b == null) return;
2902a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski
2912a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            if (!isCancelled() && !mOptions.mCancel) {
2922a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski                // Help the GC
2932a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski                if (mBitmap != null) {
2942a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski                    mBitmap.recycle();
2952a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski                }
2962a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski
297f8742be8abcb8e54e62fca04bc2811cc8ea3bda8Winson Chung                View v = getView();
298f8742be8abcb8e54e62fca04bc2811cc8ea3bda8Winson Chung                if (v != null) {
299f8742be8abcb8e54e62fca04bc2811cc8ea3bda8Winson Chung                    mBitmap = b;
300f8742be8abcb8e54e62fca04bc2811cc8ea3bda8Winson Chung                    mWallpaperDrawable.setBitmap(b);
301f8742be8abcb8e54e62fca04bc2811cc8ea3bda8Winson Chung                    v.postInvalidate();
302f8742be8abcb8e54e62fca04bc2811cc8ea3bda8Winson Chung                } else {
303f8742be8abcb8e54e62fca04bc2811cc8ea3bda8Winson Chung                    mBitmap = null;
304f8742be8abcb8e54e62fca04bc2811cc8ea3bda8Winson Chung                    mWallpaperDrawable.setBitmap(null);
305f8742be8abcb8e54e62fca04bc2811cc8ea3bda8Winson Chung                }
3062a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski                mLoader = null;
3072a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            } else {
3082a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski               b.recycle();
3092a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            }
3102a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        }
3112a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski
3122a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        void cancel() {
3132a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            mOptions.requestCancelDecode();
3142a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            super.cancel(true);
3152a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        }
3162a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    }
3176be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani
3186be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani    /**
3196be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani     * Custom drawable that centers the bitmap fed to it.
3206be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani     */
3216be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani    static class WallpaperDrawable extends Drawable {
3226be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani
3236be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani        Bitmap mBitmap;
3246be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani        int mIntrinsicWidth;
3256be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani        int mIntrinsicHeight;
3266be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani
3276be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani        /* package */void setBitmap(Bitmap bitmap) {
3286be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani            mBitmap = bitmap;
3296be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani            if (mBitmap == null)
3306be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani                return;
3316be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani            mIntrinsicWidth = mBitmap.getWidth();
3326be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani            mIntrinsicHeight = mBitmap.getHeight();
3336be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani        }
3346be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani
3356be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani        @Override
3366be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani        public void draw(Canvas canvas) {
3376be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani            if (mBitmap == null) return;
3386be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani            int width = canvas.getWidth();
3396be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani            int height = canvas.getHeight();
3406be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani            int x = (width - mIntrinsicWidth) / 2;
3416be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani            int y = (height - mIntrinsicHeight) / 2;
3426be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani            canvas.drawBitmap(mBitmap, x, y, null);
3436be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani        }
3446be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani
3456be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani        @Override
3466be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani        public int getOpacity() {
3476be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani            return android.graphics.PixelFormat.OPAQUE;
3486be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani        }
3496be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani
3506be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani        @Override
3516be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani        public void setAlpha(int alpha) {
3526be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani            // Ignore
3536be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani        }
3546be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani
3556be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani        @Override
3566be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani        public void setColorFilter(ColorFilter cf) {
3576be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani            // Ignore
3586be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani        }
3596be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani    }
36079b79dd57911b9f79d4fb872e70d37ee90b0cc64Andrew Flynn}
361