summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorConrad Chen <conradchen@google.com>2017-05-08 14:13:40 -0700
committerConrad Chen <conradchen@google.com>2017-05-11 14:28:07 -0700
commit3106a2deefc84c565eef6d6df50e7c359c3e4fe4 (patch)
tree5106e659c17188034fd31cd3d96a3e755cb85d44
parentfd09753145ae5af960e177e21857b224ea331048 (diff)
downloadTvProvider-3106a2deefc84c565eef6d6df50e7c359c3e4fe4.tar.gz
Fix bugs in TvProvider
Project maps and blocked packages are updated/loaded when DB is opened. It may cause inconsistency or NPE if we check projection maps or blocked packages before any actual DB operations are done. Test: gts-tradefed run gts -m GtsTvTestCases Bug: 37944095 Change-Id: I2444ea80d2123cebddeb05a56a91ced4b7a54290
-rw-r--r--src/com/android/providers/tv/TvProvider.java51
1 files changed, 29 insertions, 22 deletions
diff --git a/src/com/android/providers/tv/TvProvider.java b/src/com/android/providers/tv/TvProvider.java
index ceb864c..0a4577f 100644
--- a/src/com/android/providers/tv/TvProvider.java
+++ b/src/com/android/providers/tv/TvProvider.java
@@ -147,7 +147,7 @@ public class TvProvider extends ContentProvider {
private static final Map<String, String> sRecordedProgramProjectionMap;
private static final Map<String, String> sPreviewProgramProjectionMap;
private static final Map<String, String> sWatchNextProgramProjectionMap;
- private static boolean sProjectionMapsUpdated;
+ private static boolean sInitialized;
static {
sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
@@ -970,26 +970,27 @@ public class TvProvider extends ContentProvider {
@Override
public void onOpen(SQLiteDatabase db) {
- buildProjectionMap(db);
- sBlockedPackagesSharedPreference = PreferenceManager.getDefaultSharedPreferences(
- mContext);
- sBlockedPackages = new ConcurrentHashMap<>();
- for (String packageName : sBlockedPackagesSharedPreference.getStringSet(
- SHARED_PREF_BLOCKED_PACKAGES_KEY, new HashSet<>())) {
- sBlockedPackages.put(packageName, true);
+ // This method is thread-safe. It's guaranteed by the implementation of SQLiteOpenHelper
+ if (!sInitialized) {
+ buildProjectionMap(db);
+ sBlockedPackagesSharedPreference = PreferenceManager.getDefaultSharedPreferences(
+ mContext);
+ sBlockedPackages = new ConcurrentHashMap<>();
+ for (String packageName : sBlockedPackagesSharedPreference.getStringSet(
+ SHARED_PREF_BLOCKED_PACKAGES_KEY, new HashSet<>())) {
+ sBlockedPackages.put(packageName, true);
+ }
+ sInitialized = true;
}
}
private void buildProjectionMap(SQLiteDatabase db) {
- if (!sProjectionMapsUpdated) {
- updateProjectionMap(db, CHANNELS_TABLE, sChannelProjectionMap);
- updateProjectionMap(db, PROGRAMS_TABLE, sProgramProjectionMap);
- updateProjectionMap(db, WATCHED_PROGRAMS_TABLE, sWatchedProgramProjectionMap);
- updateProjectionMap(db, RECORDED_PROGRAMS_TABLE, sRecordedProgramProjectionMap);
- updateProjectionMap(db, PREVIEW_PROGRAMS_TABLE, sPreviewProgramProjectionMap);
- updateProjectionMap(db, WATCH_NEXT_PROGRAMS_TABLE, sWatchNextProgramProjectionMap);
- sProjectionMapsUpdated = true;
- }
+ updateProjectionMap(db, CHANNELS_TABLE, sChannelProjectionMap);
+ updateProjectionMap(db, PROGRAMS_TABLE, sProgramProjectionMap);
+ updateProjectionMap(db, WATCHED_PROGRAMS_TABLE, sWatchedProgramProjectionMap);
+ updateProjectionMap(db, RECORDED_PROGRAMS_TABLE, sRecordedProgramProjectionMap);
+ updateProjectionMap(db, PREVIEW_PROGRAMS_TABLE, sPreviewProgramProjectionMap);
+ updateProjectionMap(db, WATCH_NEXT_PROGRAMS_TABLE, sWatchNextProgramProjectionMap);
}
private void updateProjectionMap(SQLiteDatabase db, String tableName,
@@ -1129,11 +1130,7 @@ public class TvProvider extends ContentProvider {
if (!callerHasAccessAllEpgDataPermission()) {
return null;
}
- if (!sProjectionMapsUpdated) {
- // Database is not accessed before and the projection maps are not updated yet.
- // Gets database here to make it initialized.
- mOpenHelper.getReadableDatabase().close();
- }
+ ensureInitialized();
Map<String, String> projectionMap;
switch (method) {
case TvContract.METHOD_GET_COLUMNS:
@@ -1273,6 +1270,7 @@ public class TvProvider extends ContentProvider {
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
String sortOrder) {
+ ensureInitialized();
mTransientRowHelper.ensureOldTransientRowsDeleted();
boolean needsToValidateSortOrder = !callerHasAccessAllEpgDataPermission();
SqlParams params = createSqlParams(OP_QUERY, uri, selection, selectionArgs);
@@ -1326,6 +1324,7 @@ public class TvProvider extends ContentProvider {
@Override
public Uri insert(Uri uri, ContentValues values) {
+ ensureInitialized();
mTransientRowHelper.ensureOldTransientRowsDeleted();
switch (sUriMatcher.match(uri)) {
case MATCH_CHANNEL:
@@ -1585,6 +1584,14 @@ public class TvProvider extends ContentProvider {
return count;
}
+ private synchronized void ensureInitialized() {
+ if (!sInitialized) {
+ // Database is not accessed before and the projection maps and the blocked package list
+ // are not updated yet. Gets database here to make it initialized.
+ mOpenHelper.getReadableDatabase().close();
+ }
+ }
+
private Map<String, String> createProjectionMapForQuery(String[] projection,
Map<String, String> projectionMap) {
if (projection == null) {