10b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka/*
20b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka * Copyright (C) 2012 The Android Open Source Project
30b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka *
40b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka * Licensed under the Apache License, Version 2.0 (the "License");
50b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka * you may not use this file except in compliance with the License.
60b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka * You may obtain a copy of the License at
70b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka *
80b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka *      http://www.apache.org/licenses/LICENSE-2.0
90b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka *
100b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka * Unless required by applicable law or agreed to in writing, software
110b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka * distributed under the License is distributed on an "AS IS" BASIS,
120b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka * See the License for the specific language governing permissions and
140b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka * limitations under the License.
150b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka */
160b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka
170b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurkapackage com.android.settings;
180b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka
190b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurkaimport android.app.Activity;
204119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurkaimport android.app.ActivityManager;
214119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurkaimport android.app.LauncherActivity.IconResizer;
220b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurkaimport android.appwidget.AppWidgetHost;
230b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurkaimport android.appwidget.AppWidgetManager;
240b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurkaimport android.appwidget.AppWidgetProviderInfo;
250b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurkaimport android.content.ActivityNotFoundException;
264119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurkaimport android.content.ComponentName;
270b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurkaimport android.content.Context;
280b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurkaimport android.content.Intent;
290b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurkaimport android.content.pm.PackageManager;
300b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurkaimport android.content.res.Resources;
310b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurkaimport android.graphics.Bitmap;
324119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurkaimport android.graphics.Bitmap.Config;
330b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurkaimport android.graphics.Canvas;
340b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurkaimport android.graphics.Paint;
350b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurkaimport android.graphics.Rect;
360b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurkaimport android.graphics.drawable.Drawable;
374119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurkaimport android.os.AsyncTask;
380b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurkaimport android.os.Bundle;
390b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurkaimport android.os.IBinder;
400b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurkaimport android.os.RemoteException;
410b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurkaimport android.os.ServiceManager;
42dd395e210aa7fa35935dbd2c416a6d01e971b367Jim Millerimport android.os.UserHandle;
430b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurkaimport android.util.DisplayMetrics;
440b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurkaimport android.util.Log;
450b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurkaimport android.view.IWindowManager;
460b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurkaimport android.view.LayoutInflater;
470b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurkaimport android.view.View;
480b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurkaimport android.view.ViewGroup;
490b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurkaimport android.widget.AdapterView;
500b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurkaimport android.widget.BaseAdapter;
510b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurkaimport android.widget.GridView;
524119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurkaimport android.widget.ImageView;
530b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurkaimport android.widget.TextView;
540b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurkaimport android.widget.Toast;
550b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka
560b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurkaimport com.android.internal.widget.LockPatternUtils;
570b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka
584119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurkaimport java.lang.ref.WeakReference;
590b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurkaimport java.util.List;
600b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka
610b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka/**
620b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka * Displays a list of {@link AppWidgetProviderInfo} widgets, along with any
630b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka * injected special widgets specified through
640b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka * {@link AppWidgetManager#EXTRA_CUSTOM_INFO} and
650b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka * {@link AppWidgetManager#EXTRA_CUSTOM_EXTRAS}.
660b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka * <p>
670b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka * When an installed {@link AppWidgetProviderInfo} is selected, this activity
680b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka * will bind it to the given {@link AppWidgetManager#EXTRA_APPWIDGET_ID},
690b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka * otherwise it will return the requested extras.
700b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka */
710b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurkapublic class KeyguardAppWidgetPickActivity extends Activity
720b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka    implements GridView.OnItemClickListener,
730b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        AppWidgetLoader.ItemConstructor<KeyguardAppWidgetPickActivity.Item> {
740b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka    private static final String TAG = "KeyguardAppWidgetPickActivity";
750b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka    private static final int REQUEST_PICK_APPWIDGET = 126;
760b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka    private static final int REQUEST_CREATE_APPWIDGET = 127;
770b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka
780b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka    private AppWidgetLoader<Item> mAppWidgetLoader;
790b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka    private List<Item> mItems;
800b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka    private GridView mGridView;
814119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka    private AppWidgetAdapter mAppWidgetAdapter;
820b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka    private AppWidgetManager mAppWidgetManager;
830b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka    private int mAppWidgetId;
840b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka    // Might make it possible to make this be false in future
850b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka    private boolean mAddingToKeyguard = true;
860b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka    private Intent mResultData;
870b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka    private LockPatternUtils mLockPatternUtils;
88ab3472f5946c5dc3193c29513e31be7309ece378Michael Jurka    private Bundle mExtraConfigureOptions;
890b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka
900b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka    @Override
910b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka    protected void onCreate(Bundle savedInstanceState) {
92a487bca4700a9dbd5d5d72913d0265ae86815edfMichael Jurka        setContentView(R.layout.keyguard_appwidget_picker_layout);
930b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        super.onCreate(savedInstanceState);
940b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka
950b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        // Set default return data
960b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        setResultData(RESULT_CANCELED, null);
970b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka
980b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        // Read the appWidgetId passed our direction, otherwise bail if not found
990b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        final Intent intent = getIntent();
1000b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        if (intent.hasExtra(AppWidgetManager.EXTRA_APPWIDGET_ID)) {
1010b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka            mAppWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
1020b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka                    AppWidgetManager.INVALID_APPWIDGET_ID);
1030b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        } else {
1040b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka            finish();
1050b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        }
106ab3472f5946c5dc3193c29513e31be7309ece378Michael Jurka        mExtraConfigureOptions = intent.getBundleExtra(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS);
1070b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka
1080b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        mGridView = (GridView) findViewById(R.id.widget_list);
109a487bca4700a9dbd5d5d72913d0265ae86815edfMichael Jurka        DisplayMetrics dm = new DisplayMetrics();
110a487bca4700a9dbd5d5d72913d0265ae86815edfMichael Jurka        getWindowManager().getDefaultDisplay().getMetrics(dm);
111a487bca4700a9dbd5d5d72913d0265ae86815edfMichael Jurka        int maxGridWidth = getResources().getDimensionPixelSize(
112a487bca4700a9dbd5d5d72913d0265ae86815edfMichael Jurka                R.dimen.keyguard_appwidget_picker_max_width);
113a487bca4700a9dbd5d5d72913d0265ae86815edfMichael Jurka
114a487bca4700a9dbd5d5d72913d0265ae86815edfMichael Jurka        if (maxGridWidth < dm.widthPixels) {
115a487bca4700a9dbd5d5d72913d0265ae86815edfMichael Jurka            mGridView.getLayoutParams().width = maxGridWidth;
116a487bca4700a9dbd5d5d72913d0265ae86815edfMichael Jurka        }
1170b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        mAppWidgetManager = AppWidgetManager.getInstance(this);
1180b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        mAppWidgetLoader = new AppWidgetLoader<Item>(this, mAppWidgetManager, this);
1190b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        mItems = mAppWidgetLoader.getItems(getIntent());
1204119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka        mAppWidgetAdapter = new AppWidgetAdapter(this, mItems);
1214119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka        mGridView.setAdapter(mAppWidgetAdapter);
1220b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        mGridView.setOnItemClickListener(this);
1230b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka
1240b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        mLockPatternUtils = new LockPatternUtils(this); // TEMP-- we want to delete this
1250b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka    }
1260b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka
1270b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka    /**
1280b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka     * Convenience method for setting the result code and intent. This method
1290b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka     * correctly injects the {@link AppWidgetManager#EXTRA_APPWIDGET_ID} that
1300b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka     * most hosts expect returned.
1310b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka     */
1320b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka    void setResultData(int code, Intent intent) {
1330b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        Intent result = intent != null ? intent : new Intent();
1340b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        result.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
1350b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        mResultData = result;
1360b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        setResult(code, result);
1370b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka    }
1380b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka
1390b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka    /**
1400b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka     * Item that appears in the AppWidget picker grid.
1410b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka     */
1420b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka    public static class Item implements AppWidgetLoader.LabelledItem {
1430b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        protected static IconResizer sResizer;
1440b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka
1454119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka
1460b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        CharSequence label;
1474119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka        int appWidgetPreviewId;
1484119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka        int iconId;
1490b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        String packageName;
1500b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        String className;
1510b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        Bundle extras;
1524119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka        private WidgetPreviewLoader mWidgetPreviewLoader;
1534119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka        private Context mContext;
1540b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka
1550b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        /**
1560b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka         * Create a list item from given label and icon.
1570b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka         */
1584119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka        Item(Context context, CharSequence label) {
1590b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka            this.label = label;
1604119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka            mContext = context;
1610b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        }
1620b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka
1634119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka        void loadWidgetPreview(ImageView v) {
1644119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka            mWidgetPreviewLoader = new WidgetPreviewLoader(mContext, v);
1654119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka            mWidgetPreviewLoader.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, (Void[]) null);
1664119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka        }
1670b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka
1684119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka        void cancelLoadingWidgetPreview() {
1694119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka            if (mWidgetPreviewLoader != null) {
1704119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                mWidgetPreviewLoader.cancel(false);
1714119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                mWidgetPreviewLoader = null;
1724119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka            }
1730b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        }
1740b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka
1750b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        /**
1760b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka         * Build the {@link Intent} described by this item. If this item
1770b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka         * can't create a valid {@link android.content.ComponentName}, it will return
1780b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka         * {@link Intent#ACTION_CREATE_SHORTCUT} filled with the item label.
1790b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka         */
1800b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        Intent getIntent() {
1810b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka            Intent intent = new Intent();
1820b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka            if (packageName != null && className != null) {
1830b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka                // Valid package and class, so fill details as normal intent
1840b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka                intent.setClassName(packageName, className);
1850b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka                if (extras != null) {
1860b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka                    intent.putExtras(extras);
1870b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka                }
1880b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka            } else {
1890b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka                // No valid package or class, so treat as shortcut with label
1900b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka                intent.setAction(Intent.ACTION_CREATE_SHORTCUT);
1910b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka                intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, label);
1920b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka            }
1930b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka            return intent;
1940b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        }
1950b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka
1960b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        public CharSequence getLabel() {
1970b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka            return label;
1980b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        }
1990b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka
2004119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka        class WidgetPreviewLoader extends AsyncTask<Void, Bitmap, Void> {
2014119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka            private Resources mResources;
2024119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka            private PackageManager mPackageManager;
2034119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka            private int mIconDpi;
2044119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka            private ImageView mView;
2054119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka            public WidgetPreviewLoader(Context context, ImageView v) {
2064119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                super();
2074119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                mResources = context.getResources();
2084119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                mPackageManager = context.getPackageManager();
2094119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                ActivityManager activityManager =
2104119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                        (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
2114119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                mIconDpi = activityManager.getLauncherLargeIconDensity();
2124119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                mView = v;
2134119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka            }
2144119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka            public Void doInBackground(Void... params) {
2154119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                if (!isCancelled()) {
2164119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                    int appWidgetPreviewWidth =
2174119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                            mResources.getDimensionPixelSize(R.dimen.appwidget_preview_width);
2184119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                    int appWidgetPreviewHeight =
2194119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                            mResources.getDimensionPixelSize(R.dimen.appwidget_preview_height);
2204119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                    Bitmap b = getWidgetPreview(new ComponentName(packageName, className),
2214119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                            appWidgetPreviewId, iconId,
2224119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                            appWidgetPreviewWidth, appWidgetPreviewHeight);
2234119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                    publishProgress(b);
2244119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                }
2254119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                return null;
2264119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka            }
2274119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka            public void onProgressUpdate(Bitmap... values) {
2284119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                if (!isCancelled()) {
2294119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                    Bitmap b = values[0];
2304119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                    mView.setImageBitmap(b);
2314119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                }
2324119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka            }
2334119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka            abstract class WeakReferenceThreadLocal<T> {
2344119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                private ThreadLocal<WeakReference<T>> mThreadLocal;
2354119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                public WeakReferenceThreadLocal() {
2364119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                    mThreadLocal = new ThreadLocal<WeakReference<T>>();
2374119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                }
2380b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka
2394119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                abstract T initialValue();
2404119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka
2414119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                public void set(T t) {
2424119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                    mThreadLocal.set(new WeakReference<T>(t));
2434119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                }
2444119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka
2454119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                public T get() {
2464119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                    WeakReference<T> reference = mThreadLocal.get();
2474119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                    T obj;
2484119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                    if (reference == null) {
2494119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                        obj = initialValue();
2504119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                        mThreadLocal.set(new WeakReference<T>(obj));
2514119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                        return obj;
2524119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                    } else {
2534119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                        obj = reference.get();
2544119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                        if (obj == null) {
2554119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                            obj = initialValue();
2564119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                            mThreadLocal.set(new WeakReference<T>(obj));
2574119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                        }
2584119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                        return obj;
2594119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                    }
2604119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                }
2614119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka            }
2624119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka
2634119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka            class CanvasCache extends WeakReferenceThreadLocal<Canvas> {
2644119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                @Override
2654119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                protected Canvas initialValue() {
2664119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                    return new Canvas();
2674119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                }
2684119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka            }
2694119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka
2704119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka            class PaintCache extends WeakReferenceThreadLocal<Paint> {
2714119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                @Override
2724119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                protected Paint initialValue() {
2734119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                    return null;
2744119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                }
2754119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka            }
2764119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka
2774119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka            class BitmapCache extends WeakReferenceThreadLocal<Bitmap> {
2784119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                @Override
2794119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                protected Bitmap initialValue() {
2804119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                    return null;
2810b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka                }
2820b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka            }
2834119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka
2844119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka            class RectCache extends WeakReferenceThreadLocal<Rect> {
2854119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                @Override
2864119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                protected Rect initialValue() {
2874119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                    return new Rect();
2884119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                }
2894119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka            }
2904119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka
2914119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka            // Used for drawing widget previews
2924119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka            CanvasCache sCachedAppWidgetPreviewCanvas = new CanvasCache();
2934119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka            RectCache sCachedAppWidgetPreviewSrcRect = new RectCache();
2944119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka            RectCache sCachedAppWidgetPreviewDestRect = new RectCache();
2954119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka            PaintCache sCachedAppWidgetPreviewPaint = new PaintCache();
2964119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka
2974119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka            private Bitmap getWidgetPreview(ComponentName provider, int previewImage,
2984119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                    int iconId, int maxWidth, int maxHeight) {
2994119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                // Load the preview image if possible
3004119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                String packageName = provider.getPackageName();
3014119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                if (maxWidth < 0) maxWidth = Integer.MAX_VALUE;
3024119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                if (maxHeight < 0) maxHeight = Integer.MAX_VALUE;
3034119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka
3044119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka
3054119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                int appIconSize = mResources.getDimensionPixelSize(R.dimen.app_icon_size);
3064119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka
3074119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                Drawable drawable = null;
3084119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                if (previewImage != 0) {
3094119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                    drawable = mPackageManager.getDrawable(packageName, previewImage, null);
3104119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                    if (drawable == null) {
3114119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                        Log.w(TAG, "Can't load widget preview drawable 0x" +
3124119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                                Integer.toHexString(previewImage) + " for provider: " + provider);
3134119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                    }
3144119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                }
3154119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka
3164119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                int bitmapWidth;
3174119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                int bitmapHeight;
3184119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                Bitmap defaultPreview = null;
3194119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                boolean widgetPreviewExists = (drawable != null);
3204119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                if (widgetPreviewExists) {
3214119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                    bitmapWidth = drawable.getIntrinsicWidth();
3224119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                    bitmapHeight = drawable.getIntrinsicHeight();
3234119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                } else {
3244119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                    // Generate a preview image if we couldn't load one
325a108d9fc0edd3b4f741fae595e35a246fbc700ffMichael Jurka                    bitmapWidth = appIconSize;
326a108d9fc0edd3b4f741fae595e35a246fbc700ffMichael Jurka                    bitmapHeight = appIconSize;
3274119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                    defaultPreview = Bitmap.createBitmap(bitmapWidth, bitmapHeight,
3284119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                            Config.ARGB_8888);
3294119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka
3304119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                    try {
3314119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                        Drawable icon = null;
3324119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                        if (iconId > 0)
3334119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                            icon = getFullResIcon(packageName, iconId);
3344119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                        if (icon != null) {
335a108d9fc0edd3b4f741fae595e35a246fbc700ffMichael Jurka                            renderDrawableToBitmap(icon, defaultPreview, 0,
336a108d9fc0edd3b4f741fae595e35a246fbc700ffMichael Jurka                                    0, appIconSize, appIconSize);
3374119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                        }
3384119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                    } catch (Resources.NotFoundException e) {
3394119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                    }
3404119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                }
3414119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka
3424119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                // Scale to fit width only - let the widget preview be clipped in the
3434119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                // vertical dimension
3444119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                float scale = 1f;
3454119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                if (bitmapWidth > maxWidth) {
3464119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                    scale = maxWidth / (float) bitmapWidth;
3474119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                }
3484119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                int finalPreviewWidth = (int) (scale * bitmapWidth);
3494119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                int finalPreviewHeight = (int) (scale * bitmapHeight);
3504119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka
3514119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                bitmapWidth = finalPreviewWidth;
3524119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                bitmapHeight = Math.min(finalPreviewHeight, maxHeight);
3534119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka
3544119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                Bitmap preview = Bitmap.createBitmap(bitmapWidth, bitmapHeight,
3554119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                        Config.ARGB_8888);
3564119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka
3574119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                // Draw the scaled preview into the final bitmap
3584119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                if (widgetPreviewExists) {
3594119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                    renderDrawableToBitmap(drawable, preview, 0, 0, finalPreviewWidth,
3604119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                            finalPreviewHeight);
3614119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                } else {
3624119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                    final Canvas c = sCachedAppWidgetPreviewCanvas.get();
3634119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                    final Rect src = sCachedAppWidgetPreviewSrcRect.get();
3644119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                    final Rect dest = sCachedAppWidgetPreviewDestRect.get();
3654119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                    c.setBitmap(preview);
3664119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                    src.set(0, 0, defaultPreview.getWidth(), defaultPreview.getHeight());
3674119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                    dest.set(0, 0, finalPreviewWidth, finalPreviewHeight);
3684119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka
3694119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                    Paint p = sCachedAppWidgetPreviewPaint.get();
3704119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                    if (p == null) {
3714119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                        p = new Paint();
3724119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                        p.setFilterBitmap(true);
3734119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                        sCachedAppWidgetPreviewPaint.set(p);
3744119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                    }
3754119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                    c.drawBitmap(defaultPreview, src, dest, p);
3764119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                    c.setBitmap(null);
3774119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                }
3784119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                return preview;
3794119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka            }
3804119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka            public Drawable getFullResDefaultActivityIcon() {
3814119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                return getFullResIcon(Resources.getSystem(),
3824119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                        android.R.mipmap.sym_def_app_icon);
3834119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka            }
3844119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka
3854119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka            public Drawable getFullResIcon(Resources resources, int iconId) {
3864119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                Drawable d;
3874119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                try {
3884119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                    d = resources.getDrawableForDensity(iconId, mIconDpi);
3894119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                } catch (Resources.NotFoundException e) {
3904119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                    d = null;
3914119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                }
3924119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka
3934119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                return (d != null) ? d : getFullResDefaultActivityIcon();
3944119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka            }
3954119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka
3964119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka            public Drawable getFullResIcon(String packageName, int iconId) {
3974119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                Resources resources;
3984119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                try {
3994119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                    resources = mPackageManager.getResourcesForApplication(packageName);
4004119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                } catch (PackageManager.NameNotFoundException e) {
4014119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                    resources = null;
4024119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                }
4034119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                if (resources != null) {
4044119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                    if (iconId != 0) {
4054119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                        return getFullResIcon(resources, iconId);
4064119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                    }
4074119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                }
4084119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                return getFullResDefaultActivityIcon();
4094119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka            }
4104119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka
4114119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka            private void renderDrawableToBitmap(Drawable d, Bitmap bitmap, int x, int y, int w, int h) {
4124119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                renderDrawableToBitmap(d, bitmap, x, y, w, h, 1f);
4134119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka            }
4144119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka
4154119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka            private void renderDrawableToBitmap(Drawable d, Bitmap bitmap, int x, int y, int w, int h,
4164119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                    float scale) {
4174119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                if (bitmap != null) {
4184119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                    Canvas c = new Canvas(bitmap);
4194119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                    c.scale(scale, scale);
4204119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                    Rect oldBounds = d.copyBounds();
4214119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                    d.setBounds(x, y, x + w, y + h);
4224119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                    d.draw(c);
4234119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                    d.setBounds(oldBounds); // Restore the bounds
4244119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                    c.setBitmap(null);
4254119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                }
4260b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka            }
4270b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        }
4284119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka    }
4294119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka
4304119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka    @Override
4314119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka    public Item createItem(Context context, AppWidgetProviderInfo info, Bundle extras) {
4324119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka        CharSequence label = info.label;
4330b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka
4344119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka        Item item = new Item(context, label);
4354119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka        item.appWidgetPreviewId = info.previewImage;
4364119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka        item.iconId = info.icon;
4370b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        item.packageName = info.provider.getPackageName();
4380b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        item.className = info.provider.getClassName();
4390b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        item.extras = extras;
4400b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        return item;
4410b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka    }
4420b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka
4430b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka    protected static class AppWidgetAdapter extends BaseAdapter {
4440b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        private final LayoutInflater mInflater;
4450b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        private final List<Item> mItems;
4460b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka
4470b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        /**
4480b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka         * Create an adapter for the given items.
4490b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka         */
4500b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        public AppWidgetAdapter(Context context, List<Item> items) {
4510b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka            mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
4520b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka            mItems = items;
4530b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        }
4540b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka
4550b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        /**
4560b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka         * {@inheritDoc}
4570b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka         */
4580b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        public int getCount() {
4590b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka            return mItems.size();
4600b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        }
4610b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka
4620b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        /**
4630b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka         * {@inheritDoc}
4640b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka         */
4650b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        public Object getItem(int position) {
4660b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka            return mItems.get(position);
4670b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        }
4680b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka
4690b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        /**
4700b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka         * {@inheritDoc}
4710b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka         */
4720b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        public long getItemId(int position) {
4730b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka            return position;
4740b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        }
4750b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka
4760b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        /**
4770b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka         * {@inheritDoc}
4780b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka         */
4790b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        public View getView(int position, View convertView, ViewGroup parent) {
4800b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka            if (convertView == null) {
4810b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka                convertView = mInflater.inflate(R.layout.keyguard_appwidget_item, parent, false);
4820b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka            }
4830b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka
4840b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka            Item item = (Item) getItem(position);
4854119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka            TextView textView = (TextView) convertView.findViewById(R.id.label);
4860b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka            textView.setText(item.label);
4874119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka            ImageView iconView = (ImageView) convertView.findViewById(R.id.icon);
4884119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka            iconView.setImageDrawable(null);
4894119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka            item.loadWidgetPreview(iconView);
4900b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka            return convertView;
4910b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        }
4924119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka
4934119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka        public void cancelAllWidgetPreviewLoaders() {
4944119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka            for (int i = 0; i < mItems.size(); i++) {
4954119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka                mItems.get(i).cancelLoadingWidgetPreview();
4964119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka            }
4974119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka        }
4980b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka    }
4990b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka
5000b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka    /**
5010b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka     * {@inheritDoc}
5020b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka     */
5030b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka    @Override
5040b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
5050b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        Item item = mItems.get(position);
5060b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        Intent intent = item.getIntent();
5070b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka
5080b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        int result;
5090b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        if (item.extras != null) {
5100b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka            // If these extras are present it's because this entry is custom.
5110b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka            // Don't try to bind it, just pass it back to the app.
5120b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka            result = RESULT_OK;
5130b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka            setResultData(result, intent);
5140b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        } else {
5150b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka            try {
516f5336fd114e557fce06197041aab70217308fe90Michael Jurka                if (mAddingToKeyguard && mAppWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
517f5336fd114e557fce06197041aab70217308fe90Michael Jurka                    // Found in KeyguardHostView.java
518f5336fd114e557fce06197041aab70217308fe90Michael Jurka                    final int KEYGUARD_HOST_ID = 0x4B455947;
519dd395e210aa7fa35935dbd2c416a6d01e971b367Jim Miller                    int userId = ActivityManager.getCurrentUser();
520dd395e210aa7fa35935dbd2c416a6d01e971b367Jim Miller                    mAppWidgetId = AppWidgetHost.allocateAppWidgetIdForSystem(KEYGUARD_HOST_ID,
521dd395e210aa7fa35935dbd2c416a6d01e971b367Jim Miller                            userId);
522f5336fd114e557fce06197041aab70217308fe90Michael Jurka                }
523ab3472f5946c5dc3193c29513e31be7309ece378Michael Jurka                mAppWidgetManager.bindAppWidgetId(
524ab3472f5946c5dc3193c29513e31be7309ece378Michael Jurka                        mAppWidgetId, intent.getComponent(), mExtraConfigureOptions);
5250b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka                result = RESULT_OK;
5260b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka            } catch (IllegalArgumentException e) {
5270b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka                // This is thrown if they're already bound, or otherwise somehow
5280b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka                // bogus.  Set the result to canceled, and exit.  The app *should*
5290b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka                // clean up at this point.  We could pass the error along, but
5300b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka                // it's not clear that that's useful -- the widget will simply not
5310b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka                // appear.
5320b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka                result = RESULT_CANCELED;
5330b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka            }
5340b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka            setResultData(result, null);
5350b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        }
5360b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        if (mAddingToKeyguard) {
5370b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka            onActivityResult(REQUEST_PICK_APPWIDGET, result, mResultData);
5380b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        } else {
5390b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka            finish();
5400b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        }
5410b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka    }
5420b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka
5430b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka    protected void onDestroy() {
5444119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka        if (mAppWidgetAdapter != null) {
5454119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka            mAppWidgetAdapter.cancelAllWidgetPreviewLoaders();
5464119788b1be5d9b51e3c5cfe4e32f2aacc5a2f8fMichael Jurka        }
5470b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        super.onDestroy();
5480b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka    }
5490b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka
5500b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka    @Override
5510b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka    public void onActivityResult(int requestCode, int resultCode, Intent data) {
5520b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        super.onActivityResult(requestCode, resultCode, data);
5530b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        if (requestCode == REQUEST_PICK_APPWIDGET || requestCode == REQUEST_CREATE_APPWIDGET) {
554f5336fd114e557fce06197041aab70217308fe90Michael Jurka            int appWidgetId;
555f5336fd114e557fce06197041aab70217308fe90Michael Jurka            if  (data == null) {
556f5336fd114e557fce06197041aab70217308fe90Michael Jurka                appWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID ;
557f5336fd114e557fce06197041aab70217308fe90Michael Jurka            } else {
558f5336fd114e557fce06197041aab70217308fe90Michael Jurka                appWidgetId = data.getIntExtra(
559f5336fd114e557fce06197041aab70217308fe90Michael Jurka                        AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
560f5336fd114e557fce06197041aab70217308fe90Michael Jurka            }
561f5336fd114e557fce06197041aab70217308fe90Michael Jurka            if (requestCode == REQUEST_PICK_APPWIDGET && resultCode == Activity.RESULT_OK) {
5620b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka                AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(this);
5630b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka
5640b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka                AppWidgetProviderInfo appWidget = null;
565f5336fd114e557fce06197041aab70217308fe90Michael Jurka                appWidget = appWidgetManager.getAppWidgetInfo(appWidgetId);
5660b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka
567f5336fd114e557fce06197041aab70217308fe90Michael Jurka                if (appWidget.configure != null) {
5680b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka                    // Launch over to configure widget, if needed
5690b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka                    Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_CONFIGURE);
5700b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka                    intent.setComponent(appWidget.configure);
5710b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka                    intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
5720b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka                    intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
5730b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka
5740b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka                    startActivityForResultSafely(intent, REQUEST_CREATE_APPWIDGET);
5750b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka                } else {
5760b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka                    // Otherwise just add it
5770b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka                    onActivityResult(REQUEST_CREATE_APPWIDGET, Activity.RESULT_OK, data);
5780b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka                }
5790b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka            } else if (requestCode == REQUEST_CREATE_APPWIDGET && resultCode == Activity.RESULT_OK) {
5800b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka                mLockPatternUtils.addAppWidget(appWidgetId, 0);
5815c5eff45e97a2bb1b55befb87eb535a438a7bbf8Michael Jurka                finishDelayedAndShowLockScreen(appWidgetId);
5820b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka            } else {
583f5336fd114e557fce06197041aab70217308fe90Michael Jurka                if (mAddingToKeyguard &&
584f5336fd114e557fce06197041aab70217308fe90Michael Jurka                        mAppWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID) {
585dd395e210aa7fa35935dbd2c416a6d01e971b367Jim Miller                    int userId = ActivityManager.getCurrentUser();
586dd395e210aa7fa35935dbd2c416a6d01e971b367Jim Miller                    AppWidgetHost.deleteAppWidgetIdForSystem(mAppWidgetId, userId);
587f5336fd114e557fce06197041aab70217308fe90Michael Jurka                }
5885c5eff45e97a2bb1b55befb87eb535a438a7bbf8Michael Jurka                finishDelayedAndShowLockScreen(AppWidgetManager.INVALID_APPWIDGET_ID);
5890b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka            }
5900b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        }
5910b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka    }
5920b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka
5935c5eff45e97a2bb1b55befb87eb535a438a7bbf8Michael Jurka    private void finishDelayedAndShowLockScreen(int appWidgetId) {
5940b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        IBinder b = ServiceManager.getService(Context.WINDOW_SERVICE);
5950b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        IWindowManager iWm = IWindowManager.Stub.asInterface(b);
5965c5eff45e97a2bb1b55befb87eb535a438a7bbf8Michael Jurka        Bundle opts = null;
5975c5eff45e97a2bb1b55befb87eb535a438a7bbf8Michael Jurka        if (appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID) {
5985c5eff45e97a2bb1b55befb87eb535a438a7bbf8Michael Jurka            opts = new Bundle();
5995c5eff45e97a2bb1b55befb87eb535a438a7bbf8Michael Jurka            opts.putInt(LockPatternUtils.KEYGUARD_SHOW_APPWIDGET, appWidgetId);
6005c5eff45e97a2bb1b55befb87eb535a438a7bbf8Michael Jurka        }
6010b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        try {
6025c5eff45e97a2bb1b55befb87eb535a438a7bbf8Michael Jurka            iWm.lockNow(opts);
6030b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        } catch (RemoteException e) {
6040b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        }
6050b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka
6060b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        // Change background to all black
6070b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        ViewGroup root = (ViewGroup) findViewById(R.id.layout_root);
6080b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        root.setBackgroundColor(0xFF000000);
6090b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        // Hide all children
6100b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        final int childCount = root.getChildCount();
6110b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        for (int i = 0; i < childCount; i++) {
6120b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka            root.getChildAt(i).setVisibility(View.INVISIBLE);
6130b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        }
6140b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        mGridView.postDelayed(new Runnable() {
6150b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka            public void run() {
6160b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka                finish();
6170b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka            }
6180b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        }, 500);
6190b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka    }
6200b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka
6210b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka    void startActivityForResultSafely(Intent intent, int requestCode) {
6220b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        try {
6230b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka            startActivityForResult(intent, requestCode);
6240b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        } catch (ActivityNotFoundException e) {
6250b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka            Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
6260b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        } catch (SecurityException e) {
6270b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka            Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
6280b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka            Log.e(TAG, "Settings does not have the permission to launch " + intent, e);
6290b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka        }
6300b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka    }
6310b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka}
632