1 /*
2  * Copyright (C) 2013 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.wallpaperpicker;
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.SQLiteOpenHelper;
24 import android.graphics.Bitmap;
25 import android.graphics.BitmapFactory;
26 import android.graphics.drawable.BitmapDrawable;
27 import android.graphics.drawable.Drawable;
28 import android.util.Log;
29 
30 import com.android.wallpaperpicker.tileinfo.FileWallpaperInfo;
31 
32 import java.io.File;
33 import java.io.FileOutputStream;
34 import java.io.IOException;
35 import java.util.ArrayList;
36 import java.util.List;
37 
38 public class SavedWallpaperImages {
39 
40     private static String TAG = "SavedWallpaperImages";
41 
42     public static class SavedWallpaperInfo extends FileWallpaperInfo {
43 
44         private int mDbId;
45 
SavedWallpaperInfo(int dbId, File target, Drawable thumb)46         public SavedWallpaperInfo(int dbId, File target, Drawable thumb) {
47             super(target, thumb);
48             mDbId = dbId;
49         }
50 
51         @Override
onDelete(WallpaperPickerActivity a)52         public void onDelete(WallpaperPickerActivity a) {
53             a.getSavedImages().deleteImage(mDbId);
54         }
55     }
56 
57     private final ImageDb mDb;
58     private final Context mContext;
59 
SavedWallpaperImages(Context context)60     public SavedWallpaperImages(Context context) {
61         // We used to store the saved images in the cache directory, but that meant they'd get
62         // deleted sometimes-- move them to the data directory
63         ImageDb.moveFromCacheDirectoryIfNecessary(context);
64         mDb = new ImageDb(context);
65         mContext = context;
66     }
67 
loadThumbnailsAndImageIdList()68     public List<SavedWallpaperInfo> loadThumbnailsAndImageIdList() {
69         List<SavedWallpaperInfo> result = new ArrayList<SavedWallpaperInfo>();
70 
71         SQLiteDatabase db = mDb.getReadableDatabase();
72         Cursor c = db.query(ImageDb.TABLE_NAME,
73                 new String[] { ImageDb.COLUMN_ID,
74                     ImageDb.COLUMN_IMAGE_THUMBNAIL_FILENAME,
75                     ImageDb.COLUMN_IMAGE_FILENAME}, // cols to return
76                 null, // select query
77                 null, // args to select query
78                 null,
79                 null,
80                 ImageDb.COLUMN_ID + " DESC",
81                 null);
82 
83         while (c.moveToNext()) {
84             String filename = c.getString(1);
85             File file = new File(mContext.getFilesDir(), filename);
86 
87             Bitmap thumb = BitmapFactory.decodeFile(file.getAbsolutePath());
88             if (thumb != null) {
89                 result.add(new SavedWallpaperInfo(c.getInt(0),
90                         new File(mContext.getFilesDir(), c.getString(2)),
91                         new BitmapDrawable(mContext.getResources(), thumb)));
92             }
93         }
94         c.close();
95         return result;
96     }
97 
deleteImage(int id)98     public void deleteImage(int id) {
99         SQLiteDatabase db = mDb.getWritableDatabase();
100 
101         Cursor result = db.query(ImageDb.TABLE_NAME,
102                 new String[] { ImageDb.COLUMN_IMAGE_THUMBNAIL_FILENAME,
103                     ImageDb.COLUMN_IMAGE_FILENAME }, // cols to return
104                 ImageDb.COLUMN_ID + " = ?", // select query
105                 new String[] { Integer.toString(id) }, // args to select query
106                 null,
107                 null,
108                 null,
109                 null);
110         if (result.moveToFirst()) {
111             new File(mContext.getFilesDir(), result.getString(0)).delete();
112             new File(mContext.getFilesDir(), result.getString(1)).delete();
113         }
114         result.close();
115 
116         db.delete(ImageDb.TABLE_NAME,
117                 ImageDb.COLUMN_ID + " = ?", // SELECT query
118                 new String[] {
119                     Integer.toString(id) // args to SELECT query
120                 });
121     }
122 
writeImage(Bitmap thumbnail, byte[] imageBytes)123     public void writeImage(Bitmap thumbnail, byte[] imageBytes) {
124         try {
125             File imageFile = File.createTempFile("wallpaper", "", mContext.getFilesDir());
126             FileOutputStream imageFileStream =
127                     mContext.openFileOutput(imageFile.getName(), Context.MODE_PRIVATE);
128             imageFileStream.write(imageBytes);
129             imageFileStream.close();
130 
131             File thumbFile = File.createTempFile("wallpaperthumb", "", mContext.getFilesDir());
132             FileOutputStream thumbFileStream =
133                     mContext.openFileOutput(thumbFile.getName(), Context.MODE_PRIVATE);
134             thumbnail.compress(Bitmap.CompressFormat.JPEG, 95, thumbFileStream);
135             thumbFileStream.close();
136 
137             SQLiteDatabase db = mDb.getWritableDatabase();
138             ContentValues values = new ContentValues();
139             values.put(ImageDb.COLUMN_IMAGE_THUMBNAIL_FILENAME, thumbFile.getName());
140             values.put(ImageDb.COLUMN_IMAGE_FILENAME, imageFile.getName());
141             db.insert(ImageDb.TABLE_NAME, null, values);
142         } catch (IOException e) {
143             Log.e(TAG, "Failed writing images to storage " + e);
144         }
145     }
146 
147     private static class ImageDb extends SQLiteOpenHelper {
148         final static int DB_VERSION = 1;
149         final static String TABLE_NAME = "saved_wallpaper_images";
150         final static String COLUMN_ID = "id";
151         final static String COLUMN_IMAGE_THUMBNAIL_FILENAME = "image_thumbnail";
152         final static String COLUMN_IMAGE_FILENAME = "image";
153 
ImageDb(Context context)154         public ImageDb(Context context) {
155             super(context, context.getDatabasePath(WallpaperFiles.WALLPAPER_IMAGES_DB).getPath(),
156                     null, DB_VERSION);
157         }
158 
moveFromCacheDirectoryIfNecessary(Context context)159         public static void moveFromCacheDirectoryIfNecessary(Context context) {
160             // We used to store the saved images in the cache directory, but that meant they'd get
161             // deleted sometimes-- move them to the data directory
162             File oldSavedImagesFile = new File(context.getCacheDir(),
163                   WallpaperFiles.WALLPAPER_IMAGES_DB);
164             File savedImagesFile = context.getDatabasePath(WallpaperFiles.WALLPAPER_IMAGES_DB);
165             if (oldSavedImagesFile.exists()) {
166                 oldSavedImagesFile.renameTo(savedImagesFile);
167             }
168         }
169         @Override
onCreate(SQLiteDatabase database)170         public void onCreate(SQLiteDatabase database) {
171             database.execSQL("CREATE TABLE IF NOT EXISTS " + TABLE_NAME + " (" +
172                     COLUMN_ID + " INTEGER NOT NULL, " +
173                     COLUMN_IMAGE_THUMBNAIL_FILENAME + " TEXT NOT NULL, " +
174                     COLUMN_IMAGE_FILENAME + " TEXT NOT NULL, " +
175                     "PRIMARY KEY (" + COLUMN_ID + " ASC) " +
176                     ");");
177         }
178 
179         @Override
onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)180         public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
181             if (oldVersion != newVersion) {
182                 // Delete all the records; they'll be repopulated as this is a cache
183                 db.execSQL("DELETE FROM " + TABLE_NAME);
184             }
185         }
186     }
187 }
188