1963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert/*
2963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert * Copyright (C) 2009 The Android Open Source Project
3963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert *
4963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert * Licensed under the Apache License, Version 2.0 (the "License");
5963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert * you may not use this file except in compliance with the License.
6963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert * You may obtain a copy of the License at
7963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert *
8963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert *      http://www.apache.org/licenses/LICENSE-2.0
9963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert *
10963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert * Unless required by applicable law or agreed to in writing, software
11963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert * distributed under the License is distributed on an "AS IS" BASIS,
12963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert * See the License for the specific language governing permissions and
14963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert * limitations under the License.
15963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert */
16963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert
171a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyenpackage android.content;
18963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert
19963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringertimport android.database.Cursor;
20a006b47298539d89dc7a06b54c070cb3e986352aBjorn Bringertimport android.database.DatabaseUtils;
21963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringertimport android.database.sqlite.SQLiteDatabase;
22963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringertimport android.database.sqlite.SQLiteOpenHelper;
23963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringertimport android.net.Uri;
24963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringertimport android.os.ParcelFileDescriptor;
25963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringertimport android.util.Log;
26963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert
27963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringertimport java.io.File;
28963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringertimport java.io.FileNotFoundException;
29963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringertimport java.io.IOException;
30963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringertimport java.io.OutputStream;
31963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert
32963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert/** Simple test provider that runs in the local process. */
33963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringertpublic class MemoryFileProvider extends ContentProvider {
34963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert    private static final String TAG = "MemoryFileProvider";
35963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert
36963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert    private static final String DATA_FILE = "data.bin";
37963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert
38963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert    // some random data
39963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert    public static final byte[] TEST_BLOB = new byte[] {
40963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert        -12,  127, 0, 3, 1, 2, 3, 4, 5, 6, 1, -128, -1, -54, -65, 35,
41963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert        -53, -96, -74, -74, -55, -43, -69, 3, 52, -58,
42963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert        -121, 127, 87, -73, 16, -13, -103, -65, -128, -36,
43963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert        107, 24, 118, -17, 97, 97, -88, 19, -94, -54,
44963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert        53, 43, 44, -27, -124, 28, -74, 26, 35, -36,
45963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert        16, -124, -31, -31, -128, -79, 108, 116, 43, -17 };
46963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert
47963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert    private SQLiteOpenHelper mOpenHelper;
48963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert
49963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert    private static final int DATA_ID_BLOB = 1;
50963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert    private static final int HUGE = 2;
51963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert    private static final int FILE = 3;
52963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert
53963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert    private static final UriMatcher sURLMatcher = new UriMatcher(
54963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert            UriMatcher.NO_MATCH);
55963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert
56963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert    static {
57963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert        sURLMatcher.addURI("*", "data/#/blob", DATA_ID_BLOB);
58963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert        sURLMatcher.addURI("*", "huge", HUGE);
59963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert        sURLMatcher.addURI("*", "file", FILE);
60963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert    }
61963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert
62963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert    private static class DatabaseHelper extends SQLiteOpenHelper {
63963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert        private static final String DATABASE_NAME = "local.db";
64963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert        private static final int DATABASE_VERSION = 1;
65963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert
66963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert        public DatabaseHelper(Context context) {
67963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert            super(context, DATABASE_NAME, null, DATABASE_VERSION);
68963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert        }
69963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert
70963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert        @Override
71963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert        public void onCreate(SQLiteDatabase db) {
72963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert            db.execSQL("CREATE TABLE data (" +
73963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert                       "_id INTEGER PRIMARY KEY," +
74963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert                       "_blob TEXT, " +
75963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert                       "integer INTEGER);");
76963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert
77963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert            // insert alarms
78963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert            ContentValues values = new ContentValues();
79963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert            values.put("_id", 1);
80963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert            values.put("_blob", TEST_BLOB);
81963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert            values.put("integer", 100);
82963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert            db.insert("data", null, values);
83963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert        }
84963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert
85963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert        @Override
86963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert        public void onUpgrade(SQLiteDatabase db, int oldVersion, int currentVersion) {
87963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert            Log.w(TAG, "Upgrading test database from version " +
88963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert                  oldVersion + " to " + currentVersion +
89963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert                  ", which will destroy all old data");
90963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert            db.execSQL("DROP TABLE IF EXISTS data");
91963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert            onCreate(db);
92963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert        }
93963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert    }
94963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert
95963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert
96963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert    public MemoryFileProvider() {
97963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert    }
98963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert
99963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert    @Override
100963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert    public boolean onCreate() {
101963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert        mOpenHelper = new DatabaseHelper(getContext());
102963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert        try {
103963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert            OutputStream out = getContext().openFileOutput(DATA_FILE, Context.MODE_PRIVATE);
104963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert            out.write(TEST_BLOB);
105963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert            out.close();
106963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert        } catch (IOException ex) {
107963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert            ex.printStackTrace();
108963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert        }
109963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert        return true;
110963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert    }
111963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert
112963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert    @Override
113963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert    public Cursor query(Uri url, String[] projectionIn, String selection,
114963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert            String[] selectionArgs, String sort) {
115963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert        throw new UnsupportedOperationException("query not supported");
116963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert    }
117963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert
118963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert    @Override
119963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert    public String getType(Uri url) {
120963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert        int match = sURLMatcher.match(url);
121963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert        switch (match) {
122963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert            case DATA_ID_BLOB:
123963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert                return "application/octet-stream";
124963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert            case FILE:
125963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert                return "application/octet-stream";
126963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert            default:
127963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert                throw new IllegalArgumentException("Unknown URL");
128963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert        }
129963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert    }
130963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert
131963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert    @Override
132a006b47298539d89dc7a06b54c070cb3e986352aBjorn Bringert    public ParcelFileDescriptor openFile(Uri url, String mode) throws FileNotFoundException {
133963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert        int match = sURLMatcher.match(url);
134963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert        switch (match) {
135963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert            case DATA_ID_BLOB:
136963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert                String sql = "SELECT _blob FROM data WHERE _id=" + url.getPathSegments().get(1);
137a006b47298539d89dc7a06b54c070cb3e986352aBjorn Bringert                return getBlobColumnAsFile(url, mode, sql);
138963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert            case HUGE:
139963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert                try {
140a006b47298539d89dc7a06b54c070cb3e986352aBjorn Bringert                    return ParcelFileDescriptor.fromData(TEST_BLOB, null);
141963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert                } catch (IOException ex) {
142963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert                    throw new FileNotFoundException("Error reading " + url + ":" + ex.toString());
143963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert                }
144963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert            case FILE:
145963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert                File file = getContext().getFileStreamPath(DATA_FILE);
146a006b47298539d89dc7a06b54c070cb3e986352aBjorn Bringert                return ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY);
147963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert            default:
148963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert                throw new FileNotFoundException("No files supported by provider at " + url);
149963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert        }
150963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert    }
151963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert
152a006b47298539d89dc7a06b54c070cb3e986352aBjorn Bringert    private ParcelFileDescriptor getBlobColumnAsFile(Uri url, String mode, String sql)
153963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert            throws FileNotFoundException {
154963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert        if (!"r".equals(mode)) {
155963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert            throw new FileNotFoundException("Mode " + mode + " not supported for " + url);
156963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert        }
157963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert
158a006b47298539d89dc7a06b54c070cb3e986352aBjorn Bringert        SQLiteDatabase db = mOpenHelper.getReadableDatabase();
159a006b47298539d89dc7a06b54c070cb3e986352aBjorn Bringert        return DatabaseUtils.blobFileDescriptorForQuery(db, sql, null);
160963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert    }
161963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert
162963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert    @Override
163963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert    public int update(Uri url, ContentValues values, String where, String[] whereArgs) {
164963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert        throw new UnsupportedOperationException("update not supported");
165963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert    }
166963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert
167963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert    @Override
168963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert    public Uri insert(Uri url, ContentValues initialValues) {
169963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert        throw new UnsupportedOperationException("insert not supported");
170963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert    }
171963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert
172963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert    @Override
173963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert    public int delete(Uri url, String where, String[] whereArgs) {
174963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert        throw new UnsupportedOperationException("delete not supported");
175963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert    }
176963cd006c45716b034f656bf7e7179e6476f7e4dBjorn Bringert}
177