1 /* 2 * Copyright (C) 2009 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 android.content; 18 19 import android.database.Cursor; 20 import android.database.DatabaseUtils; 21 import android.database.sqlite.SQLiteDatabase; 22 import android.database.sqlite.SQLiteOpenHelper; 23 import android.net.Uri; 24 import android.os.ParcelFileDescriptor; 25 import android.util.Log; 26 27 import java.io.File; 28 import java.io.FileNotFoundException; 29 import java.io.IOException; 30 import java.io.OutputStream; 31 32 /** Simple test provider that runs in the local process. */ 33 public class MemoryFileProvider extends ContentProvider { 34 private static final String TAG = "MemoryFileProvider"; 35 36 private static final String DATA_FILE = "data.bin"; 37 38 // some random data 39 public static final byte[] TEST_BLOB = new byte[] { 40 -12, 127, 0, 3, 1, 2, 3, 4, 5, 6, 1, -128, -1, -54, -65, 35, 41 -53, -96, -74, -74, -55, -43, -69, 3, 52, -58, 42 -121, 127, 87, -73, 16, -13, -103, -65, -128, -36, 43 107, 24, 118, -17, 97, 97, -88, 19, -94, -54, 44 53, 43, 44, -27, -124, 28, -74, 26, 35, -36, 45 16, -124, -31, -31, -128, -79, 108, 116, 43, -17 }; 46 47 private SQLiteOpenHelper mOpenHelper; 48 49 private static final int DATA_ID_BLOB = 1; 50 private static final int HUGE = 2; 51 private static final int FILE = 3; 52 53 private static final UriMatcher sURLMatcher = new UriMatcher( 54 UriMatcher.NO_MATCH); 55 56 static { 57 sURLMatcher.addURI("*", "data/#/blob", DATA_ID_BLOB); 58 sURLMatcher.addURI("*", "huge", HUGE); 59 sURLMatcher.addURI("*", "file", FILE); 60 } 61 62 private static class DatabaseHelper extends SQLiteOpenHelper { 63 private static final String DATABASE_NAME = "local.db"; 64 private static final int DATABASE_VERSION = 1; 65 DatabaseHelper(Context context)66 public DatabaseHelper(Context context) { 67 super(context, DATABASE_NAME, null, DATABASE_VERSION); 68 } 69 70 @Override onCreate(SQLiteDatabase db)71 public void onCreate(SQLiteDatabase db) { 72 db.execSQL("CREATE TABLE data (" + 73 "_id INTEGER PRIMARY KEY," + 74 "_blob TEXT, " + 75 "integer INTEGER);"); 76 77 // insert alarms 78 ContentValues values = new ContentValues(); 79 values.put("_id", 1); 80 values.put("_blob", TEST_BLOB); 81 values.put("integer", 100); 82 db.insert("data", null, values); 83 } 84 85 @Override onUpgrade(SQLiteDatabase db, int oldVersion, int currentVersion)86 public void onUpgrade(SQLiteDatabase db, int oldVersion, int currentVersion) { 87 Log.w(TAG, "Upgrading test database from version " + 88 oldVersion + " to " + currentVersion + 89 ", which will destroy all old data"); 90 db.execSQL("DROP TABLE IF EXISTS data"); 91 onCreate(db); 92 } 93 } 94 95 MemoryFileProvider()96 public MemoryFileProvider() { 97 } 98 99 @Override onCreate()100 public boolean onCreate() { 101 mOpenHelper = new DatabaseHelper(getContext()); 102 try { 103 OutputStream out = getContext().openFileOutput(DATA_FILE, Context.MODE_PRIVATE); 104 out.write(TEST_BLOB); 105 out.close(); 106 } catch (IOException ex) { 107 ex.printStackTrace(); 108 } 109 return true; 110 } 111 112 @Override query(Uri url, String[] projectionIn, String selection, String[] selectionArgs, String sort)113 public Cursor query(Uri url, String[] projectionIn, String selection, 114 String[] selectionArgs, String sort) { 115 throw new UnsupportedOperationException("query not supported"); 116 } 117 118 @Override getType(Uri url)119 public String getType(Uri url) { 120 int match = sURLMatcher.match(url); 121 switch (match) { 122 case DATA_ID_BLOB: 123 return "application/octet-stream"; 124 case FILE: 125 return "application/octet-stream"; 126 default: 127 throw new IllegalArgumentException("Unknown URL"); 128 } 129 } 130 131 @Override openFile(Uri url, String mode)132 public ParcelFileDescriptor openFile(Uri url, String mode) throws FileNotFoundException { 133 int match = sURLMatcher.match(url); 134 switch (match) { 135 case DATA_ID_BLOB: 136 String sql = "SELECT _blob FROM data WHERE _id=" + url.getPathSegments().get(1); 137 return getBlobColumnAsFile(url, mode, sql); 138 case HUGE: 139 try { 140 return ParcelFileDescriptor.fromData(TEST_BLOB, null); 141 } catch (IOException ex) { 142 throw new FileNotFoundException("Error reading " + url + ":" + ex.toString()); 143 } 144 case FILE: 145 File file = getContext().getFileStreamPath(DATA_FILE); 146 return ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY); 147 default: 148 throw new FileNotFoundException("No files supported by provider at " + url); 149 } 150 } 151 getBlobColumnAsFile(Uri url, String mode, String sql)152 private ParcelFileDescriptor getBlobColumnAsFile(Uri url, String mode, String sql) 153 throws FileNotFoundException { 154 if (!"r".equals(mode)) { 155 throw new FileNotFoundException("Mode " + mode + " not supported for " + url); 156 } 157 158 SQLiteDatabase db = mOpenHelper.getReadableDatabase(); 159 return DatabaseUtils.blobFileDescriptorForQuery(db, sql, null); 160 } 161 162 @Override update(Uri url, ContentValues values, String where, String[] whereArgs)163 public int update(Uri url, ContentValues values, String where, String[] whereArgs) { 164 throw new UnsupportedOperationException("update not supported"); 165 } 166 167 @Override insert(Uri url, ContentValues initialValues)168 public Uri insert(Uri url, ContentValues initialValues) { 169 throw new UnsupportedOperationException("insert not supported"); 170 } 171 172 @Override delete(Uri url, String where, String[] whereArgs)173 public int delete(Uri url, String where, String[] whereArgs) { 174 throw new UnsupportedOperationException("delete not supported"); 175 } 176 } 177