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