Handle an edge case that can reset settings provider data

If the AtomicFile does the rename and fails when writing the
original, make sure we can at least use the backup on reboot.

Bug: 63753300
Test: Stop shell, move settings_global.xml to backup, start shell.
Change-Id: I2049b48af05161bb2c68717a71c1700a95150a6c
This commit is contained in:
Amith Yamasani
2017-07-19 16:49:52 -07:00
parent 479b762f99
commit 74bf71b23c
3 changed files with 23 additions and 10 deletions

View File

@@ -201,6 +201,15 @@ public class AtomicFile {
return new FileInputStream(mBaseName);
}
/**
* @hide
* Checks if the original or backup file exists.
* @return whether the original or backup file exists.
*/
public boolean exists() {
return mBaseName.exists() || mBackupName.exists();
}
/**
* Gets the last modified time of the atomic file.
* {@hide}

View File

@@ -2597,7 +2597,7 @@ public class SettingsProvider extends ContentProvider {
synchronized (mLock) {
final int key = makeKey(SETTINGS_TYPE_GLOBAL, UserHandle.USER_SYSTEM);
File globalFile = getSettingsFile(key);
if (globalFile.exists()) {
if (SettingsState.stateFileExists(globalFile)) {
return;
}
@@ -2634,7 +2634,7 @@ public class SettingsProvider extends ContentProvider {
// Every user has secure settings and if no file we need to migrate.
final int secureKey = makeKey(SETTINGS_TYPE_SECURE, userId);
File secureFile = getSettingsFile(secureKey);
if (secureFile.exists()) {
if (SettingsState.stateFileExists(secureFile)) {
return;
}

View File

@@ -689,17 +689,11 @@ final class SettingsState {
private void readStateSyncLocked() {
FileInputStream in;
if (!mStatePersistFile.exists()) {
Slog.i(LOG_TAG, "No settings state " + mStatePersistFile);
addHistoricalOperationLocked(HISTORICAL_OPERATION_INITIALIZE, null);
return;
}
try {
in = new AtomicFile(mStatePersistFile).openRead();
} catch (FileNotFoundException fnfe) {
String message = "No settings state " + mStatePersistFile;
Slog.wtf(LOG_TAG, message);
Slog.i(LOG_TAG, message);
Slog.i(LOG_TAG, "No settings state " + mStatePersistFile);
addHistoricalOperationLocked(HISTORICAL_OPERATION_INITIALIZE, null);
return;
}
try {
@@ -715,6 +709,16 @@ final class SettingsState {
}
}
/**
* Uses AtomicFile to check if the file or its backup exists.
* @param file The file to check for existence
* @return whether the original or backup exist
*/
public static boolean stateFileExists(File file) {
AtomicFile stateFile = new AtomicFile(file);
return stateFile.exists();
}
private void parseStateLocked(XmlPullParser parser)
throws IOException, XmlPullParserException {
final int outerDepth = parser.getDepth();