Home | History | Annotate | Download | only in gadget
      1 /*
      2  * Copyright (C) 2011 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.gallery3d.gadget;
     18 
     19 import android.app.Activity;
     20 import android.appwidget.AppWidgetManager;
     21 import android.content.Intent;
     22 import android.content.res.Resources;
     23 import android.graphics.Bitmap;
     24 import android.net.Uri;
     25 import android.os.Bundle;
     26 import android.util.Log;
     27 import android.widget.RemoteViews;
     28 
     29 import com.android.gallery3d.R;
     30 import com.android.gallery3d.app.AlbumPicker;
     31 import com.android.gallery3d.app.DialogPicker;
     32 import com.android.gallery3d.app.GalleryApp;
     33 import com.android.gallery3d.common.ApiHelper;
     34 import com.android.gallery3d.data.DataManager;
     35 import com.android.gallery3d.data.LocalAlbum;
     36 import com.android.gallery3d.data.MediaSet;
     37 import com.android.gallery3d.data.Path;
     38 import com.android.gallery3d.filtershow.crop.CropActivity;
     39 import com.android.gallery3d.filtershow.crop.CropExtras;
     40 
     41 public class WidgetConfigure extends Activity {
     42     @SuppressWarnings("unused")
     43     private static final String TAG = "WidgetConfigure";
     44 
     45     public static final String KEY_WIDGET_TYPE = "widget-type";
     46     private static final String KEY_PICKED_ITEM = "picked-item";
     47 
     48     private static final int REQUEST_WIDGET_TYPE = 1;
     49     private static final int REQUEST_CHOOSE_ALBUM = 2;
     50     private static final int REQUEST_CROP_IMAGE = 3;
     51     private static final int REQUEST_GET_PHOTO = 4;
     52 
     53     public static final int RESULT_ERROR = RESULT_FIRST_USER;
     54 
     55     // Scale up the widget size since we only specified the minimized
     56     // size of the gadget. The real size could be larger.
     57     // Note: There is also a limit on the size of data that can be
     58     // passed in Binder's transaction.
     59     private static float WIDGET_SCALE_FACTOR = 1.5f;
     60     private static int MAX_WIDGET_SIDE = 360;
     61 
     62     private int mAppWidgetId = -1;
     63     private Uri mPickedItem;
     64 
     65     @Override
     66     protected void onCreate(Bundle savedState) {
     67         super.onCreate(savedState);
     68         mAppWidgetId = getIntent().getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
     69 
     70         if (mAppWidgetId == -1) {
     71             setResult(Activity.RESULT_CANCELED);
     72             finish();
     73             return;
     74         }
     75 
     76         if (savedState == null) {
     77             if (ApiHelper.HAS_REMOTE_VIEWS_SERVICE) {
     78                 Intent intent = new Intent(this, WidgetTypeChooser.class);
     79                 startActivityForResult(intent, REQUEST_WIDGET_TYPE);
     80             } else { // Choose the photo type widget
     81                 setWidgetType(new Intent()
     82                         .putExtra(KEY_WIDGET_TYPE, R.id.widget_type_photo));
     83             }
     84         } else {
     85             mPickedItem = savedState.getParcelable(KEY_PICKED_ITEM);
     86         }
     87     }
     88 
     89     protected void onSaveInstanceStates(Bundle outState) {
     90         super.onSaveInstanceState(outState);
     91         outState.putParcelable(KEY_PICKED_ITEM, mPickedItem);
     92     }
     93 
     94     private void updateWidgetAndFinish(WidgetDatabaseHelper.Entry entry) {
     95         AppWidgetManager manager = AppWidgetManager.getInstance(this);
     96         RemoteViews views = PhotoAppWidgetProvider.buildWidget(this, mAppWidgetId, entry);
     97         manager.updateAppWidget(mAppWidgetId, views);
     98         setResult(RESULT_OK, new Intent().putExtra(
     99                 AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId));
    100         finish();
    101     }
    102 
    103     @Override
    104     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    105         if (resultCode != RESULT_OK) {
    106             setResult(resultCode, new Intent().putExtra(
    107                     AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId));
    108             finish();
    109             return;
    110         }
    111 
    112         if (requestCode == REQUEST_WIDGET_TYPE) {
    113             setWidgetType(data);
    114         } else if (requestCode == REQUEST_CHOOSE_ALBUM) {
    115             setChoosenAlbum(data);
    116         } else if (requestCode == REQUEST_GET_PHOTO) {
    117             setChoosenPhoto(data);
    118         } else if (requestCode == REQUEST_CROP_IMAGE) {
    119             setPhotoWidget(data);
    120         } else {
    121             throw new AssertionError("unknown request: " + requestCode);
    122         }
    123     }
    124 
    125     private void setPhotoWidget(Intent data) {
    126         // Store the cropped photo in our database
    127         Bitmap bitmap = (Bitmap) data.getParcelableExtra("data");
    128         WidgetDatabaseHelper helper = new WidgetDatabaseHelper(this);
    129         try {
    130             helper.setPhoto(mAppWidgetId, mPickedItem, bitmap);
    131             updateWidgetAndFinish(helper.getEntry(mAppWidgetId));
    132         } finally {
    133             helper.close();
    134         }
    135     }
    136 
    137     private void setChoosenPhoto(Intent data) {
    138         Resources res = getResources();
    139 
    140         float width = res.getDimension(R.dimen.appwidget_width);
    141         float height = res.getDimension(R.dimen.appwidget_height);
    142 
    143         // We try to crop a larger image (by scale factor), but there is still
    144         // a bound on the binder limit.
    145         float scale = Math.min(WIDGET_SCALE_FACTOR,
    146                 MAX_WIDGET_SIDE / Math.max(width, height));
    147 
    148         int widgetWidth = Math.round(width * scale);
    149         int widgetHeight = Math.round(height * scale);
    150 
    151         mPickedItem = data.getData();
    152         Intent request = new Intent(CropActivity.CROP_ACTION, mPickedItem)
    153                 .putExtra(CropExtras.KEY_OUTPUT_X, widgetWidth)
    154                 .putExtra(CropExtras.KEY_OUTPUT_Y, widgetHeight)
    155                 .putExtra(CropExtras.KEY_ASPECT_X, widgetWidth)
    156                 .putExtra(CropExtras.KEY_ASPECT_Y, widgetHeight)
    157                 .putExtra(CropExtras.KEY_SCALE_UP_IF_NEEDED, true)
    158                 .putExtra(CropExtras.KEY_SCALE, true)
    159                 .putExtra(CropExtras.KEY_RETURN_DATA, true);
    160         startActivityForResult(request, REQUEST_CROP_IMAGE);
    161     }
    162 
    163     private void setChoosenAlbum(Intent data) {
    164         String albumPath = data.getStringExtra(AlbumPicker.KEY_ALBUM_PATH);
    165         WidgetDatabaseHelper helper = new WidgetDatabaseHelper(this);
    166         try {
    167             String relativePath = null;
    168             GalleryApp galleryApp = (GalleryApp) getApplicationContext();
    169             DataManager manager = galleryApp.getDataManager();
    170             Path path = Path.fromString(albumPath);
    171             MediaSet mediaSet = (MediaSet) manager.getMediaObject(path);
    172             if (mediaSet instanceof LocalAlbum) {
    173                 int bucketId = Integer.parseInt(path.getSuffix());
    174                 // If the chosen album is a local album, find relative path
    175                 // Otherwise, leave the relative path field empty
    176                 relativePath = LocalAlbum.getRelativePath(bucketId);
    177                 Log.i(TAG, "Setting widget, album path: " + albumPath
    178                         + ", relative path: " + relativePath);
    179             }
    180             helper.setWidget(mAppWidgetId,
    181                     WidgetDatabaseHelper.TYPE_ALBUM, albumPath, relativePath);
    182             updateWidgetAndFinish(helper.getEntry(mAppWidgetId));
    183         } finally {
    184             helper.close();
    185         }
    186     }
    187 
    188     private void setWidgetType(Intent data) {
    189         int widgetType = data.getIntExtra(KEY_WIDGET_TYPE, R.id.widget_type_shuffle);
    190         if (widgetType == R.id.widget_type_album) {
    191             Intent intent = new Intent(this, AlbumPicker.class);
    192             startActivityForResult(intent, REQUEST_CHOOSE_ALBUM);
    193         } else if (widgetType == R.id.widget_type_shuffle) {
    194             WidgetDatabaseHelper helper = new WidgetDatabaseHelper(this);
    195             try {
    196                 helper.setWidget(mAppWidgetId, WidgetDatabaseHelper.TYPE_SHUFFLE, null, null);
    197                 updateWidgetAndFinish(helper.getEntry(mAppWidgetId));
    198             } finally {
    199                 helper.close();
    200             }
    201         } else {
    202             // Explicitly send the intent to the DialogPhotoPicker
    203             Intent request = new Intent(this, DialogPicker.class)
    204                     .setAction(Intent.ACTION_GET_CONTENT)
    205                     .setType("image/*");
    206             startActivityForResult(request, REQUEST_GET_PHOTO);
    207         }
    208     }
    209 }
    210