Home | History | Annotate | Download | only in gadget
      1 /*
      2  * Copyright (C) 2010 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 com.android.gallery3d.common.Utils;
     20 
     21 import android.content.ContentValues;
     22 import android.content.Context;
     23 import android.database.Cursor;
     24 import android.database.sqlite.SQLiteDatabase;
     25 import android.database.sqlite.SQLiteException;
     26 import android.database.sqlite.SQLiteOpenHelper;
     27 import android.graphics.Bitmap;
     28 import android.net.Uri;
     29 import android.util.Log;
     30 
     31 import java.io.ByteArrayOutputStream;
     32 import java.util.ArrayList;
     33 
     34 public class WidgetDatabaseHelper extends SQLiteOpenHelper {
     35     private static final String TAG = "PhotoDatabaseHelper";
     36     private static final String DATABASE_NAME = "launcher.db";
     37 
     38     private static final int DATABASE_VERSION = 4;
     39 
     40     private static final String TABLE_WIDGETS = "widgets";
     41 
     42     private static final String FIELD_APPWIDGET_ID = "appWidgetId";
     43     private static final String FIELD_IMAGE_URI = "imageUri";
     44     private static final String FIELD_PHOTO_BLOB = "photoBlob";
     45     private static final String FIELD_WIDGET_TYPE = "widgetType";
     46     private static final String FIELD_ALBUM_PATH = "albumPath";
     47 
     48     public static final int TYPE_SINGLE_PHOTO = 0;
     49     public static final int TYPE_SHUFFLE = 1;
     50     public static final int TYPE_ALBUM = 2;
     51 
     52     private static final String[] PROJECTION = {
     53             FIELD_WIDGET_TYPE, FIELD_IMAGE_URI, FIELD_PHOTO_BLOB, FIELD_ALBUM_PATH};
     54     private static final int INDEX_WIDGET_TYPE = 0;
     55     private static final int INDEX_IMAGE_URI = 1;
     56     private static final int INDEX_PHOTO_BLOB = 2;
     57     private static final int INDEX_ALBUM_PATH = 3;
     58     private static final String WHERE_CLAUSE = FIELD_APPWIDGET_ID + " = ?";
     59 
     60     public static class Entry {
     61         public int widgetId;
     62         public int type;
     63         public String imageUri;
     64         public byte imageData[];
     65         public String albumPath;
     66 
     67         private Entry() {}
     68 
     69         private Entry(int id, Cursor cursor) {
     70             widgetId = id;
     71             type = cursor.getInt(INDEX_WIDGET_TYPE);
     72             if (type == TYPE_SINGLE_PHOTO) {
     73                 imageUri = cursor.getString(INDEX_IMAGE_URI);
     74                 imageData = cursor.getBlob(INDEX_PHOTO_BLOB);
     75             } else if (type == TYPE_ALBUM) {
     76                 albumPath = cursor.getString(INDEX_ALBUM_PATH);
     77             }
     78         }
     79     }
     80 
     81     public WidgetDatabaseHelper(Context context) {
     82         super(context, DATABASE_NAME, null, DATABASE_VERSION);
     83     }
     84 
     85     @Override
     86     public void onCreate(SQLiteDatabase db) {
     87         db.execSQL("CREATE TABLE " + TABLE_WIDGETS + " ("
     88                 + FIELD_APPWIDGET_ID + " INTEGER PRIMARY KEY, "
     89                 + FIELD_WIDGET_TYPE + " INTEGER DEFAULT 0, "
     90                 + FIELD_IMAGE_URI + " TEXT, "
     91                 + FIELD_ALBUM_PATH + " TEXT, "
     92                 + FIELD_PHOTO_BLOB + " BLOB)");
     93     }
     94 
     95     private void saveData(SQLiteDatabase db, int oldVersion, ArrayList<Entry> data) {
     96         if (oldVersion <= 2) {
     97             Cursor cursor = db.query("photos",
     98                     new String[] {FIELD_APPWIDGET_ID, FIELD_PHOTO_BLOB},
     99                     null, null, null, null, null);
    100             if (cursor == null) return;
    101             try {
    102                 while (cursor.moveToNext()) {
    103                     Entry entry = new Entry();
    104                     entry.type = TYPE_SINGLE_PHOTO;
    105                     entry.widgetId = cursor.getInt(0);
    106                     entry.imageData = cursor.getBlob(1);
    107                     data.add(entry);
    108                 }
    109             } finally {
    110                 cursor.close();
    111             }
    112         } else if (oldVersion == 3) {
    113             Cursor cursor = db.query("photos",
    114                     new String[] {FIELD_APPWIDGET_ID, FIELD_PHOTO_BLOB, FIELD_IMAGE_URI},
    115                     null, null, null, null, null);
    116             if (cursor == null) return;
    117             try {
    118                 while (cursor.moveToNext()) {
    119                     Entry entry = new Entry();
    120                     entry.type = TYPE_SINGLE_PHOTO;
    121                     entry.widgetId = cursor.getInt(0);
    122                     entry.imageData = cursor.getBlob(1);
    123                     entry.imageUri = cursor.getString(2);
    124                     data.add(entry);
    125                 }
    126             } finally {
    127                 cursor.close();
    128             }
    129         }
    130     }
    131 
    132     private void restoreData(SQLiteDatabase db, ArrayList<Entry> data) {
    133         db.beginTransaction();
    134         try {
    135             for (Entry entry : data) {
    136                 ContentValues values = new ContentValues();
    137                 values.put(FIELD_APPWIDGET_ID, entry.widgetId);
    138                 values.put(FIELD_WIDGET_TYPE, entry.type);
    139                 values.put(FIELD_IMAGE_URI, entry.imageUri);
    140                 values.put(FIELD_PHOTO_BLOB, entry.imageData);
    141                 values.put(FIELD_ALBUM_PATH, entry.albumPath);
    142                 db.insert(TABLE_WIDGETS, null, values);
    143             }
    144             db.setTransactionSuccessful();
    145         } finally {
    146             db.endTransaction();
    147         }
    148     }
    149 
    150     @Override
    151     public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    152         int version = oldVersion;
    153 
    154         if (version != DATABASE_VERSION) {
    155             ArrayList<Entry> data = new ArrayList<Entry>();
    156             saveData(db, oldVersion, data);
    157 
    158             Log.w(TAG, "destroying all old data.");
    159             // Table "photos" is renamed to "widget" in version 4
    160             db.execSQL("DROP TABLE IF EXISTS photos");
    161             db.execSQL("DROP TABLE IF EXISTS " + TABLE_WIDGETS);
    162             onCreate(db);
    163 
    164             restoreData(db, data);
    165         }
    166     }
    167 
    168     /**
    169      * Store the given bitmap in this database for the given appWidgetId.
    170      */
    171     public boolean setPhoto(int appWidgetId, Uri imageUri, Bitmap bitmap) {
    172         try {
    173             // Try go guesstimate how much space the icon will take when
    174             // serialized to avoid unnecessary allocations/copies during
    175             // the write.
    176             int size = bitmap.getWidth() * bitmap.getHeight() * 4;
    177             ByteArrayOutputStream out = new ByteArrayOutputStream(size);
    178             bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
    179             out.close();
    180 
    181             ContentValues values = new ContentValues();
    182             values.put(FIELD_APPWIDGET_ID, appWidgetId);
    183             values.put(FIELD_WIDGET_TYPE, TYPE_SINGLE_PHOTO);
    184             values.put(FIELD_IMAGE_URI, imageUri.toString());
    185             values.put(FIELD_PHOTO_BLOB, out.toByteArray());
    186 
    187             SQLiteDatabase db = getWritableDatabase();
    188             db.replaceOrThrow(TABLE_WIDGETS, null, values);
    189             return true;
    190         } catch (Throwable e) {
    191             Log.e(TAG, "set widget photo fail", e);
    192             return false;
    193         }
    194     }
    195 
    196     public boolean setWidget(int id, int type, String albumPath) {
    197         try {
    198             ContentValues values = new ContentValues();
    199             values.put(FIELD_APPWIDGET_ID, id);
    200             values.put(FIELD_WIDGET_TYPE, type);
    201             values.put(FIELD_ALBUM_PATH, Utils.ensureNotNull(albumPath));
    202             getWritableDatabase().replaceOrThrow(TABLE_WIDGETS, null, values);
    203             return true;
    204         } catch (Throwable e) {
    205             Log.e(TAG, "set widget fail", e);
    206             return false;
    207         }
    208     }
    209 
    210     public Entry getEntry(int appWidgetId) {
    211         Cursor cursor = null;
    212         try {
    213             SQLiteDatabase db = getReadableDatabase();
    214             cursor = db.query(TABLE_WIDGETS, PROJECTION,
    215                     WHERE_CLAUSE, new String[] {String.valueOf(appWidgetId)},
    216                     null, null, null);
    217             if (cursor == null || !cursor.moveToNext()) {
    218                 Log.e(TAG, "query fail: empty cursor: " + cursor);
    219                 return null;
    220             }
    221             return new Entry(appWidgetId, cursor);
    222         } catch (Throwable e) {
    223             Log.e(TAG, "Could not load photo from database", e);
    224             return null;
    225         } finally {
    226             Utils.closeSilently(cursor);
    227         }
    228     }
    229 
    230     /**
    231      * Remove any bitmap associated with the given appWidgetId.
    232      */
    233     public void deleteEntry(int appWidgetId) {
    234         try {
    235             SQLiteDatabase db = getWritableDatabase();
    236             db.delete(TABLE_WIDGETS, WHERE_CLAUSE,
    237                     new String[] {String.valueOf(appWidgetId)});
    238         } catch (SQLiteException e) {
    239             Log.e(TAG, "Could not delete photo from database", e);
    240         }
    241     }
    242 }