• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2013 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.launcher3;
18 
19 import android.app.backup.BackupAgentHelper;
20 import android.app.backup.BackupDataInput;
21 import android.app.backup.BackupManager;
22 import android.content.Context;
23 import android.content.SharedPreferences;
24 import android.database.Cursor;
25 import android.os.ParcelFileDescriptor;
26 import android.util.Log;
27 
28 import com.android.launcher3.model.GridSizeMigrationTask;
29 
30 import java.io.IOException;
31 
32 public class LauncherBackupAgentHelper extends BackupAgentHelper {
33 
34     private static final String TAG = "LauncherBAHelper";
35 
36     private static final String KEY_LAST_NOTIFIED_TIME = "backup_manager_last_notified";
37 
38     private static final String LAUNCHER_DATA_PREFIX = "L";
39 
40     static final boolean VERBOSE = false;
41     static final boolean DEBUG = false;
42 
43     /**
44      * Notify the backup manager that out database is dirty.
45      *
46      * <P>This does not force an immediate backup.
47      *
48      * @param context application context
49      */
dataChanged(Context context)50     public static void dataChanged(Context context) {
51         dataChanged(context, 0);
52     }
53 
54     /**
55      * Notify the backup manager that out database is dirty.
56      *
57      * <P>This does not force an immediate backup.
58      *
59      * @param context application context
60      * @param throttleMs duration in ms for which two consecutive calls to backup manager should
61      *                   not be made.
62      */
dataChanged(Context context, long throttleMs)63     public static void dataChanged(Context context, long throttleMs) {
64         SharedPreferences prefs = Utilities.getPrefs(context);
65         long now = System.currentTimeMillis();
66         long lastTime = prefs.getLong(KEY_LAST_NOTIFIED_TIME, 0);
67 
68         // User can manually change the system time, which could lead to now < lastTime.
69         // Re-backup in that case, as the backup will have a wrong lastModifiedTime.
70         if (now < lastTime || now >= (lastTime + throttleMs)) {
71             BackupManager.dataChanged(context.getPackageName());
72             prefs.edit().putLong(KEY_LAST_NOTIFIED_TIME, now).apply();
73         }
74     }
75 
76     private LauncherBackupHelper mHelper;
77 
78     @Override
onCreate()79     public void onCreate() {
80         super.onCreate();
81         mHelper = new LauncherBackupHelper(this);
82         addHelper(LAUNCHER_DATA_PREFIX, mHelper);
83     }
84 
85     @Override
onRestore(BackupDataInput data, int appVersionCode, ParcelFileDescriptor newState)86     public void onRestore(BackupDataInput data, int appVersionCode, ParcelFileDescriptor newState)
87             throws IOException {
88         if (!Utilities.ATLEAST_LOLLIPOP) {
89             // No restore for old devices.
90             Log.i(TAG, "You shall not pass!!!");
91             Log.d(TAG, "Restore is only supported on devices running Lollipop and above.");
92             return;
93         }
94 
95         // Clear dB before restore
96         LauncherAppState.getLauncherProvider().createEmptyDB();
97 
98         boolean hasData;
99         try {
100             super.onRestore(data, appVersionCode, newState);
101             // If no favorite was migrated, clear the data and start fresh.
102             final Cursor c = getContentResolver().query(
103                     LauncherSettings.Favorites.CONTENT_URI, null, null, null, null);
104             hasData = c.moveToNext();
105             c.close();
106         } catch (Exception e) {
107             // If the restore fails, we should do a fresh start.
108             Log.e(TAG, "Restore failed", e);
109             hasData = false;
110         }
111 
112         if (hasData && mHelper.restoreSuccessful) {
113             LauncherAppState.getLauncherProvider().clearFlagEmptyDbCreated();
114             LauncherClings.markFirstRunClingDismissed(this);
115 
116             // Rank was added in v4.
117             if (mHelper.restoredBackupVersion <= 3) {
118                 LauncherAppState.getLauncherProvider().updateFolderItemsRank();
119             }
120 
121             if (GridSizeMigrationTask.ENABLED && mHelper.shouldAttemptWorkspaceMigration()) {
122                 GridSizeMigrationTask.markForMigration(getApplicationContext(),
123                         mHelper.widgetSizes, mHelper.migrationCompatibleProfileData);
124             }
125 
126             LauncherAppState.getLauncherProvider().convertShortcutsToLauncherActivities();
127         } else {
128             if (VERBOSE) Log.v(TAG, "Nothing was restored, clearing DB");
129             LauncherAppState.getLauncherProvider().createEmptyDB();
130         }
131     }
132 }
133