18cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck/*
28cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck * Copyright (C) 2011 The Android Open Source Project
38cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck *
48cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck * Licensed under the Apache License, Version 2.0 (the "License");
58cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck * you may not use this file except in compliance with the License.
68cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck * You may obtain a copy of the License at
78cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck *
88cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck *      http://www.apache.org/licenses/LICENSE-2.0
98cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck *
108cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck * Unless required by applicable law or agreed to in writing, software
118cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck * distributed under the License is distributed on an "AS IS" BASIS,
128cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck * See the License for the specific language governing permissions and
148cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck * limitations under the License.
158cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck */
168cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reckpackage com.android.browser.provider;
178cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck
188cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reckimport android.content.BroadcastReceiver;
198cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reckimport android.content.ContentProvider;
208cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reckimport android.content.ContentUris;
218cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reckimport android.content.ContentValues;
228cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reckimport android.content.Context;
238cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reckimport android.content.Intent;
248cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reckimport android.content.IntentFilter;
258cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reckimport android.content.UriMatcher;
268cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reckimport android.database.Cursor;
278cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reckimport android.database.DatabaseUtils;
288cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reckimport android.database.sqlite.SQLiteDatabase;
298cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reckimport android.database.sqlite.SQLiteOpenHelper;
308cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reckimport android.database.sqlite.SQLiteQueryBuilder;
318cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reckimport android.net.Uri;
328cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reckimport android.os.Environment;
338cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reckimport android.provider.BrowserContract;
348cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck
358cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reckimport java.io.File;
368cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck
378cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck/**
388cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck * This provider is expected to be potentially flaky. It uses a database
398cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck * stored on external storage, which could be yanked unexpectedly.
408cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck */
418cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reckpublic class SnapshotProvider extends ContentProvider {
428cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck
438cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck    public static interface Snapshots {
448cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck
458cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        public static final Uri CONTENT_URI = Uri.withAppendedPath(
468cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck                SnapshotProvider.AUTHORITY_URI, "snapshots");
478cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        public static final String _ID = "_id";
488cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        public static final String VIEWSTATE = "view_state";
498cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        public static final String BACKGROUND = "background";
508cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        public static final String TITLE = "title";
518cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        public static final String URL = "url";
528cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        public static final String FAVICON = "favicon";
538cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        public static final String THUMBNAIL = "thumbnail";
548cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        public static final String DATE_CREATED = "date_created";
558cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck    }
568cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck
578cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck    public static final String AUTHORITY = "com.android.browser.snapshots";
588cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck    public static final Uri AUTHORITY_URI = Uri.parse("content://" + AUTHORITY);
598cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck
608cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck    static final String TABLE_SNAPSHOTS = "snapshots";
618cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck    static final int SNAPSHOTS = 10;
628cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck    static final int SNAPSHOTS_ID = 11;
638cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck    static final UriMatcher URI_MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
648cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck
658cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck    SnapshotDatabaseHelper mOpenHelper;
668cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck
678cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck    static {
688cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        URI_MATCHER.addURI(AUTHORITY, "snapshots", SNAPSHOTS);
698cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        URI_MATCHER.addURI(AUTHORITY, "snapshots/#", SNAPSHOTS_ID);
708cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck    }
718cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck
728cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck    final static class SnapshotDatabaseHelper extends SQLiteOpenHelper {
738cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck
748cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        static final String DATABASE_NAME = "snapshots.db";
7568ca4ab8075cd087c9325154c9488d2420fae9f1John Reck        static final int DATABASE_VERSION = 2;
768cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck
778cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        public SnapshotDatabaseHelper(Context context) {
788cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck            super(context, getFullDatabaseName(context), null, DATABASE_VERSION);
798cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        }
808cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck
818cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        static String getFullDatabaseName(Context context) {
828cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck            File dir = context.getExternalFilesDir(null);
838cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck            return new File(dir, DATABASE_NAME).getAbsolutePath();
848cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        }
858cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck
868cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        @Override
878cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        public void onCreate(SQLiteDatabase db) {
888cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck            db.execSQL("CREATE TABLE " + TABLE_SNAPSHOTS + "(" +
898cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck                    Snapshots._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
908cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck                    Snapshots.TITLE + " TEXT," +
918cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck                    Snapshots.URL + " TEXT NOT NULL," +
928cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck                    Snapshots.DATE_CREATED + " INTEGER," +
938cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck                    Snapshots.FAVICON + " BLOB," +
948cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck                    Snapshots.THUMBNAIL + " BLOB," +
958cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck                    Snapshots.BACKGROUND + " INTEGER," +
968cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck                    Snapshots.VIEWSTATE + " BLOB NOT NULL" +
978cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck                    ");");
988cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        }
998cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck
1008cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        @Override
1018cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
10268ca4ab8075cd087c9325154c9488d2420fae9f1John Reck            if (oldVersion < 2) {
10368ca4ab8075cd087c9325154c9488d2420fae9f1John Reck                db.execSQL("DROP TABLE " + TABLE_SNAPSHOTS);
10468ca4ab8075cd087c9325154c9488d2420fae9f1John Reck                onCreate(db);
10568ca4ab8075cd087c9325154c9488d2420fae9f1John Reck            }
1068cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        }
1078cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck
1088cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck    }
1098cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck
1108cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck    @Override
1118cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck    public boolean onCreate() {
1128cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        IntentFilter filter = new IntentFilter(Intent.ACTION_MEDIA_EJECT);
1138cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        filter.addAction(Intent.ACTION_MEDIA_UNMOUNTED);
1148cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        getContext().registerReceiver(mExternalStorageReceiver, filter);
1158cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        return true;
1168cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck    }
1178cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck
1188cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck    final BroadcastReceiver mExternalStorageReceiver = new BroadcastReceiver() {
1198cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck
1208cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        @Override
1218cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        public void onReceive(Context context, Intent intent) {
122b98cb5187fcb3034ee3675de791fd811d76d1593Ben Murdoch            if (mOpenHelper != null) {
123b98cb5187fcb3034ee3675de791fd811d76d1593Ben Murdoch                try {
124b98cb5187fcb3034ee3675de791fd811d76d1593Ben Murdoch                    mOpenHelper.close();
125b98cb5187fcb3034ee3675de791fd811d76d1593Ben Murdoch                } catch (Throwable t) {
126b98cb5187fcb3034ee3675de791fd811d76d1593Ben Murdoch                    // We failed to close the open helper, which most likely means
127b98cb5187fcb3034ee3675de791fd811d76d1593Ben Murdoch                    // another thread is busy attempting to open the database
128b98cb5187fcb3034ee3675de791fd811d76d1593Ben Murdoch                    // or use the database. Let that thread try to gracefully
129b98cb5187fcb3034ee3675de791fd811d76d1593Ben Murdoch                    // deal with the error
130b98cb5187fcb3034ee3675de791fd811d76d1593Ben Murdoch                }
1318cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck            }
1328cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        }
1338cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck    };
1348cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck
1358cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck    SQLiteDatabase getWritableDatabase() {
1368cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        String state = Environment.getExternalStorageState();
1378cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        if (Environment.MEDIA_MOUNTED.equals(state)) {
1388cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck            try {
139b98cb5187fcb3034ee3675de791fd811d76d1593Ben Murdoch                if (mOpenHelper == null) {
140b98cb5187fcb3034ee3675de791fd811d76d1593Ben Murdoch                    mOpenHelper = new SnapshotDatabaseHelper(getContext());
141b98cb5187fcb3034ee3675de791fd811d76d1593Ben Murdoch                }
1428cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck                return mOpenHelper.getWritableDatabase();
1438cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck            } catch (Throwable t) {
1448cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck                return null;
1458cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck            }
1468cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        }
1478cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        return null;
1488cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck    }
1498cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck
1508cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck    SQLiteDatabase getReadableDatabase() {
1518cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        String state = Environment.getExternalStorageState();
1528cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        if (Environment.MEDIA_MOUNTED.equals(state)
1538cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck                || Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
1548cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck            try {
155b98cb5187fcb3034ee3675de791fd811d76d1593Ben Murdoch                if (mOpenHelper == null) {
156b98cb5187fcb3034ee3675de791fd811d76d1593Ben Murdoch                    mOpenHelper = new SnapshotDatabaseHelper(getContext());
157b98cb5187fcb3034ee3675de791fd811d76d1593Ben Murdoch                }
1588cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck                return mOpenHelper.getReadableDatabase();
1598cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck            } catch (Throwable t) {
1608cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck                return null;
1618cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck            }
1628cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        }
1638cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        return null;
1648cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck    }
1658cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck
1668cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck    @Override
1678cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck    public Cursor query(Uri uri, String[] projection, String selection,
1688cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck            String[] selectionArgs, String sortOrder) {
1698cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        SQLiteDatabase db = getReadableDatabase();
1708cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        if (db == null) {
1718cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck            return null;
1728cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        }
1738cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        final int match = URI_MATCHER.match(uri);
1748cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
1758cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        String limit = uri.getQueryParameter(BrowserContract.PARAM_LIMIT);
1768cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        switch (match) {
1778cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        case SNAPSHOTS_ID:
1788cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck            selection = DatabaseUtils.concatenateWhere(selection, "_id=?");
1798cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck            selectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs,
1808cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck                    new String[] { Long.toString(ContentUris.parseId(uri)) });
1818cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck            // fall through
1828cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        case SNAPSHOTS:
1838cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck            qb.setTables(TABLE_SNAPSHOTS);
1848cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck            break;
1858cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck
1868cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        default:
1878cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck            throw new UnsupportedOperationException("Unknown URL " + uri.toString());
1888cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        }
1898cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        try {
1908cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck            Cursor cursor = qb.query(db, projection, selection, selectionArgs,
1918cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck                    null, null, sortOrder, limit);
1928cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck            cursor.setNotificationUri(getContext().getContentResolver(),
1938cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck                    AUTHORITY_URI);
1948cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck            return cursor;
1958cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        } catch (Throwable t) {
1968cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck            return null;
1978cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        }
1988cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck    }
1998cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck
2008cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck    @Override
2018cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck    public String getType(Uri uri) {
2028cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        return null;
2038cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck    }
2048cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck
2058cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck    @Override
2068cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck    public Uri insert(Uri uri, ContentValues values) {
2078cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        SQLiteDatabase db = getWritableDatabase();
2088cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        if (db == null) {
2098cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck            return null;
2108cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        }
2118cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        int match = URI_MATCHER.match(uri);
2128cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        long id = -1;
2138cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        switch (match) {
2148cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        case SNAPSHOTS:
2158cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck            try {
2168cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck                id = db.insert(TABLE_SNAPSHOTS, Snapshots.TITLE, values);
2178cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck            } catch (Throwable t) {
2188cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck                id = -1;
2198cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck            }
2208cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck            break;
2218cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        default:
2228cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck            throw new UnsupportedOperationException("Unknown insert URI " + uri);
2238cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        }
2248cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        if (id < 0) {
2258cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck            return null;
2268cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        }
2278cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        Uri inserted = ContentUris.withAppendedId(uri, id);
2288cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        getContext().getContentResolver().notifyChange(inserted, null, false);
2298cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        return inserted;
2308cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck    }
2318cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck
2328cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck    @Override
2338cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck    public int delete(Uri uri, String selection, String[] selectionArgs) {
2348cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        SQLiteDatabase db = getWritableDatabase();
2358cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        if (db == null) {
2368cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck            return 0;
2378cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        }
2388cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        int match = URI_MATCHER.match(uri);
2398cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        int deleted = 0;
2408cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        switch (match) {
2418cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        case SNAPSHOTS_ID: {
2428cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck            selection = DatabaseUtils.concatenateWhere(selection, TABLE_SNAPSHOTS + "._id=?");
2438cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck            selectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs,
2448cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck                    new String[] { Long.toString(ContentUris.parseId(uri)) });
2458cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck            // fall through
2468cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        }
2478cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        case SNAPSHOTS:
2488cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck            try {
2498cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck                deleted = db.delete(TABLE_SNAPSHOTS, selection, selectionArgs);
2508cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck            } catch (Throwable t) {
2518cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck            }
2528cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck            break;
2538cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        default:
2548cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck            throw new UnsupportedOperationException("Unknown delete URI " + uri);
2558cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        }
2568cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        if (deleted > 0) {
2578cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck            getContext().getContentResolver().notifyChange(uri, null, false);
2588cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        }
2598cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        return deleted;
2608cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck    }
2618cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck
2628cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck    @Override
2638cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck    public int update(Uri uri, ContentValues values, String selection,
2648cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck            String[] selectionArgs) {
2658cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck        throw new UnsupportedOperationException("not implemented");
2668cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck    }
2678cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck
2688cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck}
269