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

Commit 15024975 authored by Ritesh Reddy's avatar Ritesh Reddy Committed by android-build-merger
Browse files

Merge "Stashing SyncSettings for accounts added aft SUW" into nyc-dev am: 9ca8ed93

am: 7db999af

* commit '7db999af':
  Stashing SyncSettings for accounts added aft SUW
parents d0faa505 7db999af
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)) {