WidgetConfigure.java revision a2cb30b688131380cab763a1b4da25f15a9fa45a
1f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin/*
2f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * Copyright (C) 2011 The Android Open Source Project
3f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin *
4f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * Licensed under the Apache License, Version 2.0 (the "License");
5f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * you may not use this file except in compliance with the License.
6f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * You may obtain a copy of the License at
7f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin *
8f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin *      http://www.apache.org/licenses/LICENSE-2.0
9f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin *
10f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * Unless required by applicable law or agreed to in writing, software
11f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * distributed under the License is distributed on an "AS IS" BASIS,
12f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * See the License for the specific language governing permissions and
14f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * limitations under the License.
15f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin */
16f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
17d6db8eab6df048b9065834113a6d46a885af01d3Owen Linpackage com.android.gallery3d.gadget;
18f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
19f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.app.Activity;
20f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.appwidget.AppWidgetManager;
21f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.content.Intent;
22f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.content.res.Resources;
23f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.graphics.Bitmap;
24f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.net.Uri;
25f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.os.Bundle;
26f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.widget.RemoteViews;
27f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
282b3ee0ea07246b859a5b75d8a6102a7cce7ec838Owen Linimport com.android.gallery3d.R;
292b3ee0ea07246b859a5b75d8a6102a7cce7ec838Owen Linimport com.android.gallery3d.app.AlbumPicker;
302b3ee0ea07246b859a5b75d8a6102a7cce7ec838Owen Linimport com.android.gallery3d.app.CropImage;
312b3ee0ea07246b859a5b75d8a6102a7cce7ec838Owen Linimport com.android.gallery3d.app.DialogPicker;
32a2cb30b688131380cab763a1b4da25f15a9fa45aOwen Linimport com.android.gallery3d.common.ApiHelper;
332b3ee0ea07246b859a5b75d8a6102a7cce7ec838Owen Lin
34f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linpublic class WidgetConfigure extends Activity {
35f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    @SuppressWarnings("unused")
36f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private static final String TAG = "WidgetConfigure";
37f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
38f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public static final String KEY_WIDGET_TYPE = "widget-type";
39a2cb30b688131380cab763a1b4da25f15a9fa45aOwen Lin    private static final String KEY_PICKED_ITEM = "picked-item";
40f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
41f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private static final int REQUEST_WIDGET_TYPE = 1;
42f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private static final int REQUEST_CHOOSE_ALBUM = 2;
43f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private static final int REQUEST_CROP_IMAGE = 3;
44f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private static final int REQUEST_GET_PHOTO = 4;
45f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
46f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public static final int RESULT_ERROR = RESULT_FIRST_USER;
47f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
48f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    // Scale up the widget size since we only specified the minimized
49f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    // size of the gadget. The real size could be larger.
50f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    // Note: There is also a limit on the size of data that can be
51f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    // passed in Binder's transaction.
52f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private static float WIDGET_SCALE_FACTOR = 1.5f;
535da31f8fd85d7c1e33133473bd1fbc5e3a240f2dOwen Lin    private static int MAX_WIDGET_SIDE = 360;
54f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
55f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private int mAppWidgetId = -1;
56f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private Uri mPickedItem;
57f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
58f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    @Override
59a2cb30b688131380cab763a1b4da25f15a9fa45aOwen Lin    protected void onCreate(Bundle savedState) {
60a2cb30b688131380cab763a1b4da25f15a9fa45aOwen Lin        super.onCreate(savedState);
61f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mAppWidgetId = getIntent().getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
62f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
63f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        if (mAppWidgetId == -1) {
64f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            setResult(Activity.RESULT_CANCELED);
65f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            finish();
66f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            return;
67f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
68f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
69a2cb30b688131380cab763a1b4da25f15a9fa45aOwen Lin        if (savedState == null) {
70a2cb30b688131380cab763a1b4da25f15a9fa45aOwen Lin            if (ApiHelper.HAS_REMOTE_VIEWS_SERVICE) {
71a2cb30b688131380cab763a1b4da25f15a9fa45aOwen Lin                Intent intent = new Intent(this, WidgetTypeChooser.class);
72a2cb30b688131380cab763a1b4da25f15a9fa45aOwen Lin                startActivityForResult(intent, REQUEST_WIDGET_TYPE);
73a2cb30b688131380cab763a1b4da25f15a9fa45aOwen Lin            } else { // Choose the photo type widget
74a2cb30b688131380cab763a1b4da25f15a9fa45aOwen Lin                setWidgetType(new Intent()
75a2cb30b688131380cab763a1b4da25f15a9fa45aOwen Lin                        .putExtra(KEY_WIDGET_TYPE, R.id.widget_type_photo));
76a2cb30b688131380cab763a1b4da25f15a9fa45aOwen Lin            }
77a2cb30b688131380cab763a1b4da25f15a9fa45aOwen Lin        } else {
78a2cb30b688131380cab763a1b4da25f15a9fa45aOwen Lin            mPickedItem = savedState.getParcelable(KEY_PICKED_ITEM);
79f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
80f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
81f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
82a2cb30b688131380cab763a1b4da25f15a9fa45aOwen Lin    protected void onSaveInstanceStates(Bundle outState) {
83a2cb30b688131380cab763a1b4da25f15a9fa45aOwen Lin        super.onSaveInstanceState(outState);
84a2cb30b688131380cab763a1b4da25f15a9fa45aOwen Lin        outState.putParcelable(KEY_PICKED_ITEM, mPickedItem);
85a2cb30b688131380cab763a1b4da25f15a9fa45aOwen Lin    }
86a2cb30b688131380cab763a1b4da25f15a9fa45aOwen Lin
87f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private void updateWidgetAndFinish(WidgetDatabaseHelper.Entry entry) {
88f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        AppWidgetManager manager = AppWidgetManager.getInstance(this);
89d6db8eab6df048b9065834113a6d46a885af01d3Owen Lin        RemoteViews views = PhotoAppWidgetProvider.buildWidget(this, mAppWidgetId, entry);
90f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        manager.updateAppWidget(mAppWidgetId, views);
91f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        setResult(RESULT_OK, new Intent().putExtra(
92f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId));
93f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        finish();
94f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
95f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
96f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    @Override
97f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
98f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        if (resultCode != RESULT_OK) {
99f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            setResult(resultCode, new Intent().putExtra(
100f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                    AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId));
101f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            finish();
102f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            return;
103f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
104f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
105f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        if (requestCode == REQUEST_WIDGET_TYPE) {
106f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            setWidgetType(data);
107f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        } else if (requestCode == REQUEST_CHOOSE_ALBUM) {
108f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            setChoosenAlbum(data);
109f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        } else if (requestCode == REQUEST_GET_PHOTO) {
110f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            setChoosenPhoto(data);
111f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        } else if (requestCode == REQUEST_CROP_IMAGE) {
112f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            setPhotoWidget(data);
113f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        } else {
114f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            throw new AssertionError("unknown request: " + requestCode);
115f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
116f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
117f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
118f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private void setPhotoWidget(Intent data) {
119f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        // Store the cropped photo in our database
120f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        Bitmap bitmap = (Bitmap) data.getParcelableExtra("data");
121f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        WidgetDatabaseHelper helper = new WidgetDatabaseHelper(this);
122f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        try {
123f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            helper.setPhoto(mAppWidgetId, mPickedItem, bitmap);
124f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            updateWidgetAndFinish(helper.getEntry(mAppWidgetId));
125f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        } finally {
126f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            helper.close();
127f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
128f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
129f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
130f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private void setChoosenPhoto(Intent data) {
131f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        Resources res = getResources();
1325da31f8fd85d7c1e33133473bd1fbc5e3a240f2dOwen Lin
1335da31f8fd85d7c1e33133473bd1fbc5e3a240f2dOwen Lin        float width = res.getDimension(R.dimen.appwidget_width);
1345da31f8fd85d7c1e33133473bd1fbc5e3a240f2dOwen Lin        float height = res.getDimension(R.dimen.appwidget_height);
1355da31f8fd85d7c1e33133473bd1fbc5e3a240f2dOwen Lin
1365da31f8fd85d7c1e33133473bd1fbc5e3a240f2dOwen Lin        // We try to crop a larger image (by scale factor), but there is still
1375da31f8fd85d7c1e33133473bd1fbc5e3a240f2dOwen Lin        // a bound on the binder limit.
1385da31f8fd85d7c1e33133473bd1fbc5e3a240f2dOwen Lin        float scale = Math.min(WIDGET_SCALE_FACTOR,
1395da31f8fd85d7c1e33133473bd1fbc5e3a240f2dOwen Lin                MAX_WIDGET_SIDE / Math.max(width, height));
1405da31f8fd85d7c1e33133473bd1fbc5e3a240f2dOwen Lin
1415da31f8fd85d7c1e33133473bd1fbc5e3a240f2dOwen Lin        int widgetWidth = Math.round(width * scale);
1425da31f8fd85d7c1e33133473bd1fbc5e3a240f2dOwen Lin        int widgetHeight = Math.round(height * scale);
1435da31f8fd85d7c1e33133473bd1fbc5e3a240f2dOwen Lin
144f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mPickedItem = data.getData();
145f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        Intent request = new Intent(CropImage.ACTION_CROP, mPickedItem)
146f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                .putExtra(CropImage.KEY_OUTPUT_X, widgetWidth)
147f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                .putExtra(CropImage.KEY_OUTPUT_Y, widgetHeight)
148f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                .putExtra(CropImage.KEY_ASPECT_X, widgetWidth)
149f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                .putExtra(CropImage.KEY_ASPECT_Y, widgetHeight)
150f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                .putExtra(CropImage.KEY_SCALE_UP_IF_NEEDED, true)
151f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                .putExtra(CropImage.KEY_SCALE, true)
152f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                .putExtra(CropImage.KEY_RETURN_DATA, true);
153f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        startActivityForResult(request, REQUEST_CROP_IMAGE);
154f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
155f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
156f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private void setChoosenAlbum(Intent data) {
157f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        String albumPath = data.getStringExtra(AlbumPicker.KEY_ALBUM_PATH);
158f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        WidgetDatabaseHelper helper = new WidgetDatabaseHelper(this);
159f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        try {
160f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            helper.setWidget(mAppWidgetId,
161f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                    WidgetDatabaseHelper.TYPE_ALBUM, albumPath);
162f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            updateWidgetAndFinish(helper.getEntry(mAppWidgetId));
163f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        } finally {
164f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            helper.close();
165f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
166f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
167f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
168f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private void setWidgetType(Intent data) {
169a2cb30b688131380cab763a1b4da25f15a9fa45aOwen Lin        int widgetType = data.getIntExtra(KEY_WIDGET_TYPE, R.id.widget_type_shuffle);
170a2cb30b688131380cab763a1b4da25f15a9fa45aOwen Lin        if (widgetType == R.id.widget_type_album) {
171f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            Intent intent = new Intent(this, AlbumPicker.class);
172f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            startActivityForResult(intent, REQUEST_CHOOSE_ALBUM);
173a2cb30b688131380cab763a1b4da25f15a9fa45aOwen Lin        } else if (widgetType == R.id.widget_type_shuffle) {
174f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            WidgetDatabaseHelper helper = new WidgetDatabaseHelper(this);
175f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            try {
176f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                helper.setWidget(mAppWidgetId, WidgetDatabaseHelper.TYPE_SHUFFLE, null);
177f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                updateWidgetAndFinish(helper.getEntry(mAppWidgetId));
178f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            } finally {
179f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                helper.close();
180f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            }
181f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        } else {
182f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            // Explicitly send the intent to the DialogPhotoPicker
183f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            Intent request = new Intent(this, DialogPicker.class)
184f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                    .setAction(Intent.ACTION_GET_CONTENT)
185f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                    .setType("image/*");
186f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            startActivityForResult(request, REQUEST_GET_PHOTO);
187f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
188f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
189f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin}
190