diff options
-rw-r--r-- | jni/FuseDaemon.cpp | 7 | ||||
-rw-r--r-- | src/com/android/providers/media/DatabaseBackupAndRecovery.java | 27 | ||||
-rw-r--r-- | tests/src/com/android/providers/media/TestDatabaseBackupAndRecovery.java | 5 |
3 files changed, 36 insertions, 3 deletions
diff --git a/jni/FuseDaemon.cpp b/jni/FuseDaemon.cpp index 743551c2b..73f92d6f7 100644 --- a/jni/FuseDaemon.cpp +++ b/jni/FuseDaemon.cpp @@ -408,7 +408,7 @@ struct fuse { // LevelDb Connection Map std::map<std::string, leveldb::DB*> level_db_connection_map; - std::mutex level_db_mutex; + std::recursive_mutex level_db_mutex; }; struct OpenInfo { @@ -2690,8 +2690,9 @@ std::vector<std::string> FuseDaemon::ReadFilePathsFromLevelDb(const std::string& std::vector<std::string> file_paths; if (!CheckLevelDbConnection(volume_name)) { - LOG(INFO) << "ReadFilePathsFromLevelDb: Missing leveldb connection, attempting setup."; - SetupLevelDbInstances(); + fuse->level_db_mutex.unlock(); + LOG(ERROR) << "ReadFilePathsFromLevelDb: Missing leveldb connection"; + return file_paths; } leveldb::Iterator* it = diff --git a/src/com/android/providers/media/DatabaseBackupAndRecovery.java b/src/com/android/providers/media/DatabaseBackupAndRecovery.java index 6b824eca6..1cfc9e80f 100644 --- a/src/com/android/providers/media/DatabaseBackupAndRecovery.java +++ b/src/com/android/providers/media/DatabaseBackupAndRecovery.java @@ -64,6 +64,7 @@ import java.util.Map; import java.util.Optional; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; @@ -919,6 +920,13 @@ public class DatabaseBackupAndRecovery { } Log.d(TAG, "Backup is present for " + volumeName); + try { + waitForVolumeToBeAttached(mSetupCompleteVolumes); + } catch (Exception e) { + Log.e(TAG, "Volume not attached in given time. Cannot recover data.", e); + return; + } + long rowsRecovered = 0; long dirtyRowsCount = 0; String[] backedUpFilePaths; @@ -976,6 +984,25 @@ public class DatabaseBackupAndRecovery { return false; } + protected void waitForVolumeToBeAttached(Set<String> setupCompleteVolumes) + throws TimeoutException { + long time = 0; + // Wait of 10 seconds + long waitTimeInMilliseconds = 10000; + // Poll every 100 milliseconds + long pollTime = 100; + while (time <= waitTimeInMilliseconds) { + if (setupCompleteVolumes.contains(MediaStore.VOLUME_EXTERNAL_PRIMARY)) { + Log.i(TAG, "Found external primary volume attached."); + return; + } + + SystemClock.sleep(pollTime); + time += pollTime; + } + throw new TimeoutException("Timed out waiting for external primary setup"); + } + protected FuseDaemon getFuseDaemonForFileWithWait(File fuseFilePath) throws FileNotFoundException { pollForExternalStorageMountedState(); diff --git a/tests/src/com/android/providers/media/TestDatabaseBackupAndRecovery.java b/tests/src/com/android/providers/media/TestDatabaseBackupAndRecovery.java index 1e3d799a9..5cacc7535 100644 --- a/tests/src/com/android/providers/media/TestDatabaseBackupAndRecovery.java +++ b/tests/src/com/android/providers/media/TestDatabaseBackupAndRecovery.java @@ -28,6 +28,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.Set; public class TestDatabaseBackupAndRecovery extends DatabaseBackupAndRecovery { @@ -94,4 +95,8 @@ public class TestDatabaseBackupAndRecovery extends DatabaseBackupAndRecovery { @Override public void removeRecoveryDataExceptValidUsers(List<String> validUsers) { } + + @Override + protected void waitForVolumeToBeAttached(Set<String> setupCompleteVolumes) { + } } |