Commit dd99fdcb by olly Committed by Andrew Lewis

Changes for SQLite databases on internal storage

- Remove ability to encrypt content index for SQLite storage
- Remove hack for specifying arbitrary database location

PiperOrigin-RevId: 232863763
parent a7324061
...@@ -16,20 +16,16 @@ ...@@ -16,20 +16,16 @@
package com.google.android.exoplayer2.database; package com.google.android.exoplayer2.database;
import android.content.Context; import android.content.Context;
import android.content.ContextWrapper;
import android.database.Cursor; import android.database.Cursor;
import android.database.DatabaseErrorHandler;
import android.database.SQLException; import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper; import android.database.sqlite.SQLiteOpenHelper;
import android.support.annotation.Nullable;
import com.google.android.exoplayer2.util.Log; import com.google.android.exoplayer2.util.Log;
import java.io.File;
/** /**
* An {@link SQLiteOpenHelper} that provides instances of a standalone ExoPlayer database. * An {@link SQLiteOpenHelper} that provides instances of a standalone ExoPlayer database.
* *
* <p>Suitable for use by applications that do not already have their own database, or which would * <p>Suitable for use by applications that do not already have their own database, or that would
* prefer to keep ExoPlayer tables isolated in their own database. Other applications should prefer * prefer to keep ExoPlayer tables isolated in their own database. Other applications should prefer
* to use {@link DefaultDatabaseProvider} with their own {@link SQLiteOpenHelper}. * to use {@link DefaultDatabaseProvider} with their own {@link SQLiteOpenHelper}.
*/ */
...@@ -51,15 +47,6 @@ public final class ExoDatabaseProvider extends SQLiteOpenHelper implements Datab ...@@ -51,15 +47,6 @@ public final class ExoDatabaseProvider extends SQLiteOpenHelper implements Datab
super(context.getApplicationContext(), DATABASE_NAME, /* factory= */ null, VERSION); super(context.getApplicationContext(), DATABASE_NAME, /* factory= */ null, VERSION);
} }
/**
* Provides instances of the database located at the specified file.
*
* @param file The database file.
*/
public ExoDatabaseProvider(File file) {
super(new DatabaseFileProvidingContext(file), file.getName(), /* factory= */ null, VERSION);
}
@Override @Override
public void onCreate(SQLiteDatabase db) { public void onCreate(SQLiteDatabase db) {
// Features create their own tables. // Features create their own tables.
...@@ -105,48 +92,4 @@ public final class ExoDatabaseProvider extends SQLiteOpenHelper implements Datab ...@@ -105,48 +92,4 @@ public final class ExoDatabaseProvider extends SQLiteOpenHelper implements Datab
} }
} }
} }
// TODO: This is fragile. Stop using it if/when SQLiteOpenHelper can be instantiated without a
// context [Internal ref: b/123351819], or by injecting a Context into all components that need
// to instantiate an ExoDatabaseProvider.
/** A {@link Context} that implements methods called by {@link SQLiteOpenHelper}. */
private static class DatabaseFileProvidingContext extends ContextWrapper {
private final File file;
@SuppressWarnings("nullness:argument.type.incompatible")
public DatabaseFileProvidingContext(File file) {
super(/* base= */ null);
this.file = file;
}
@Override
public File getDatabasePath(String name) {
return file;
}
@Override
public SQLiteDatabase openOrCreateDatabase(
String name, int mode, SQLiteDatabase.CursorFactory factory) {
return openOrCreateDatabase(name, mode, factory, /* errorHandler= */ null);
}
@Override
@SuppressWarnings("nullness:argument.type.incompatible")
public SQLiteDatabase openOrCreateDatabase(
String name,
int mode,
SQLiteDatabase.CursorFactory factory,
@Nullable DatabaseErrorHandler errorHandler) {
File databasePath = getDatabasePath(name);
int flags = SQLiteDatabase.CREATE_IF_NECESSARY;
if ((mode & MODE_ENABLE_WRITE_AHEAD_LOGGING) != 0) {
flags |= SQLiteDatabase.ENABLE_WRITE_AHEAD_LOGGING;
}
if ((mode & MODE_NO_LOCALIZED_COLLATORS) != 0) {
flags |= SQLiteDatabase.NO_LOCALIZED_COLLATORS;
}
return SQLiteDatabase.openDatabase(databasePath.getPath(), factory, flags, errorHandler);
}
}
} }
...@@ -45,6 +45,8 @@ public final class VersionTable { ...@@ -45,6 +45,8 @@ public final class VersionTable {
private static final String COLUMN_FEATURE = "feature"; private static final String COLUMN_FEATURE = "feature";
private static final String COLUMN_VERSION = "version"; private static final String COLUMN_VERSION = "version";
private static final String WHERE_FEATURE_EQUALS = COLUMN_FEATURE + " = ?";
private static final String SQL_CREATE_TABLE_IF_NOT_EXISTS = private static final String SQL_CREATE_TABLE_IF_NOT_EXISTS =
"CREATE TABLE IF NOT EXISTS " "CREATE TABLE IF NOT EXISTS "
+ TABLE_NAME + TABLE_NAME
...@@ -62,7 +64,7 @@ public final class VersionTable { ...@@ -62,7 +64,7 @@ public final class VersionTable {
private VersionTable() {} private VersionTable() {}
/** /**
* Sets the version of tables belonging to the specified feature. * Sets the version of the specified feature.
* *
* @param writableDatabase The database to update. * @param writableDatabase The database to update.
* @param feature The feature. * @param feature The feature.
...@@ -78,8 +80,21 @@ public final class VersionTable { ...@@ -78,8 +80,21 @@ public final class VersionTable {
} }
/** /**
* Returns the version of tables belonging to the specified feature, or {@link #VERSION_UNSET} if * Removes the version of the specified feature.
* no version information is available. *
* @param writableDatabase The database to update.
* @param feature The feature.
*/
public static void removeVersion(SQLiteDatabase writableDatabase, @Feature int feature) {
if (!tableExists(writableDatabase, TABLE_NAME)) {
return;
}
writableDatabase.delete(TABLE_NAME, WHERE_FEATURE_EQUALS, featureArgument(feature));
}
/**
* Returns the version of the specified feature, or {@link #VERSION_UNSET} if no version
* information is available.
* *
* @param database The database to query. * @param database The database to query.
* @param feature The feature. * @param feature The feature.
...@@ -88,14 +103,12 @@ public final class VersionTable { ...@@ -88,14 +103,12 @@ public final class VersionTable {
if (!tableExists(database, TABLE_NAME)) { if (!tableExists(database, TABLE_NAME)) {
return VERSION_UNSET; return VERSION_UNSET;
} }
String selection = COLUMN_FEATURE + " = ?";
String[] selectionArgs = {Integer.toString(feature)};
try (Cursor cursor = try (Cursor cursor =
database.query( database.query(
TABLE_NAME, TABLE_NAME,
new String[] {COLUMN_VERSION}, new String[] {COLUMN_VERSION},
selection, WHERE_FEATURE_EQUALS,
selectionArgs, featureArgument(feature),
/* groupBy= */ null, /* groupBy= */ null,
/* having= */ null, /* having= */ null,
/* orderBy= */ null)) { /* orderBy= */ null)) {
...@@ -114,4 +127,8 @@ public final class VersionTable { ...@@ -114,4 +127,8 @@ public final class VersionTable {
readableDatabase, "sqlite_master", "tbl_name = ?", new String[] {tableName}); readableDatabase, "sqlite_master", "tbl_name = ?", new String[] {tableName});
return count > 0; return count > 0;
} }
private static String[] featureArgument(int feature) {
return new String[] {Integer.toString(feature)};
}
} }
...@@ -73,7 +73,7 @@ public final class DefaultDownloadIndex implements DownloadIndex { ...@@ -73,7 +73,7 @@ public final class DefaultDownloadIndex implements DownloadIndex {
private static final int COLUMN_INDEX_STREAM_KEYS = 14; private static final int COLUMN_INDEX_STREAM_KEYS = 14;
private static final int COLUMN_INDEX_CUSTOM_METADATA = 15; private static final int COLUMN_INDEX_CUSTOM_METADATA = 15;
private static final String COLUMN_SELECTION_ID = COLUMN_ID + " = ?"; private static final String WHERE_ID_EQUALS = COLUMN_ID + " = ?";
private static final String[] COLUMNS = private static final String[] COLUMNS =
new String[] { new String[] {
...@@ -152,7 +152,7 @@ public final class DefaultDownloadIndex implements DownloadIndex { ...@@ -152,7 +152,7 @@ public final class DefaultDownloadIndex implements DownloadIndex {
@Nullable @Nullable
public DownloadState getDownloadState(String id) { public DownloadState getDownloadState(String id) {
ensureInitialized(); ensureInitialized();
try (Cursor cursor = getCursor(COLUMN_SELECTION_ID, new String[] {id})) { try (Cursor cursor = getCursor(WHERE_ID_EQUALS, new String[] {id})) {
if (cursor.getCount() == 0) { if (cursor.getCount() == 0) {
return null; return null;
} }
...@@ -210,9 +210,7 @@ public final class DefaultDownloadIndex implements DownloadIndex { ...@@ -210,9 +210,7 @@ public final class DefaultDownloadIndex implements DownloadIndex {
@Override @Override
public void removeDownloadState(String id) { public void removeDownloadState(String id) {
ensureInitialized(); ensureInitialized();
databaseProvider databaseProvider.getWritableDatabase().delete(TABLE_NAME, WHERE_ID_EQUALS, new String[] {id});
.getWritableDatabase()
.delete(TABLE_NAME, COLUMN_SELECTION_ID, new String[] {id});
} }
private void ensureInitialized() { private void ensureInitialized() {
......
...@@ -171,7 +171,6 @@ public final class SimpleCache implements Cache { ...@@ -171,7 +171,6 @@ public final class SimpleCache implements Cache {
} catch (CacheException e) { } catch (CacheException e) {
Log.e(TAG, "Storing index file failed", e); Log.e(TAG, "Storing index file failed", e);
} finally { } finally {
contentIndex.release();
unlockFolder(cacheDir); unlockFolder(cacheDir);
released = true; released = true;
} }
......
...@@ -68,6 +68,16 @@ public class VersionTableTest { ...@@ -68,6 +68,16 @@ public class VersionTableTest {
} }
@Test @Test
public void removeVersion_removesSetVersion() {
VersionTable.setVersion(writableDatabase, FEATURE_OFFLINE, 1);
assertThat(VersionTable.getVersion(readableDatabase, FEATURE_OFFLINE)).isEqualTo(1);
VersionTable.removeVersion(writableDatabase, FEATURE_OFFLINE);
assertThat(VersionTable.getVersion(readableDatabase, FEATURE_OFFLINE))
.isEqualTo(VersionTable.VERSION_UNSET);
}
@Test
public void doesTableExist_nonExistingTable_returnsFalse() { public void doesTableExist_nonExistingTable_returnsFalse() {
assertThat(VersionTable.tableExists(readableDatabase, "NonExistingTable")).isFalse(); assertThat(VersionTable.tableExists(readableDatabase, "NonExistingTable")).isFalse();
} }
......
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 sign in to comment