Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cf2ee87f authored by Hai Zhang's avatar Hai Zhang
Browse files

Maintain compatibility by deleting target directory before renaming into it.

The target shouldn't be a directory, but if it is, it would be
deleted (as long as it's empty). This became some kind of API and we
need to remain compatible with it.

Bug: 151959443
Test: Reboot and ensure ShortcutService can persist its state
Change-Id: I11a80cd4252128b025912b7aab86b113935e549a
Merged-In: I11a80cd4252128b025912b7aab86b113935e549a
parent 25adf3c4
Loading
Loading
Loading
Loading
+20 −11
Original line number Diff line number Diff line
@@ -116,10 +116,7 @@ public class AtomicFile {
        mStartTime = startTime;

        if (mLegacyBackupName.exists()) {
            if (!mLegacyBackupName.renameTo(mBaseName)) {
                Log.e(LOG_TAG, "Failed to rename legacy backup file " + mLegacyBackupName
                        + " to base file " + mBaseName);
            }
            rename(mLegacyBackupName, mBaseName);
        }

        try {
@@ -157,9 +154,7 @@ public class AtomicFile {
        } catch (IOException e) {
            Log.e(LOG_TAG, "Failed to close file output stream", e);
        }
        if (!mNewName.renameTo(mBaseName)) {
            Log.e(LOG_TAG, "Failed to rename new file " + mNewName + " to base file " + mBaseName);
        }
        rename(mNewName, mBaseName);
        if (mCommitTag != null) {
            com.android.internal.logging.EventLogTags.writeCommitSysConfigFile(
                    mCommitTag, SystemClock.uptimeMillis() - mStartTime);
@@ -221,10 +216,7 @@ public class AtomicFile {
     */
    public FileInputStream openRead() throws FileNotFoundException {
        if (mLegacyBackupName.exists()) {
            if (!mLegacyBackupName.renameTo(mBaseName)) {
                Log.e(LOG_TAG, "Failed to rename legacy backup file " + mLegacyBackupName
                        + " to base file " + mBaseName);
            }
            rename(mLegacyBackupName, mBaseName);
        }

        // Don't delete mNewName here - it was okay to call openRead() between startWrite() and
@@ -301,4 +293,21 @@ public class AtomicFile {
            IoUtils.closeQuietly(out);
        }
    }

    private static void rename(File source, File target) {
        // We used to delete the target file before rename, but that isn't atomic, and the rename()
        // syscall should atomically replace the target file. However in the case where the target
        // file is a directory, a simple rename() won't work. We need to delete the file in this
        // case because there are callers who erroneously called mBaseName.mkdirs() (instead of
        // mBaseName.getParentFile().mkdirs()) before creating the AtomicFile, and it worked
        // regardless, so this deletion became some kind of API.
        if (target.isDirectory()) {
            if (!target.delete()) {
                Log.e(LOG_TAG, "Failed to delete file which is a directory " + target);
            }
        }
        if (!source.renameTo(target)) {
            Log.e(LOG_TAG, "Failed to rename " + source + " to " + target);
        }
    }
}