Commit 8cc92358 authored by John Reck's avatar John Reck
Browse files

Move Snapshots to own DB on sdcard

 Bug: 4982126

Change-Id: Ib66b2880d163de4feb4d880e1d01996301bbea08
parent dc0282ad
...@@ -254,6 +254,10 @@ ...@@ -254,6 +254,10 @@
</intent-filter> </intent-filter>
</receiver> </receiver>
<provider android:name=".provider.SnapshotProvider"
android:authorities="com.android.browser.snapshots"
android:exported="false" />
</application> </application>
</manifest> </manifest>
......
...@@ -40,8 +40,9 @@ ...@@ -40,8 +40,9 @@
android:textSize="12sp" android:textSize="12sp"
android:typeface="sans" android:typeface="sans"
android:textColor="@android:color/white" android:textColor="@android:color/white"
android:paddingLeft="2dip" android:paddingLeft="6dip"
android:paddingRight="2dip" /> android:paddingRight="2dip"
android:gravity="center_vertical" />
<ImageView <ImageView
android:id="@+id/divider" android:id="@+id/divider"
android:src="?android:attr/dividerVertical" android:src="?android:attr/dividerVertical"
......
...@@ -43,7 +43,7 @@ import android.widget.ImageView; ...@@ -43,7 +43,7 @@ import android.widget.ImageView;
import android.widget.ResourceCursorAdapter; import android.widget.ResourceCursorAdapter;
import android.widget.TextView; import android.widget.TextView;
import com.android.browser.provider.BrowserProvider2.Snapshots; import com.android.browser.provider.SnapshotProvider.Snapshots;
import java.text.DateFormat; import java.text.DateFormat;
import java.util.Date; import java.util.Date;
...@@ -61,12 +61,14 @@ public class BrowserSnapshotPage extends Fragment implements ...@@ -61,12 +61,14 @@ public class BrowserSnapshotPage extends Fragment implements
Snapshots.THUMBNAIL, Snapshots.THUMBNAIL,
Snapshots.FAVICON, Snapshots.FAVICON,
Snapshots.URL, Snapshots.URL,
Snapshots.DATE_CREATED,
}; };
private static final int SNAPSHOT_TITLE = 1; private static final int SNAPSHOT_TITLE = 1;
private static final int SNAPSHOT_VIEWSTATE_LENGTH = 2; private static final int SNAPSHOT_VIEWSTATE_LENGTH = 2;
private static final int SNAPSHOT_THUMBNAIL = 3; private static final int SNAPSHOT_THUMBNAIL = 3;
private static final int SNAPSHOT_FAVICON = 4; private static final int SNAPSHOT_FAVICON = 4;
private static final int SNAPSHOT_URL = 5; private static final int SNAPSHOT_URL = 5;
private static final int SNAPSHOT_DATE_CREATED = 6;
GridView mGrid; GridView mGrid;
View mEmpty; View mEmpty;
...@@ -113,10 +115,9 @@ public class BrowserSnapshotPage extends Fragment implements ...@@ -113,10 +115,9 @@ public class BrowserSnapshotPage extends Fragment implements
@Override @Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) { public Loader<Cursor> onCreateLoader(int id, Bundle args) {
if (id == LOADER_SNAPSHOTS) { if (id == LOADER_SNAPSHOTS) {
// TODO: Sort by date created
return new CursorLoader(getActivity(), return new CursorLoader(getActivity(),
Snapshots.CONTENT_URI, PROJECTION, Snapshots.CONTENT_URI, PROJECTION,
null, null, null); null, null, Snapshots.DATE_CREATED + " DESC");
} }
return null; return null;
} }
...@@ -216,12 +217,11 @@ public class BrowserSnapshotPage extends Fragment implements ...@@ -216,12 +217,11 @@ public class BrowserSnapshotPage extends Fragment implements
title.setText(cursor.getString(SNAPSHOT_TITLE)); title.setText(cursor.getString(SNAPSHOT_TITLE));
TextView size = (TextView) view.findViewById(R.id.size); TextView size = (TextView) view.findViewById(R.id.size);
int stateLen = cursor.getInt(SNAPSHOT_VIEWSTATE_LENGTH); int stateLen = cursor.getInt(SNAPSHOT_VIEWSTATE_LENGTH);
size.setText(String.format("%.1fMB", stateLen / 1024f / 1024f)); size.setText(String.format("%.2fMB", stateLen / 1024f / 1024f));
// We don't actually have the date in the database yet long timestamp = cursor.getLong(SNAPSHOT_DATE_CREATED);
// Use the current date as a placeholder
TextView date = (TextView) view.findViewById(R.id.date); TextView date = (TextView) view.findViewById(R.id.date);
DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.SHORT); DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.SHORT);
date.setText(dateFormat.format(new Date())); date.setText(dateFormat.format(new Date(timestamp)));
} }
@Override @Override
......
...@@ -79,7 +79,7 @@ import com.android.browser.IntentHandler.UrlData; ...@@ -79,7 +79,7 @@ import com.android.browser.IntentHandler.UrlData;
import com.android.browser.UI.ComboViews; import com.android.browser.UI.ComboViews;
import com.android.browser.UI.DropdownChangeListener; import com.android.browser.UI.DropdownChangeListener;
import com.android.browser.provider.BrowserProvider; import com.android.browser.provider.BrowserProvider;
import com.android.browser.provider.BrowserProvider2.Snapshots; import com.android.browser.provider.SnapshotProvider.Snapshots;
import com.android.browser.search.SearchEngine; import com.android.browser.search.SearchEngine;
import com.android.common.Search; import com.android.common.Search;
...@@ -1945,7 +1945,7 @@ public class Controller ...@@ -1945,7 +1945,7 @@ public class Controller
return null; return null;
} }
private static Bitmap createScreenshot(WebView view, int width, int height) { static Bitmap createScreenshot(WebView view, int width, int height) {
// We render to a bitmap 2x the desired size so that we can then // We render to a bitmap 2x the desired size so that we can then
// re-scale it with filtering since canvas.scale doesn't filter // re-scale it with filtering since canvas.scale doesn't filter
// This helps reduce aliasing at the cost of being slightly blurry // This helps reduce aliasing at the cost of being slightly blurry
......
...@@ -20,19 +20,21 @@ import android.content.ContentUris; ...@@ -20,19 +20,21 @@ import android.content.ContentUris;
import android.content.ContentValues; import android.content.ContentValues;
import android.database.Cursor; import android.database.Cursor;
import android.graphics.BitmapFactory; import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.net.Uri; import android.net.Uri;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Bundle; import android.util.Log;
import android.webkit.WebView; import android.webkit.WebView;
import com.android.browser.provider.BrowserProvider2.Snapshots; import com.android.browser.provider.SnapshotProvider.Snapshots;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.util.zip.GZIPInputStream;
public class SnapshotTab extends Tab { public class SnapshotTab extends Tab {
private static final String LOGTAG = "SnapshotTab";
private long mSnapshotId; private long mSnapshotId;
private LoadData mLoadTask; private LoadData mLoadTask;
private WebViewFactory mWebViewFactory; private WebViewFactory mWebViewFactory;
...@@ -145,8 +147,13 @@ public class SnapshotTab extends Tab { ...@@ -145,8 +147,13 @@ public class SnapshotTab extends Tab {
WebView web = mTab.getWebView(); WebView web = mTab.getWebView();
if (web != null) { if (web != null) {
byte[] data = result.getBlob(4); byte[] data = result.getBlob(4);
ByteArrayInputStream stream = new ByteArrayInputStream(data); ByteArrayInputStream bis = new ByteArrayInputStream(data);
web.loadViewState(stream); try {
GZIPInputStream stream = new GZIPInputStream(bis);
web.loadViewState(stream);
} catch (Exception e) {
Log.w(LOGTAG, "Failed to load view state", e);
}
} }
mTab.mBackgroundColor = result.getInt(5); mTab.mBackgroundColor = result.getInt(5);
mTab.mWebViewController.onPageFinished(mTab); mTab.mWebViewController.onPageFinished(mTab);
......
...@@ -27,6 +27,7 @@ import android.content.DialogInterface.OnCancelListener; ...@@ -27,6 +27,7 @@ import android.content.DialogInterface.OnCancelListener;
import android.content.Intent; import android.content.Intent;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.BitmapFactory; import android.graphics.BitmapFactory;
import android.graphics.Bitmap.CompressFormat;
import android.net.Uri; import android.net.Uri;
import android.net.http.SslError; import android.net.http.SslError;
import android.os.Bundle; import android.os.Bundle;
...@@ -63,7 +64,7 @@ import android.widget.TextView; ...@@ -63,7 +64,7 @@ import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import com.android.browser.homepages.HomeProvider; import com.android.browser.homepages.HomeProvider;
import com.android.browser.provider.BrowserProvider2.Snapshots; import com.android.browser.provider.SnapshotProvider.Snapshots;
import com.android.common.speech.LoggingEvents; import com.android.common.speech.LoggingEvents;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
...@@ -73,6 +74,7 @@ import java.util.Iterator; ...@@ -73,6 +74,7 @@ import java.util.Iterator;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.Map; import java.util.Map;
import java.util.Vector; import java.util.Vector;
import java.util.zip.GZIPOutputStream;
/** /**
* Class for maintaining Tabs with a main WebView and a subwindow. * Class for maintaining Tabs with a main WebView and a subwindow.
...@@ -1875,28 +1877,42 @@ class Tab { ...@@ -1875,28 +1877,42 @@ class Tab {
public ContentValues createSnapshotValues() { public ContentValues createSnapshotValues() {
if (mMainView == null) return null; if (mMainView == null) return null;
/* ByteArrayOutputStream bos = new ByteArrayOutputStream();
* TODO: Compression try {
* Some quick tests indicate GZIPing the stream will result in GZIPOutputStream stream = new GZIPOutputStream(bos);
* some decent savings. There is little overhead for sites with mostly if (!mMainView.saveViewState(stream)) {
* images (such as the "Most Visited" page), dropping from 235kb return null;
* to 200kb. Sites with a decent amount of text (hardocp.com), the size }
* drops from 522kb to 381kb. Do this as part of the switch to saving stream.flush();
* to the SD card. stream.close();
*/ } catch (Exception e) {
ByteArrayOutputStream stream = new ByteArrayOutputStream(); Log.w(LOGTAG, "Failed to save view state", e);
if (!mMainView.saveViewState(stream)) {
return null; return null;
} }
byte[] data = stream.toByteArray(); byte[] data = bos.toByteArray();
ContentValues values = new ContentValues(); ContentValues values = new ContentValues();
values.put(Snapshots.TITLE, mCurrentState.mTitle); values.put(Snapshots.TITLE, mCurrentState.mTitle);
values.put(Snapshots.URL, mCurrentState.mUrl); values.put(Snapshots.URL, mCurrentState.mUrl);
values.put(Snapshots.VIEWSTATE, data); values.put(Snapshots.VIEWSTATE, data);
values.put(Snapshots.BACKGROUND, mMainView.getPageBackgroundColor()); values.put(Snapshots.BACKGROUND, mMainView.getPageBackgroundColor());
values.put(Snapshots.DATE_CREATED, System.currentTimeMillis());
values.put(Snapshots.FAVICON, compressBitmap(getFavicon()));
Bitmap screenshot = Controller.createScreenshot(mMainView,
Controller.getDesiredThumbnailWidth(mContext),
Controller.getDesiredThumbnailHeight(mContext));
values.put(Snapshots.THUMBNAIL, compressBitmap(screenshot));
return values; return values;
} }
public byte[] compressBitmap(Bitmap bitmap) {
if (bitmap == null) {
return null;
}
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(CompressFormat.PNG, 100, stream);
return stream.toByteArray();
}
public void loadUrl(String url, Map<String, String> headers) { public void loadUrl(String url, Map<String, String> headers) {
if (mMainView != null) { if (mMainView != null) {
mCurrentState = new PageState(mContext, false, url, null); mCurrentState = new PageState(mContext, false, url, null);
......
...@@ -68,19 +68,6 @@ import java.util.HashMap; ...@@ -68,19 +68,6 @@ import java.util.HashMap;
public class BrowserProvider2 extends SQLiteContentProvider { public class BrowserProvider2 extends SQLiteContentProvider {
public static interface Snapshots {
public static final Uri CONTENT_URI = Uri.withAppendedPath(
BrowserContract.AUTHORITY_URI, "snapshots");
public static final String _ID = "_id";
public static final String VIEWSTATE = "view_state";
public static final String BACKGROUND = "background";
public static final String TITLE = History.TITLE;
public static final String URL = History.URL;
public static final String FAVICON = History.FAVICON;
public static final String THUMBNAIL = History.THUMBNAIL;
}
public static final String PARAM_GROUP_BY = "groupBy"; public static final String PARAM_GROUP_BY = "groupBy";
public static final String LEGACY_AUTHORITY = "browser"; public static final String LEGACY_AUTHORITY = "browser";
...@@ -152,9 +139,6 @@ public class BrowserProvider2 extends SQLiteContentProvider { ...@@ -152,9 +139,6 @@ public class BrowserProvider2 extends SQLiteContentProvider {
static final int LEGACY = 9000; static final int LEGACY = 9000;
static final int LEGACY_ID = 9001; static final int LEGACY_ID = 9001;
static final int SNAPSHOTS = 10000;
static final int SNAPSHOTS_ID = 10001;
public static final long FIXED_ID_ROOT = 1; public static final long FIXED_ID_ROOT = 1;
// Default sort order for unsync'd bookmarks // Default sort order for unsync'd bookmarks
...@@ -216,9 +200,6 @@ public class BrowserProvider2 extends SQLiteContentProvider { ...@@ -216,9 +200,6 @@ public class BrowserProvider2 extends SQLiteContentProvider {
"bookmarks/" + SearchManager.SUGGEST_URI_PATH_QUERY, "bookmarks/" + SearchManager.SUGGEST_URI_PATH_QUERY,
BOOKMARKS_SUGGESTIONS); BOOKMARKS_SUGGESTIONS);
matcher.addURI(authority, "snapshots", SNAPSHOTS);
matcher.addURI(authority, "snapshots/#", SNAPSHOTS_ID);
// Projection maps // Projection maps
HashMap<String, String> map; HashMap<String, String> map;
...@@ -352,7 +333,7 @@ public class BrowserProvider2 extends SQLiteContentProvider { ...@@ -352,7 +333,7 @@ public class BrowserProvider2 extends SQLiteContentProvider {
final class DatabaseHelper extends SQLiteOpenHelper { final class DatabaseHelper extends SQLiteOpenHelper {
static final String DATABASE_NAME = "browser2.db"; static final String DATABASE_NAME = "browser2.db";
static final int DATABASE_VERSION = 29; static final int DATABASE_VERSION = 30;
public DatabaseHelper(Context context) { public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION); super(context, DATABASE_NAME, null, DATABASE_VERSION);
} }
...@@ -423,8 +404,6 @@ public class BrowserProvider2 extends SQLiteContentProvider { ...@@ -423,8 +404,6 @@ public class BrowserProvider2 extends SQLiteContentProvider {
} }
enableSync(db); enableSync(db);
createSnapshots(db);
} }
void enableSync(SQLiteDatabase db) { void enableSync(SQLiteDatabase db) {
...@@ -521,8 +500,9 @@ public class BrowserProvider2 extends SQLiteContentProvider { ...@@ -521,8 +500,9 @@ public class BrowserProvider2 extends SQLiteContentProvider {
@Override @Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
if (oldVersion < 29) { if (oldVersion < 30) {
createSnapshots(db); db.execSQL("DROP VIEW IF EXISTS " + VIEW_SNAPSHOTS_COMBINED);
db.execSQL("DROP TABLE IF EXISTS " + TABLE_SNAPSHOTS);
} }
if (oldVersion < 28) { if (oldVersion < 28) {
enableSync(db); enableSync(db);
...@@ -544,23 +524,6 @@ public class BrowserProvider2 extends SQLiteContentProvider { ...@@ -544,23 +524,6 @@ public class BrowserProvider2 extends SQLiteContentProvider {
} }
} }
void createSnapshots(SQLiteDatabase db) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_SNAPSHOTS);
db.execSQL("CREATE TABLE " + TABLE_SNAPSHOTS + " (" +
Snapshots._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
Snapshots.URL + " TEXT NOT NULL," +
Snapshots.TITLE + " TEXT," +
Snapshots.BACKGROUND + " INTEGER," +
Snapshots.VIEWSTATE + " BLOB NOT NULL" +
");");
db.execSQL("CREATE VIEW IF NOT EXISTS " + VIEW_SNAPSHOTS_COMBINED +
" AS SELECT * FROM " + TABLE_SNAPSHOTS +
" LEFT OUTER JOIN " + TABLE_IMAGES +
" ON " + TABLE_SNAPSHOTS + "." + Snapshots.URL +
" = images.url_key");
}
@Override
public void onOpen(SQLiteDatabase db) { public void onOpen(SQLiteDatabase db) {
db.enableWriteAheadLogging(); db.enableWriteAheadLogging();
mSyncHelper.onDatabaseOpened(db); mSyncHelper.onDatabaseOpened(db);
...@@ -1011,17 +974,6 @@ public class BrowserProvider2 extends SQLiteContentProvider { ...@@ -1011,17 +974,6 @@ public class BrowserProvider2 extends SQLiteContentProvider {
break; break;
} }
case SNAPSHOTS_ID: {
selection = DatabaseUtils.concatenateWhere(selection, "_id=?");
selectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs,
new String[] { Long.toString(ContentUris.parseId(uri)) });
// fall through
}
case SNAPSHOTS: {
qb.setTables(VIEW_SNAPSHOTS_COMBINED);
break;
}
default: { default: {
throw new UnsupportedOperationException("Unknown URL " + uri.toString()); throw new UnsupportedOperationException("Unknown URL " + uri.toString());
} }
...@@ -1221,16 +1173,6 @@ public class BrowserProvider2 extends SQLiteContentProvider { ...@@ -1221,16 +1173,6 @@ public class BrowserProvider2 extends SQLiteContentProvider {
} }
break; break;
} }
case SNAPSHOTS_ID: {
selection = DatabaseUtils.concatenateWhere(selection, TABLE_SNAPSHOTS + "._id=?");
selectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs,
new String[] { Long.toString(ContentUris.parseId(uri)) });
// fall through
}
case SNAPSHOTS: {
deleted = db.delete(TABLE_SNAPSHOTS, selection, selectionArgs);
break;
}
default: { default: {
throw new UnsupportedOperationException("Unknown delete URI " + uri); throw new UnsupportedOperationException("Unknown delete URI " + uri);
} }
...@@ -1368,11 +1310,6 @@ public class BrowserProvider2 extends SQLiteContentProvider { ...@@ -1368,11 +1310,6 @@ public class BrowserProvider2 extends SQLiteContentProvider {
break; break;
} }
case SNAPSHOTS: {
id = db.insertOrThrow(TABLE_SNAPSHOTS, Snapshots.TITLE, values);
break;
}
default: { default: {
throw new UnsupportedOperationException("Unknown insert URI " + uri); throw new UnsupportedOperationException("Unknown insert URI " + uri);
} }
......
/*
* Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.browser.provider;
import android.content.BroadcastReceiver;
import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.DatabaseUtils;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.os.Environment;
import android.provider.BrowserContract;
import java.io.File;
/**
* This provider is expected to be potentially flaky. It uses a database
* stored on external storage, which could be yanked unexpectedly.
*/
public class SnapshotProvider extends ContentProvider {
public static interface Snapshots {
public static final Uri CONTENT_URI = Uri.withAppendedPath(
SnapshotProvider.AUTHORITY_URI, "snapshots");
public static final String _ID = "_id";
public static final String VIEWSTATE = "view_state";
public static final String BACKGROUND = "background";
public static final String TITLE = "title";
public static final String URL = "url";
public static final String FAVICON = "favicon";
public static final String THUMBNAIL = "thumbnail";
public static final String DATE_CREATED = "date_created";
}
public static final String AUTHORITY = "com.android.browser.snapshots";
public static final Uri AUTHORITY_URI = Uri.parse("content://" + AUTHORITY);
static final String TABLE_SNAPSHOTS = "snapshots";
static final int SNAPSHOTS = 10;
static final int SNAPSHOTS_ID = 11;
static final UriMatcher URI_MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
SnapshotDatabaseHelper mOpenHelper;
static {
URI_MATCHER.addURI(AUTHORITY, "snapshots", SNAPSHOTS);
URI_MATCHER.addURI(AUTHORITY, "snapshots/#", SNAPSHOTS_ID);
}
final static class SnapshotDatabaseHelper extends SQLiteOpenHelper {
static final String DATABASE_NAME = "snapshots.db";
static final int DATABASE_VERSION = 1;
public SnapshotDatabaseHelper(Context context) {
super(context, getFullDatabaseName(context), null, DATABASE_VERSION);
}
static String getFullDatabaseName(Context context) {
File dir = context.getExternalFilesDir(null);
return new File(dir, DATABASE_NAME).getAbsolutePath();
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE " + TABLE_SNAPSHOTS + "(" +
Snapshots._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
Snapshots.TITLE + " TEXT," +
Snapshots.URL + " TEXT NOT NULL," +
Snapshots.DATE_CREATED + " INTEGER," +
Snapshots.FAVICON + " BLOB," +
Snapshots.THUMBNAIL + " BLOB," +
Snapshots.BACKGROUND + " INTEGER," +
Snapshots.VIEWSTATE + " BLOB NOT NULL" +
");");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// Not needed yet
}
}
@Override
public boolean onCreate() {
mOpenHelper = new SnapshotDatabaseHelper(getContext());
IntentFilter filter = new IntentFilter(Intent.ACTION_MEDIA_EJECT);
filter.addAction(Intent.ACTION_MEDIA_UNMOUNTED);
getContext().registerReceiver(mExternalStorageReceiver, filter);
return true;
}
final BroadcastReceiver mExternalStorageReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
try {
mOpenHelper.close();
} catch (Throwable t) {
// We failed to close the open helper, which most likely means
// another thread is busy attempting to open the database
// or use the database. Let that thread try to gracefully
// deal with the error
}
}
};
SQLiteDatabase getWritableDatabase() {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
try {
return mOpenHelper.getWritableDatabase();
} catch (Throwable t) {
return null;
}
}
return null;
}
SQLiteDatabase getReadableDatabase() {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)
|| Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
try {
return mOpenHelper.getReadableDatabase();
} catch (Throwable t) {
return null;
}
}
return null;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
SQLiteDatabase db = getReadableDatabase();
if (db == null) {
return null;
}
final int match = URI_MATCHER.match(uri);
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
String limit = uri.getQueryParameter(BrowserContract.PARAM_LIMIT);
switch (match) {
case SNAPSHOTS_ID:
selection = DatabaseUtils.concatenateWhere(selection, "_id=?");
selectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs,
new String[] { Long.toString(ContentUris.parseId(uri)) });
// fall through
case SNAPSHOTS:
qb.setTables(TABLE_SNAPSHOTS);
break;
default:
throw new UnsupportedOperationException("Unknown URL " + uri.toString());
}
try {
Cursor cursor = qb.query(db, projection, selection, selectionArgs,
null, null, sortOrder, limit);
cursor.setNotificationUri(getContext().getContentResolver(),
AUTHORITY_URI);
return cursor;
} catch (Throwable t) {
return null;
}
}
@Override
public String getType(Uri uri) {
return null;
}
@Override
public Uri insert(Uri uri, ContentValues values) {
SQLiteDatabase db = getWritableDatabase();
if (db == null) {
return null;
}
int match = URI_MATCHER.match(uri);
long id = -1;
switch (match) {
case SNAPSHOTS:
try {
id = db.insert(TABLE_SNAPSHOTS, Snapshots.TITLE, values);
} catch (Throwable t) {
id = -1;
}
break;
default:
throw new UnsupportedOperationException("Unknown insert URI " + uri);
}
if (id < 0) {
return null;
}
Uri inserted = ContentUris.withAppendedId(uri, id);
getContext().getContentResolver().notifyChange(inserted, null, false);
return inserted;
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
SQLiteDatabase db = getWritableDatabase();
if (db == null) {
return 0;
}
int match = URI_MATCHER.match(uri);
int deleted = 0;
switch (match) {
case SNAPSHOTS_ID: {
selection = DatabaseUtils.concatenateWhere(selection, TABLE_SNAPSHOTS + "._id=?");
selectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs,
new String[] { Long.toString(ContentUris.parseId(uri)) });
// fall through
}
case SNAPSHOTS:
try {
deleted = db.delete(TABLE_SNAPSHOTS, selection, selectionArgs);
} catch (Throwable t) {
}
break;
default:
throw new UnsupportedOperationException("Unknown delete URI " + uri);
}
if (deleted > 0) {
getContext().getContentResolver().notifyChange(uri, null, false);
}
return deleted;
}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
throw new UnsupportedOperationException("not implemented");
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment