release-request-951b3a8b-6c0c-4d2e-8af4-1c3f7e209f66-for-git_oc-release-4006899 snap-temp-L39600000063784275

Change-Id: Ifa351e3ad40e80afe2acb56ea3f7bfff5e6590da
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 @@
     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 @@
 
         @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 @@
         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 @@
     @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 @@
 
     @Override
     public Uri insert(Uri uri, ContentValues values) {
+        ensureInitialized();
         mTransientRowHelper.ensureOldTransientRowsDeleted();
         switch (sUriMatcher.match(uri)) {
             case MATCH_CHANNEL:
@@ -1585,6 +1584,14 @@
         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) {