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

Commit 9ca8ed93 authored by Ritesh Reddy's avatar Ritesh Reddy Committed by Android (Google) Code Review
Browse files

Merge "Stashing SyncSettings for accounts added aft SUW" into nyc-dev

parents 67a28e8c ae0bcddc
Loading
Loading
Loading
Loading
+88 −25
Original line number Diff line number Diff line
@@ -16,10 +16,6 @@

package com.android.server.backup;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.accounts.Account;
import android.accounts.AccountManager;
import android.app.backup.BackupDataInputStream;
@@ -28,14 +24,21 @@ import android.app.backup.BackupHelper;
import android.content.ContentResolver;
import android.content.Context;
import android.content.SyncAdapterType;
import android.os.Environment;
import android.os.ParcelFileDescriptor;
import android.util.Log;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.MessageDigest;
@@ -73,6 +76,8 @@ public class AccountSyncSettingsBackupHelper implements BackupHelper {
    private static final String KEY_AUTHORITY_NAME = "name";
    private static final String KEY_AUTHORITY_SYNC_STATE = "syncState";
    private static final String KEY_AUTHORITY_SYNC_ENABLED = "syncEnabled";
    private static final String STASH_FILE = Environment.getDataDirectory()
            + "/backup/unadded_account_syncsettings.json";

    private Context mContext;
    private AccountManager mAccountManager;
@@ -256,33 +261,91 @@ public class AccountSyncSettingsBackupHelper implements BackupHelper {
            }

            try {
                HashSet<Account> currentAccounts = getAccountsHashSet();
                restoreFromJsonArray(accountJSONArray);
            } finally {
                // Set the master sync preference to the value from the backup set.
                ContentResolver.setMasterSyncAutomatically(masterSyncEnabled);
            }
            Log.i(TAG, "Restore successful.");
        } catch (IOException | JSONException e) {
            Log.e(TAG, "Couldn't restore account sync settings\n" + e);
        }
    }

    private void restoreFromJsonArray(JSONArray accountJSONArray)
            throws JSONException {
        HashSet<Account> currentAccounts = getAccounts();
        JSONArray unaddedAccountsJSONArray = new JSONArray();
        for (int i = 0; i < accountJSONArray.length(); i++) {
            JSONObject accountJSON = (JSONObject) accountJSONArray.get(i);
            String accountName = accountJSON.getString(KEY_ACCOUNT_NAME);
            String accountType = accountJSON.getString(KEY_ACCOUNT_TYPE);

                    Account account = new Account(accountName, accountType);
            Account account = null;
            try {
                account = new Account(accountName, accountType);
            } catch (IllegalArgumentException iae) {
                continue;
            }

            // Check if the account already exists. Accounts that don't exist on the device
            // yet won't be restored.
            if (currentAccounts.contains(account)) {
                if (DEBUG) Log.i(TAG, "Restoring Sync Settings for" + accountName);
                restoreExistingAccountSyncSettingsFromJSON(accountJSON);
            } else {
                        // TODO:
                        // Stash the data to a file that the SyncManager can read from to restore
                        // settings at a later date.
                unaddedAccountsJSONArray.put(accountJSON);
            }
        }
            } finally {
                // Set the master sync preference to the value from the backup set.
                ContentResolver.setMasterSyncAutomatically(masterSyncEnabled);

        if (unaddedAccountsJSONArray.length() > 0) {
            try (FileOutputStream fOutput = new FileOutputStream(STASH_FILE)) {
                String jsonString = unaddedAccountsJSONArray.toString();
                DataOutputStream out = new DataOutputStream(fOutput);
                out.writeUTF(jsonString);
            } catch (IOException ioe) {
                // Error in writing to stash file
                Log.e(TAG, "unable to write the sync settings to the stash file", ioe);
            }
        } else {
            File stashFile = new File(STASH_FILE);
            if (stashFile.exists()) stashFile.delete();
        }
    }

            Log.i(TAG, "Restore successful.");
        } catch (IOException | JSONException e) {
            Log.e(TAG, "Couldn't restore account sync settings\n" + e);
    /**
     * Restore SyncSettings for all existing accounts from a stashed backup-set
     */
    private void accountAddedInternal() {
        String jsonString;

        try (FileInputStream fIn = new FileInputStream(new File(STASH_FILE))) {
            DataInputStream in = new DataInputStream(fIn);
            jsonString = in.readUTF();
        } catch (FileNotFoundException fnfe) {
            // This is expected to happen when there is no accounts info stashed
            if (DEBUG) Log.d(TAG, "unable to find the stash file", fnfe);
            return;
        } catch (IOException ioe) {
            if (DEBUG) Log.d(TAG, "could not read sync settings from stash file", ioe);
            return;
        }

        try {
            JSONArray unaddedAccountsJSONArray = new JSONArray(jsonString);
            restoreFromJsonArray(unaddedAccountsJSONArray);
        } catch (JSONException jse) {
            // Malformed jsonString
            Log.e(TAG, "there was an error with the stashed sync settings", jse);
        }
    }

    /**
     * Restore SyncSettings for all existing accounts from a stashed backup-set
     */
    public static void accountAdded(Context context) {
        AccountSyncSettingsBackupHelper helper = new AccountSyncSettingsBackupHelper(context);
        helper.accountAddedInternal();
    }

    /**
@@ -290,7 +353,7 @@ public class AccountSyncSettingsBackupHelper implements BackupHelper {
     *
     * @return Accounts in a HashSet.
     */
    private HashSet<Account> getAccountsHashSet() {
    private HashSet<Account> getAccounts() {
        Account[] accounts = mAccountManager.getAccounts();
        HashSet<Account> accountHashSet = new HashSet<Account>();
        for (Account account : accounts) {
+47 −33
Original line number Diff line number Diff line
@@ -62,6 +62,7 @@ import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.Messenger;
import android.os.PowerManager;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -70,41 +71,42 @@ import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.UserManager;
import android.os.WorkSource;
import android.os.Messenger;
import android.provider.Settings;
import android.text.format.DateUtils;
import android.text.format.Time;
import android.util.EventLog;
import android.util.Log;
import android.util.Slog;
import android.util.Pair;

import android.util.Slog;
import android.util.SparseArray;

import com.google.android.collect.Lists;
import com.google.android.collect.Maps;

import com.android.internal.R;
import com.android.internal.app.IBatteryStats;
import com.android.internal.os.BackgroundThread;
import com.android.internal.util.IndentingPrintWriter;
import com.android.server.accounts.AccountManagerService;
import com.android.server.backup.AccountSyncSettingsBackupHelper;
import com.android.server.content.SyncStorageEngine.AuthorityInfo;
import com.android.server.content.SyncStorageEngine.EndPoint;
import com.android.server.content.SyncStorageEngine.OnSyncRequestListener;
import com.google.android.collect.Lists;
import com.google.android.collect.Maps;

import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Random;
import java.util.List;
import java.util.Set;
import java.util.HashSet;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Map;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Random;
import java.util.Set;

/**
 * Implementation details:
@@ -2572,6 +2574,7 @@ public class SyncManager {
        }

        private void updateRunningAccountsH(EndPoint syncTargets) {
            AccountAndUser[] oldAccounts = mRunningAccounts;
            mRunningAccounts = AccountManagerService.getSingleton().getRunningAccounts();
            if (Log.isLoggable(TAG, Log.VERBOSE)) {
                Slog.v(TAG, "Accounts list: ");
@@ -2595,6 +2598,17 @@ public class SyncManager {
                }
            }

            // On account add, check if there are any settings to be restored.
            for (AccountAndUser aau : mRunningAccounts) {
                if (!containsAccountAndUser(oldAccounts, aau.account, aau.userId)) {
                    if (Log.isLoggable(TAG, Log.DEBUG)) {
                        Log.d(TAG, "Account " + aau.account + " added, checking sync restore data");
                    }
                    AccountSyncSettingsBackupHelper.accountAdded(mContext);
                    break;
                }
            }

            List<SyncOperation> ops = getAllPendingSyncsFromCache();
            for (SyncOperation op: ops) {
                if (!containsAccountAndUser(accounts, op.target.account, op.target.userId)) {