Home | History | Annotate | Download | only in launcher3
      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      */
     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      */
     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
     79     public void onCreate() {
     80         super.onCreate();
     81         mHelper = new LauncherBackupHelper(this);
     82         addHelper(LAUNCHER_DATA_PREFIX, mHelper);
     83     }
     84 
     85     @Override
     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