blob: a96495de831693b52f7a296605383ff5332d347a [file] [log] [blame]
Sunny Goyalc190dbf2016-05-05 14:37:05 -07001package com.android.launcher3;
2
Stefan Andonian8c0a7872024-10-21 14:26:27 -07003import static com.android.launcher3.LauncherPrefs.NO_DB_FILES_RESTORED;
4
Sunny Goyalc190dbf2016-05-05 14:37:05 -07005import android.app.backup.BackupAgent;
6import android.app.backup.BackupDataInput;
7import android.app.backup.BackupDataOutput;
Sunny Goyalc190dbf2016-05-05 14:37:05 -07008import android.os.ParcelFileDescriptor;
9
Sunny Goyal49f19f02017-01-05 14:36:02 -080010import com.android.launcher3.logging.FileLog;
Sunny Goyale8f7d5a2016-05-24 11:30:14 -070011import com.android.launcher3.provider.RestoreDbTask;
Sunny Goyalc190dbf2016-05-05 14:37:05 -070012
Alex Chau29a96ad2022-02-10 13:12:20 +000013import java.io.File;
14import java.io.IOException;
Stefan Andonian8c0a7872024-10-21 14:26:27 -070015import java.util.Arrays;
16import java.util.stream.Collectors;
Alex Chau29a96ad2022-02-10 13:12:20 +000017
Sunny Goyalc190dbf2016-05-05 14:37:05 -070018public class LauncherBackupAgent extends BackupAgent {
Alex Chau29a96ad2022-02-10 13:12:20 +000019 private static final String TAG = "LauncherBackupAgent";
Stefan Andonian8c0a7872024-10-21 14:26:27 -070020 private static final String DB_FILE_PREFIX = "launcher";
21 private static final String DB_FILE_SUFFIX = ".db";
Alex Chau29a96ad2022-02-10 13:12:20 +000022
Sunny Goyalc190dbf2016-05-05 14:37:05 -070023 @Override
Sunny Goyal49f19f02017-01-05 14:36:02 -080024 public void onCreate() {
25 super.onCreate();
26 // Set the log dir as LauncherAppState is not initialized during restore.
27 FileLog.setDir(getFilesDir());
28 }
29
30 @Override
Sunny Goyalc190dbf2016-05-05 14:37:05 -070031 public void onRestore(
32 BackupDataInput data, int appVersionCode, ParcelFileDescriptor newState) {
33 // Doesn't do incremental backup/restore
34 }
35
36 @Override
Alex Chau29a96ad2022-02-10 13:12:20 +000037 public void onRestoreFile(ParcelFileDescriptor data, long size, File destination, int type,
38 long mode, long mtime) throws IOException {
39 // Remove old files which might contain obsolete attributes like idp_grid_name in shared
40 // preference that will obstruct backup's attribute from writing to shared preferences.
41 if (destination.delete()) {
Charlie Andersonc9d11e82023-08-02 11:41:55 -040042 FileLog.d(TAG, "onRestoreFile: Removed obsolete file " + destination);
Alex Chau29a96ad2022-02-10 13:12:20 +000043 }
44 super.onRestoreFile(data, size, destination, type, mode, mtime);
45 }
46
47 @Override
Sunny Goyalc190dbf2016-05-05 14:37:05 -070048 public void onBackup(
49 ParcelFileDescriptor oldState, BackupDataOutput data, ParcelFileDescriptor newState) {
50 // Doesn't do incremental backup/restore
51 }
52
53 @Override
54 public void onRestoreFinished() {
Sunny Goyal68031ca2021-08-02 12:23:44 -070055 RestoreDbTask.setPending(this);
Stefan Andonian8c0a7872024-10-21 14:26:27 -070056 FileLog.d(TAG, "onRestoreFinished: set pending for RestoreDbTask");
57 markIfFilesWereNotActuallyRestored();
58 }
59
60 /**
61 * When restore is finished, we check to see if any db files were successfully restored. If not,
62 * our restore will fail later, but will report a different cause. This is important to split
63 * out the metric failures that are launcher's fault, and those that are due to bugs in the
64 * backup/restore code itself.
65 */
66 private void markIfFilesWereNotActuallyRestored() {
67 File directory = new File(getDatabasePath(InvariantDeviceProfile.INSTANCE.get(this).dbFile)
68 .getParent());
69 if (!directory.exists()) {
70 FileLog.e(TAG, "restore failed as target database directory doesn't exist");
71 } else {
72 // Check for any db file that was restored, and collect as list
73 String fileNames = Arrays.stream(directory.listFiles())
74 .map(File::getName)
75 .filter(n -> n.startsWith(DB_FILE_PREFIX) && n.endsWith(DB_FILE_SUFFIX))
76 .collect(Collectors.joining(", "));
77 if (fileNames.isBlank()) {
78 FileLog.e(TAG, "no database files were successfully restored");
79 LauncherPrefs.get(this).putSync(NO_DB_FILES_RESTORED.to(true));
80 } else {
81 FileLog.d(TAG, "database files successfully restored: " + fileNames);
82 }
83 }
Sunny Goyalc190dbf2016-05-05 14:37:05 -070084 }
85}