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
852a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    @Override
862a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    public void onDestroy() {
872a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        super.onDestroy();
882a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski
892a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        if (mLoader != null && mLoader.getStatus() != WallpaperLoader.Status.FINISHED) {
902a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            mLoader.cancel(true);
912a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            mLoader = null;
922a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        }
932a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    }
942a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski
952a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    @Override
962a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    public void onDismiss(DialogInterface dialog) {
972a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        super.onDismiss(dialog);
982a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        /* On orientation changes, the dialog is effectively "dismissed" so this is called
992a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski         * when the activity is no longer associated with this dying dialog fragment. We
1002a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski         * should just safely ignore this case by checking if getActivity() returns null
1012a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski         */
1022a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        Activity activity = getActivity();
1032a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        if (activity != null) {
1042a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            activity.finish();
1052a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        }
1062a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    }
1072a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski
1082a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    /* This will only be called when in XLarge mode, since this Fragment is invoked like
1092a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski     * a dialog in that mode
1102a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski     */
1112a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    @Override
1122a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    public Dialog onCreateDialog(Bundle savedInstanceState) {
1133b7d86d02658ec9c2782d7c252e68b2e9c0c07b7Winson Chung        findWallpapers();
1143b7d86d02658ec9c2782d7c252e68b2e9c0c07b7Winson Chung
1156be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani        // TODO: The following code is not exercised right now and may be removed
1166be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani        // if the dialog version is not needed.
1176be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani        /*
1182a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        final View v = getActivity().getLayoutInflater().inflate(
1192a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski                R.layout.wallpaper_chooser, null, false);
1202a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski
1212a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        GridView gridView = (GridView) v.findViewById(R.id.gallery);
1222a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        gridView.setOnItemClickListener(this);
1232a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        gridView.setAdapter(new ImageAdapter(getActivity()));
1242a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski
1252a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        final int viewInset =
1262a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski                getResources().getDimensionPixelSize(R.dimen.alert_dialog_content_inset);
1276be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani
128a6612cd45fc77e4f44fcdd1a74833a61bf440720Adam Cohen        FrameLayout wallPaperList = (FrameLayout) v.findViewById(R.id.wallpaper_list);
1292a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
1302a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        builder.setNegativeButton(R.string.wallpaper_cancel, null);
1312a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        builder.setTitle(R.string.wallpaper_dialog_title);
1326be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani        builder.setView(wallPaperList,
1336be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani        viewInset, viewInset, viewInset, viewInset); return builder.create();
1346be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani        */
1356be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani        return null;
1362a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    }
1372a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski
1382a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    @Override
1392a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    public View onCreateView(LayoutInflater inflater, ViewGroup container,
1402a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            Bundle savedInstanceState) {
1412a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        findWallpapers();
1422a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski
1432a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        /* If this fragment is embedded in the layout of this activity, then we should
1442a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski         * generate a view to display. Otherwise, a dialog will be created in
1452a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski         * onCreateDialog()
1462a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski         */
1472a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        if (mEmbedded) {
1482a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            View view = inflater.inflate(R.layout.wallpaper_chooser, container, false);
1496be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani            view.setBackgroundDrawable(mWallpaperDrawable);
1502a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski
1512a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            final Gallery gallery = (Gallery) view.findViewById(R.id.gallery);
1522a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            gallery.setCallbackDuringFling(false);
1532a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            gallery.setOnItemSelectedListener(this);
1542a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            gallery.setAdapter(new ImageAdapter(getActivity()));
1552a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski
1562a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            View setButton = view.findViewById(R.id.set);
1572a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            setButton.setOnClickListener(new OnClickListener() {
1582a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski                @Override
1592a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski                public void onClick(View v) {
1602a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski                    selectWallpaper(gallery.getSelectedItemPosition());
1612a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski                }
1622a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            });
1632a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            return view;
1642a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        }
1652a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        return null;
1662a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    }
1672a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski
1682a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    private void selectWallpaper(int position) {
1692a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        try {
1702a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            WallpaperManager wpm = (WallpaperManager) getActivity().getSystemService(
1712a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski                    Context.WALLPAPER_SERVICE);
1722a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            wpm.setResource(mImages.get(position));
1732a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            Activity activity = getActivity();
1742a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            activity.setResult(Activity.RESULT_OK);
1752a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            activity.finish();
1762a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        } catch (IOException e) {
1772a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            Log.e(TAG, "Failed to set wallpaper: " + e);
1782a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        }
1792a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    }
1802a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski
1812a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    // Click handler for the Dialog's GridView
1822a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    @Override
1832a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
1842a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        selectWallpaper(position);
1852a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    }
1862a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski
1872a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    // Selection handler for the embedded Gallery view
1882a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    @Override
1892a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
1902a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        if (mLoader != null && mLoader.getStatus() != WallpaperLoader.Status.FINISHED) {
1912a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            mLoader.cancel();
1922a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        }
1932a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        mLoader = (WallpaperLoader) new WallpaperLoader().execute(position);
1942a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    }
1952a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski
1962a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    @Override
1972a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    public void onNothingSelected(AdapterView<?> parent) {
1982a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    }
1992a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski
2002a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    private void findWallpapers() {
2012a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        mThumbs = new ArrayList<Integer>(24);
2022a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        mImages = new ArrayList<Integer>(24);
2032a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski
2042a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        final Resources resources = getResources();
2052a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        // Context.getPackageName() may return the "original" package name,
2062a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        // com.android.launcher2; Resources needs the real package name,
2072a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        // com.android.launcher. So we ask Resources for what it thinks the
2082a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        // package name should be.
2092a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        final String packageName = resources.getResourcePackageName(R.array.wallpapers);
2102a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski
2112a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        addWallpapers(resources, packageName, R.array.wallpapers);
2122a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        addWallpapers(resources, packageName, R.array.extra_wallpapers);
2132a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    }
2142a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski
2152a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    private void addWallpapers(Resources resources, String packageName, int list) {
2162a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        final String[] extras = resources.getStringArray(list);
2172a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        for (String extra : extras) {
2182a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            int res = resources.getIdentifier(extra, "drawable", packageName);
2192a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            if (res != 0) {
2202a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski                final int thumbRes = resources.getIdentifier(extra + "_small",
2212a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski                        "drawable", packageName);
2222a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski
2232a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski                if (thumbRes != 0) {
2242a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski                    mThumbs.add(thumbRes);
2252a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski                    mImages.add(res);
2262a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski                    // Log.d(TAG, "add: [" + packageName + "]: " + extra + " (" + res + ")");
2272a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski                }
2282a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            }
2292a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        }
2302a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    }
2312a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski
2322a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    private class ImageAdapter extends BaseAdapter implements ListAdapter, SpinnerAdapter {
2332a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        private LayoutInflater mLayoutInflater;
2342a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski
2352a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        ImageAdapter(Activity activity) {
2362a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            mLayoutInflater = activity.getLayoutInflater();
2372a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        }
2382a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski
2392a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        public int getCount() {
2402a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            return mThumbs.size();
2412a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        }
2422a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski
2432a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        public Object getItem(int position) {
2442a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            return position;
2452a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        }
2462a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski
2472a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        public long getItemId(int position) {
2482a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            return position;
2492a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        }
2502a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski
2512a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        public View getView(int position, View convertView, ViewGroup parent) {
252a6612cd45fc77e4f44fcdd1a74833a61bf440720Adam Cohen            View view;
2532a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski
2542a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            if (convertView == null) {
255a6612cd45fc77e4f44fcdd1a74833a61bf440720Adam Cohen                view = mLayoutInflater.inflate(R.layout.wallpaper_item, parent, false);
2562a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            } else {
257a6612cd45fc77e4f44fcdd1a74833a61bf440720Adam Cohen                view = convertView;
2582a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            }
2592a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski
260a6612cd45fc77e4f44fcdd1a74833a61bf440720Adam Cohen            ImageView image = (ImageView) view.findViewById(R.id.wallpaper_image);
261a6612cd45fc77e4f44fcdd1a74833a61bf440720Adam Cohen
2622a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            int thumbRes = mThumbs.get(position);
2632a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            image.setImageResource(thumbRes);
2642a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            Drawable thumbDrawable = image.getDrawable();
2652a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            if (thumbDrawable != null) {
2662a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski                thumbDrawable.setDither(true);
2672a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            } else {
2682a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski                Log.e(TAG, "Error decoding thumbnail resId=" + thumbRes + " for wallpaper #"
2692a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski                        + position);
2702a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            }
2712a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski
272a6612cd45fc77e4f44fcdd1a74833a61bf440720Adam Cohen            return view;
2732a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        }
2742a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    }
2752a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski
2762a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    class WallpaperLoader extends AsyncTask<Integer, Void, Bitmap> {
2772a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        BitmapFactory.Options mOptions;
2782a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski
2792a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        WallpaperLoader() {
2802a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            mOptions = new BitmapFactory.Options();
2812a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            mOptions.inDither = false;
2822a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            mOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;
2832a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        }
2842a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski
2852a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        @Override
2862a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        protected Bitmap doInBackground(Integer... params) {
2872a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            if (isCancelled()) return null;
2882a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            try {
2892a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski                return BitmapFactory.decodeResource(getResources(),
2902a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski                        mImages.get(params[0]), mOptions);
2912a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            } catch (OutOfMemoryError e) {
2922a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski                return null;
2932a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            }
2942a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        }
2952a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski
2962a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        @Override
2972a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        protected void onPostExecute(Bitmap b) {
2982a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            if (b == null) return;
2992a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski
3002a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            if (!isCancelled() && !mOptions.mCancel) {
3012a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski                // Help the GC
3022a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski                if (mBitmap != null) {
3032a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski                    mBitmap.recycle();
3042a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski                }
3052a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski
306f8742be8abcb8e54e62fca04bc2811cc8ea3bda8Winson Chung                View v = getView();
307f8742be8abcb8e54e62fca04bc2811cc8ea3bda8Winson Chung                if (v != null) {
308f8742be8abcb8e54e62fca04bc2811cc8ea3bda8Winson Chung                    mBitmap = b;
309f8742be8abcb8e54e62fca04bc2811cc8ea3bda8Winson Chung                    mWallpaperDrawable.setBitmap(b);
310f8742be8abcb8e54e62fca04bc2811cc8ea3bda8Winson Chung                    v.postInvalidate();
311f8742be8abcb8e54e62fca04bc2811cc8ea3bda8Winson Chung                } else {
312f8742be8abcb8e54e62fca04bc2811cc8ea3bda8Winson Chung                    mBitmap = null;
313f8742be8abcb8e54e62fca04bc2811cc8ea3bda8Winson Chung                    mWallpaperDrawable.setBitmap(null);
314f8742be8abcb8e54e62fca04bc2811cc8ea3bda8Winson Chung                }
3152a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski                mLoader = null;
3162a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            } else {
3172a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski               b.recycle();
3182a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            }
3192a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        }
3202a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski
3212a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        void cancel() {
3222a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            mOptions.requestCancelDecode();
3232a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski            super.cancel(true);
3242a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski        }
3252a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski    }
3266be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani
3276be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani    /**
3286be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani     * Custom drawable that centers the bitmap fed to it.
3296be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani     */
3306be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani    static class WallpaperDrawable extends Drawable {
3316be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani
3326be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani        Bitmap mBitmap;
3336be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani        int mIntrinsicWidth;
3346be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani        int mIntrinsicHeight;
3356be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani
3366be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani        /* package */void setBitmap(Bitmap bitmap) {
3376be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani            mBitmap = bitmap;
3386be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani            if (mBitmap == null)
3396be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani                return;
3406be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani            mIntrinsicWidth = mBitmap.getWidth();
3416be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani            mIntrinsicHeight = mBitmap.getHeight();
3426be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani        }
3436be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani
3446be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani        @Override
3456be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani        public void draw(Canvas canvas) {
3466be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani            if (mBitmap == null) return;
3476be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani            int width = canvas.getWidth();
3486be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani            int height = canvas.getHeight();
3496be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani            int x = (width - mIntrinsicWidth) / 2;
3506be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani            int y = (height - mIntrinsicHeight) / 2;
3516be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani            canvas.drawBitmap(mBitmap, x, y, null);
3526be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani        }
3536be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani
3546be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani        @Override
3556be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani        public int getOpacity() {
3566be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani            return android.graphics.PixelFormat.OPAQUE;
3576be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani        }
3586be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani
3596be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani        @Override
3606be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani        public void setAlpha(int alpha) {
3616be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani            // Ignore
3626be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani        }
3636be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani
3646be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani        @Override
3656be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani        public void setColorFilter(ColorFilter cf) {
3666be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani            // Ignore
3676be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani        }
3686be594922fac988f3b350718df8e9df3ef25b97eAmith Yamasani    }
3692a898a0ac54beab0ae56c97eeccc017b02d61453Adam Lesinski}