1f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin/*
2f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * Copyright (C) 2010 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.content.ContentValues;
20f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.content.Context;
21f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.database.Cursor;
22f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.database.sqlite.SQLiteDatabase;
23f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.database.sqlite.SQLiteException;
24f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.database.sqlite.SQLiteOpenHelper;
25f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.graphics.Bitmap;
26f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.net.Uri;
27f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.util.Log;
28f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
292b3ee0ea07246b859a5b75d8a6102a7cce7ec838Owen Linimport com.android.gallery3d.common.Utils;
302b3ee0ea07246b859a5b75d8a6102a7cce7ec838Owen Lin
31f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport java.io.ByteArrayOutputStream;
32d6db8eab6df048b9065834113a6d46a885af01d3Owen Linimport java.util.ArrayList;
3340234dd934d0dac0a65c896d9d287d58bc10b198Hung-ying Tyanimport java.util.List;
34f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
35f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linpublic class WidgetDatabaseHelper extends SQLiteOpenHelper {
36f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private static final String TAG = "PhotoDatabaseHelper";
37f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private static final String DATABASE_NAME = "launcher.db";
38f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
39fcf54601d45bfcef2fbeb911c46ff394e84d7011Doris Liu    // Increment the database version to 5. In version 5, we
40fcf54601d45bfcef2fbeb911c46ff394e84d7011Doris Liu    // add a column in widgets table to record relative paths.
41fcf54601d45bfcef2fbeb911c46ff394e84d7011Doris Liu    private static final int DATABASE_VERSION = 5;
42f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
43f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private static final String TABLE_WIDGETS = "widgets";
44f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
45f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private static final String FIELD_APPWIDGET_ID = "appWidgetId";
46f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private static final String FIELD_IMAGE_URI = "imageUri";
47f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private static final String FIELD_PHOTO_BLOB = "photoBlob";
48f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private static final String FIELD_WIDGET_TYPE = "widgetType";
49f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private static final String FIELD_ALBUM_PATH = "albumPath";
50fcf54601d45bfcef2fbeb911c46ff394e84d7011Doris Liu    private static final String FIELD_RELATIVE_PATH = "relativePath";
51f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
52f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public static final int TYPE_SINGLE_PHOTO = 0;
53f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public static final int TYPE_SHUFFLE = 1;
54f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public static final int TYPE_ALBUM = 2;
55f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
56f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private static final String[] PROJECTION = {
5740234dd934d0dac0a65c896d9d287d58bc10b198Hung-ying Tyan            FIELD_WIDGET_TYPE, FIELD_IMAGE_URI, FIELD_PHOTO_BLOB, FIELD_ALBUM_PATH,
58fcf54601d45bfcef2fbeb911c46ff394e84d7011Doris Liu            FIELD_APPWIDGET_ID, FIELD_RELATIVE_PATH};
59f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private static final int INDEX_WIDGET_TYPE = 0;
60f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private static final int INDEX_IMAGE_URI = 1;
61f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private static final int INDEX_PHOTO_BLOB = 2;
62f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private static final int INDEX_ALBUM_PATH = 3;
6340234dd934d0dac0a65c896d9d287d58bc10b198Hung-ying Tyan    private static final int INDEX_APPWIDGET_ID = 4;
64fcf54601d45bfcef2fbeb911c46ff394e84d7011Doris Liu    private static final int INDEX_RELATIVE_PATH = 5;
6540234dd934d0dac0a65c896d9d287d58bc10b198Hung-ying Tyan    private static final String WHERE_APPWIDGET_ID = FIELD_APPWIDGET_ID + " = ?";
6640234dd934d0dac0a65c896d9d287d58bc10b198Hung-ying Tyan    private static final String WHERE_WIDGET_TYPE = FIELD_WIDGET_TYPE + " = ?";
67f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
68f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public static class Entry {
69f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        public int widgetId;
70f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        public int type;
71d6db8eab6df048b9065834113a6d46a885af01d3Owen Lin        public String imageUri;
72d6db8eab6df048b9065834113a6d46a885af01d3Owen Lin        public byte imageData[];
73f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        public String albumPath;
74fcf54601d45bfcef2fbeb911c46ff394e84d7011Doris Liu        public String relativePath;
75f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
76d6db8eab6df048b9065834113a6d46a885af01d3Owen Lin        private Entry() {}
77d6db8eab6df048b9065834113a6d46a885af01d3Owen Lin
78f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        private Entry(int id, Cursor cursor) {
79f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            widgetId = id;
80f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            type = cursor.getInt(INDEX_WIDGET_TYPE);
81f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            if (type == TYPE_SINGLE_PHOTO) {
82d6db8eab6df048b9065834113a6d46a885af01d3Owen Lin                imageUri = cursor.getString(INDEX_IMAGE_URI);
83d6db8eab6df048b9065834113a6d46a885af01d3Owen Lin                imageData = cursor.getBlob(INDEX_PHOTO_BLOB);
84f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            } else if (type == TYPE_ALBUM) {
85f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                albumPath = cursor.getString(INDEX_ALBUM_PATH);
86fcf54601d45bfcef2fbeb911c46ff394e84d7011Doris Liu                relativePath = cursor.getString(INDEX_RELATIVE_PATH);
87f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            }
88f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
8940234dd934d0dac0a65c896d9d287d58bc10b198Hung-ying Tyan
9040234dd934d0dac0a65c896d9d287d58bc10b198Hung-ying Tyan        private Entry(Cursor cursor) {
9140234dd934d0dac0a65c896d9d287d58bc10b198Hung-ying Tyan            this(cursor.getInt(INDEX_APPWIDGET_ID), cursor);
9240234dd934d0dac0a65c896d9d287d58bc10b198Hung-ying Tyan        }
93f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
94f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
95f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public WidgetDatabaseHelper(Context context) {
96f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        super(context, DATABASE_NAME, null, DATABASE_VERSION);
97f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
98f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
99f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    @Override
100f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public void onCreate(SQLiteDatabase db) {
101f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        db.execSQL("CREATE TABLE " + TABLE_WIDGETS + " ("
102f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                + FIELD_APPWIDGET_ID + " INTEGER PRIMARY KEY, "
103f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                + FIELD_WIDGET_TYPE + " INTEGER DEFAULT 0, "
104f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                + FIELD_IMAGE_URI + " TEXT, "
105f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                + FIELD_ALBUM_PATH + " TEXT, "
106fcf54601d45bfcef2fbeb911c46ff394e84d7011Doris Liu                + FIELD_PHOTO_BLOB + " BLOB, "
107fcf54601d45bfcef2fbeb911c46ff394e84d7011Doris Liu                + FIELD_RELATIVE_PATH + " TEXT)");
108f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
109f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
110d6db8eab6df048b9065834113a6d46a885af01d3Owen Lin    private void saveData(SQLiteDatabase db, int oldVersion, ArrayList<Entry> data) {
111d6db8eab6df048b9065834113a6d46a885af01d3Owen Lin        if (oldVersion <= 2) {
112d6db8eab6df048b9065834113a6d46a885af01d3Owen Lin            Cursor cursor = db.query("photos",
113d6db8eab6df048b9065834113a6d46a885af01d3Owen Lin                    new String[] {FIELD_APPWIDGET_ID, FIELD_PHOTO_BLOB},
114d6db8eab6df048b9065834113a6d46a885af01d3Owen Lin                    null, null, null, null, null);
115d6db8eab6df048b9065834113a6d46a885af01d3Owen Lin            if (cursor == null) return;
116d6db8eab6df048b9065834113a6d46a885af01d3Owen Lin            try {
117d6db8eab6df048b9065834113a6d46a885af01d3Owen Lin                while (cursor.moveToNext()) {
118d6db8eab6df048b9065834113a6d46a885af01d3Owen Lin                    Entry entry = new Entry();
119d6db8eab6df048b9065834113a6d46a885af01d3Owen Lin                    entry.type = TYPE_SINGLE_PHOTO;
120d6db8eab6df048b9065834113a6d46a885af01d3Owen Lin                    entry.widgetId = cursor.getInt(0);
121d6db8eab6df048b9065834113a6d46a885af01d3Owen Lin                    entry.imageData = cursor.getBlob(1);
122d6db8eab6df048b9065834113a6d46a885af01d3Owen Lin                    data.add(entry);
123d6db8eab6df048b9065834113a6d46a885af01d3Owen Lin                }
124d6db8eab6df048b9065834113a6d46a885af01d3Owen Lin            } finally {
125d6db8eab6df048b9065834113a6d46a885af01d3Owen Lin                cursor.close();
126d6db8eab6df048b9065834113a6d46a885af01d3Owen Lin            }
127d6db8eab6df048b9065834113a6d46a885af01d3Owen Lin        } else if (oldVersion == 3) {
128d6db8eab6df048b9065834113a6d46a885af01d3Owen Lin            Cursor cursor = db.query("photos",
129d6db8eab6df048b9065834113a6d46a885af01d3Owen Lin                    new String[] {FIELD_APPWIDGET_ID, FIELD_PHOTO_BLOB, FIELD_IMAGE_URI},
130d6db8eab6df048b9065834113a6d46a885af01d3Owen Lin                    null, null, null, null, null);
131d6db8eab6df048b9065834113a6d46a885af01d3Owen Lin            if (cursor == null) return;
132d6db8eab6df048b9065834113a6d46a885af01d3Owen Lin            try {
133d6db8eab6df048b9065834113a6d46a885af01d3Owen Lin                while (cursor.moveToNext()) {
134d6db8eab6df048b9065834113a6d46a885af01d3Owen Lin                    Entry entry = new Entry();
135d6db8eab6df048b9065834113a6d46a885af01d3Owen Lin                    entry.type = TYPE_SINGLE_PHOTO;
136d6db8eab6df048b9065834113a6d46a885af01d3Owen Lin                    entry.widgetId = cursor.getInt(0);
137d6db8eab6df048b9065834113a6d46a885af01d3Owen Lin                    entry.imageData = cursor.getBlob(1);
138d6db8eab6df048b9065834113a6d46a885af01d3Owen Lin                    entry.imageUri = cursor.getString(2);
139d6db8eab6df048b9065834113a6d46a885af01d3Owen Lin                    data.add(entry);
140d6db8eab6df048b9065834113a6d46a885af01d3Owen Lin                }
141d6db8eab6df048b9065834113a6d46a885af01d3Owen Lin            } finally {
142d6db8eab6df048b9065834113a6d46a885af01d3Owen Lin                cursor.close();
143d6db8eab6df048b9065834113a6d46a885af01d3Owen Lin            }
144d6db8eab6df048b9065834113a6d46a885af01d3Owen Lin        }
145d6db8eab6df048b9065834113a6d46a885af01d3Owen Lin    }
146d6db8eab6df048b9065834113a6d46a885af01d3Owen Lin
147d6db8eab6df048b9065834113a6d46a885af01d3Owen Lin    private void restoreData(SQLiteDatabase db, ArrayList<Entry> data) {
148d6db8eab6df048b9065834113a6d46a885af01d3Owen Lin        db.beginTransaction();
149d6db8eab6df048b9065834113a6d46a885af01d3Owen Lin        try {
150d6db8eab6df048b9065834113a6d46a885af01d3Owen Lin            for (Entry entry : data) {
151d6db8eab6df048b9065834113a6d46a885af01d3Owen Lin                ContentValues values = new ContentValues();
152d6db8eab6df048b9065834113a6d46a885af01d3Owen Lin                values.put(FIELD_APPWIDGET_ID, entry.widgetId);
153d6db8eab6df048b9065834113a6d46a885af01d3Owen Lin                values.put(FIELD_WIDGET_TYPE, entry.type);
154d6db8eab6df048b9065834113a6d46a885af01d3Owen Lin                values.put(FIELD_IMAGE_URI, entry.imageUri);
155d6db8eab6df048b9065834113a6d46a885af01d3Owen Lin                values.put(FIELD_PHOTO_BLOB, entry.imageData);
156d6db8eab6df048b9065834113a6d46a885af01d3Owen Lin                values.put(FIELD_ALBUM_PATH, entry.albumPath);
157d6db8eab6df048b9065834113a6d46a885af01d3Owen Lin                db.insert(TABLE_WIDGETS, null, values);
158d6db8eab6df048b9065834113a6d46a885af01d3Owen Lin            }
159d6db8eab6df048b9065834113a6d46a885af01d3Owen Lin            db.setTransactionSuccessful();
160d6db8eab6df048b9065834113a6d46a885af01d3Owen Lin        } finally {
161d6db8eab6df048b9065834113a6d46a885af01d3Owen Lin            db.endTransaction();
162d6db8eab6df048b9065834113a6d46a885af01d3Owen Lin        }
163d6db8eab6df048b9065834113a6d46a885af01d3Owen Lin    }
164d6db8eab6df048b9065834113a6d46a885af01d3Owen Lin
165f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    @Override
166f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
167fcf54601d45bfcef2fbeb911c46ff394e84d7011Doris Liu        if (oldVersion < 4) {
168fcf54601d45bfcef2fbeb911c46ff394e84d7011Doris Liu            // Table "photos" is renamed to "widget" in version 4
169d6db8eab6df048b9065834113a6d46a885af01d3Owen Lin            ArrayList<Entry> data = new ArrayList<Entry>();
170d6db8eab6df048b9065834113a6d46a885af01d3Owen Lin            saveData(db, oldVersion, data);
171d6db8eab6df048b9065834113a6d46a885af01d3Owen Lin
172f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            Log.w(TAG, "destroying all old data.");
173f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            db.execSQL("DROP TABLE IF EXISTS photos");
174f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            db.execSQL("DROP TABLE IF EXISTS " + TABLE_WIDGETS);
175f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            onCreate(db);
176d6db8eab6df048b9065834113a6d46a885af01d3Owen Lin
177d6db8eab6df048b9065834113a6d46a885af01d3Owen Lin            restoreData(db, data);
178f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
179fcf54601d45bfcef2fbeb911c46ff394e84d7011Doris Liu        // Add a column for relative path
180fcf54601d45bfcef2fbeb911c46ff394e84d7011Doris Liu        if (oldVersion < DATABASE_VERSION) {
181fcf54601d45bfcef2fbeb911c46ff394e84d7011Doris Liu            try {
182fcf54601d45bfcef2fbeb911c46ff394e84d7011Doris Liu                db.execSQL("ALTER TABLE widgets ADD COLUMN relativePath TEXT");
183fcf54601d45bfcef2fbeb911c46ff394e84d7011Doris Liu            } catch (Throwable t) {
184fcf54601d45bfcef2fbeb911c46ff394e84d7011Doris Liu                Log.e(TAG, "Failed to add the column for relative path.");
185fcf54601d45bfcef2fbeb911c46ff394e84d7011Doris Liu                return;
186fcf54601d45bfcef2fbeb911c46ff394e84d7011Doris Liu            }
187fcf54601d45bfcef2fbeb911c46ff394e84d7011Doris Liu        }
188f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
189f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
190f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    /**
191f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin     * Store the given bitmap in this database for the given appWidgetId.
192f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin     */
193f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public boolean setPhoto(int appWidgetId, Uri imageUri, Bitmap bitmap) {
194f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        try {
195f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            // Try go guesstimate how much space the icon will take when
196f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            // serialized to avoid unnecessary allocations/copies during
197f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            // the write.
198f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            int size = bitmap.getWidth() * bitmap.getHeight() * 4;
199f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            ByteArrayOutputStream out = new ByteArrayOutputStream(size);
200f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
201f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            out.close();
202f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
203f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            ContentValues values = new ContentValues();
204f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            values.put(FIELD_APPWIDGET_ID, appWidgetId);
205f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            values.put(FIELD_WIDGET_TYPE, TYPE_SINGLE_PHOTO);
206f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            values.put(FIELD_IMAGE_URI, imageUri.toString());
207f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            values.put(FIELD_PHOTO_BLOB, out.toByteArray());
208f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
209f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            SQLiteDatabase db = getWritableDatabase();
210f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            db.replaceOrThrow(TABLE_WIDGETS, null, values);
211f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            return true;
212f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        } catch (Throwable e) {
213f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            Log.e(TAG, "set widget photo fail", e);
214f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            return false;
215f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
216f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
217f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
218fcf54601d45bfcef2fbeb911c46ff394e84d7011Doris Liu    public boolean setWidget(int id, int type, String albumPath, String relativePath) {
219f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        try {
220f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            ContentValues values = new ContentValues();
221f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            values.put(FIELD_APPWIDGET_ID, id);
222f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            values.put(FIELD_WIDGET_TYPE, type);
223f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            values.put(FIELD_ALBUM_PATH, Utils.ensureNotNull(albumPath));
224fcf54601d45bfcef2fbeb911c46ff394e84d7011Doris Liu            values.put(FIELD_RELATIVE_PATH, relativePath);
225f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            getWritableDatabase().replaceOrThrow(TABLE_WIDGETS, null, values);
226f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            return true;
227f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        } catch (Throwable e) {
228f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            Log.e(TAG, "set widget fail", e);
229f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            return false;
230f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
231f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
232f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
233f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public Entry getEntry(int appWidgetId) {
234f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        Cursor cursor = null;
235f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        try {
236f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            SQLiteDatabase db = getReadableDatabase();
237f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            cursor = db.query(TABLE_WIDGETS, PROJECTION,
23840234dd934d0dac0a65c896d9d287d58bc10b198Hung-ying Tyan                    WHERE_APPWIDGET_ID, new String[] {String.valueOf(appWidgetId)},
239f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                    null, null, null);
240f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            if (cursor == null || !cursor.moveToNext()) {
241fcf54601d45bfcef2fbeb911c46ff394e84d7011Doris Liu                Log.e(TAG, "query fail: empty cursor: " + cursor + " appWidgetId: "
242fcf54601d45bfcef2fbeb911c46ff394e84d7011Doris Liu                        + appWidgetId);
243f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                return null;
244f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            }
245f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            return new Entry(appWidgetId, cursor);
246f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        } catch (Throwable e) {
247f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            Log.e(TAG, "Could not load photo from database", e);
248f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            return null;
249f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        } finally {
250f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            Utils.closeSilently(cursor);
251f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
252f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
253f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
25440234dd934d0dac0a65c896d9d287d58bc10b198Hung-ying Tyan    public List<Entry> getEntries(int type) {
25540234dd934d0dac0a65c896d9d287d58bc10b198Hung-ying Tyan        Cursor cursor = null;
25640234dd934d0dac0a65c896d9d287d58bc10b198Hung-ying Tyan        try {
25740234dd934d0dac0a65c896d9d287d58bc10b198Hung-ying Tyan            SQLiteDatabase db = getReadableDatabase();
25840234dd934d0dac0a65c896d9d287d58bc10b198Hung-ying Tyan            cursor = db.query(TABLE_WIDGETS, PROJECTION,
25940234dd934d0dac0a65c896d9d287d58bc10b198Hung-ying Tyan                    WHERE_WIDGET_TYPE, new String[] {String.valueOf(type)},
26040234dd934d0dac0a65c896d9d287d58bc10b198Hung-ying Tyan                    null, null, null);
26140234dd934d0dac0a65c896d9d287d58bc10b198Hung-ying Tyan            if (cursor == null) {
26240234dd934d0dac0a65c896d9d287d58bc10b198Hung-ying Tyan                Log.e(TAG, "query fail: null cursor: " + cursor);
26340234dd934d0dac0a65c896d9d287d58bc10b198Hung-ying Tyan                return null;
26440234dd934d0dac0a65c896d9d287d58bc10b198Hung-ying Tyan            }
26540234dd934d0dac0a65c896d9d287d58bc10b198Hung-ying Tyan            ArrayList<Entry> result = new ArrayList<Entry>(cursor.getCount());
26640234dd934d0dac0a65c896d9d287d58bc10b198Hung-ying Tyan            while (cursor.moveToNext()) {
26740234dd934d0dac0a65c896d9d287d58bc10b198Hung-ying Tyan                result.add(new Entry(cursor));
26840234dd934d0dac0a65c896d9d287d58bc10b198Hung-ying Tyan            }
26940234dd934d0dac0a65c896d9d287d58bc10b198Hung-ying Tyan            return result;
27040234dd934d0dac0a65c896d9d287d58bc10b198Hung-ying Tyan        } catch (Throwable e) {
27140234dd934d0dac0a65c896d9d287d58bc10b198Hung-ying Tyan            Log.e(TAG, "Could not load widget from database", e);
27240234dd934d0dac0a65c896d9d287d58bc10b198Hung-ying Tyan            return null;
27340234dd934d0dac0a65c896d9d287d58bc10b198Hung-ying Tyan        } finally {
27440234dd934d0dac0a65c896d9d287d58bc10b198Hung-ying Tyan            Utils.closeSilently(cursor);
27540234dd934d0dac0a65c896d9d287d58bc10b198Hung-ying Tyan        }
27640234dd934d0dac0a65c896d9d287d58bc10b198Hung-ying Tyan    }
27740234dd934d0dac0a65c896d9d287d58bc10b198Hung-ying Tyan
27840234dd934d0dac0a65c896d9d287d58bc10b198Hung-ying Tyan    /**
27940234dd934d0dac0a65c896d9d287d58bc10b198Hung-ying Tyan     * Updates the entry in the widget database.
28040234dd934d0dac0a65c896d9d287d58bc10b198Hung-ying Tyan     */
28140234dd934d0dac0a65c896d9d287d58bc10b198Hung-ying Tyan    public void updateEntry(Entry entry) {
28240234dd934d0dac0a65c896d9d287d58bc10b198Hung-ying Tyan        deleteEntry(entry.widgetId);
28340234dd934d0dac0a65c896d9d287d58bc10b198Hung-ying Tyan        try {
28440234dd934d0dac0a65c896d9d287d58bc10b198Hung-ying Tyan            ContentValues values = new ContentValues();
28540234dd934d0dac0a65c896d9d287d58bc10b198Hung-ying Tyan            values.put(FIELD_APPWIDGET_ID, entry.widgetId);
28640234dd934d0dac0a65c896d9d287d58bc10b198Hung-ying Tyan            values.put(FIELD_WIDGET_TYPE, entry.type);
28740234dd934d0dac0a65c896d9d287d58bc10b198Hung-ying Tyan            values.put(FIELD_ALBUM_PATH, entry.albumPath);
28840234dd934d0dac0a65c896d9d287d58bc10b198Hung-ying Tyan            values.put(FIELD_IMAGE_URI, entry.imageUri);
28940234dd934d0dac0a65c896d9d287d58bc10b198Hung-ying Tyan            values.put(FIELD_PHOTO_BLOB, entry.imageData);
290fcf54601d45bfcef2fbeb911c46ff394e84d7011Doris Liu            values.put(FIELD_RELATIVE_PATH, entry.relativePath);
29140234dd934d0dac0a65c896d9d287d58bc10b198Hung-ying Tyan            getWritableDatabase().insert(TABLE_WIDGETS, null, values);
29240234dd934d0dac0a65c896d9d287d58bc10b198Hung-ying Tyan        } catch (Throwable e) {
29340234dd934d0dac0a65c896d9d287d58bc10b198Hung-ying Tyan            Log.e(TAG, "set widget fail", e);
29440234dd934d0dac0a65c896d9d287d58bc10b198Hung-ying Tyan        }
29540234dd934d0dac0a65c896d9d287d58bc10b198Hung-ying Tyan    }
29640234dd934d0dac0a65c896d9d287d58bc10b198Hung-ying Tyan
297f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    /**
298f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin     * Remove any bitmap associated with the given appWidgetId.
299f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin     */
300f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public void deleteEntry(int appWidgetId) {
301f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        try {
302f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            SQLiteDatabase db = getWritableDatabase();
30340234dd934d0dac0a65c896d9d287d58bc10b198Hung-ying Tyan            db.delete(TABLE_WIDGETS, WHERE_APPWIDGET_ID,
304f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                    new String[] {String.valueOf(appWidgetId)});
305f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        } catch (SQLiteException e) {
306f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            Log.e(TAG, "Could not delete photo from database", e);
307f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
308f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
30940234dd934d0dac0a65c896d9d287d58bc10b198Hung-ying Tyan}
310