• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
Entry()71         private Entry() {}
72 
Entry(int id, Cursor cursor)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 
Entry(Cursor cursor)84         private Entry(Cursor cursor) {
85             this(cursor.getInt(INDEX_APPWIDGET_ID), cursor);
86         }
87     }
88 
WidgetDatabaseHelper(Context context)89     public WidgetDatabaseHelper(Context context) {
90         super(context, DATABASE_NAME, null, DATABASE_VERSION);
91     }
92 
93     @Override
onCreate(SQLiteDatabase db)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 
saveData(SQLiteDatabase db, int oldVersion, ArrayList<Entry> data)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 
restoreData(SQLiteDatabase db, ArrayList<Entry> data)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
onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)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      */
setPhoto(int appWidgetId, Uri imageUri, Bitmap bitmap)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 
setWidget(int id, int type, String albumPath)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 
getEntry(int appWidgetId)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 
getEntries(int type)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      */
updateEntry(Entry entry)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      */
deleteEntry(int appWidgetId)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