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

Commit 5e79e323 authored by Christopher Tate's avatar Christopher Tate Committed by The Android Open Source Project
Browse files

am 91717497: Use system properties to track the current transport

Merge commit '91717497'

* commit '91717497':
  Use system properties to track the current transport
parents da6edf4d 91717497
Loading
Loading
Loading
Loading
+54 −11
Original line number Diff line number Diff line
@@ -124,11 +124,14 @@ public final class Bmgr {

    private void doTransport() {
        try {
            int which = Integer.parseInt(nextArg());
            int old = mBmgr.selectBackupTransport(which);
            String which = nextArg();
            String old = mBmgr.selectBackupTransport(which);
            if (old == null) {
                System.out.println("Unknown transport '" + which
                        + "' specified; no changes made.");
            } else {
                System.out.println("Selected transport " + which + " (formerly " + old + ")");
        } catch (NumberFormatException e) {
            showUsage();
            }
        } catch (RemoteException e) {
            System.err.println(e.toString());
            System.err.println(BMGR_NOT_RUNNING_ERR);
@@ -144,7 +147,7 @@ public final class Bmgr {

        // The rest of the 'list' options work with a restore session on the current transport
        try {
            int curTransport = mBmgr.getCurrentTransport();
            String curTransport = mBmgr.getCurrentTransport();
            mRestore = mBmgr.beginRestoreSession(curTransport);
            if (mRestore == null) {
                System.err.println(BMGR_NOT_RUNNING_ERR);
@@ -153,6 +156,8 @@ public final class Bmgr {

            if ("sets".equals(arg)) {
                doListRestoreSets();
            } else if ("transports".equals(arg)) {
                doListTransports();
            }

            mRestore.endRestoreSession();
@@ -163,6 +168,22 @@ public final class Bmgr {
    }

    private void doListTransports() {
        try {
            String current = mBmgr.getCurrentTransport();
            String[] transports = mBmgr.listAllTransports();
            if (transports == null || transports.length == 0) {
                System.out.println("No transports available.");
                return;
            }

            for (String t : transports) {
                String pad = (t.equals(current)) ? "  * " : "    ";
                System.out.println(pad + t);
            }
        } catch (RemoteException e) {
            System.err.println(e.toString());
            System.err.println(BMGR_NOT_RUNNING_ERR);
        }
    }

    private void doListRestoreSets() {
@@ -217,7 +238,7 @@ public final class Bmgr {

        try {
            boolean didRestore = false;
            int curTransport = mBmgr.getCurrentTransport();
            String curTransport = mBmgr.getCurrentTransport();
            mRestore = mBmgr.beginRestoreSession(curTransport);
            if (mRestore == null) {
                System.err.println(BMGR_NOT_RUNNING_ERR);
@@ -269,11 +290,33 @@ public final class Bmgr {

    private static void showUsage() {
        System.err.println("usage: bmgr [backup|restore|list|transport|run]");
        System.err.println("       bmgr backup [-f] package");
        System.err.println("       bmgr backup PACKAGE");
        System.err.println("       bmgr list transports");
        System.err.println("       bmgr list sets");
        System.err.println("       #bmgr list transports");
        System.err.println("       #bmgr transport which#");
        System.err.println("       bmgr restore token#");
        System.err.println("       bmgr transport WHICH");
        System.err.println("       bmgr restore TOKEN");
        System.err.println("       bmgr run");
        System.err.println("");
        System.err.println("The 'backup' command schedules a backup pass for the named package.");
        System.err.println("Note that the backup pass will effectively be a no-op if the package");
        System.err.println("does not actually have changed data to store.");
        System.err.println("");
        System.err.println("The 'list transports' command reports the names of the backup transports");
        System.err.println("currently available on the device.  These names can be passed as arguments");
        System.err.println("to the 'transport' command.  The currently selected transport is indicated");
        System.err.println("with a '*' character.");
        System.err.println("");
        System.err.println("The 'list sets' command reports the token and name of each restore set");
        System.err.println("available to the device via the current transport.");
        System.err.println("");
        System.err.println("The 'transport' command designates the named transport as the currently");
        System.err.println("active one.  This setting is persistent across reboots.");
        System.err.println("");
        System.err.println("The 'restore' command initiates a restore operation, using the restore set");
        System.err.println("from the current transport whose token matches the argument.");
        System.err.println("");
        System.err.println("The 'run' command causes any scheduled backup operation to be initiated");
        System.err.println("immediately, without the usual waiting period for batching together");
        System.err.println("data changes.");
    }
}
+2 −2
Original line number Diff line number Diff line
@@ -83,11 +83,11 @@ public class BackupManager {
     *
     * {@hide}
     */
    public IRestoreSession beginRestoreSession(int transportID) {
    public IRestoreSession beginRestoreSession(String transport) {
        IRestoreSession binder = null;
        if (mService != null) {
            try {
                binder = mService.beginRestoreSession(transportID);
                binder = mService.beginRestoreSession(transport);
            } catch (RemoteException e) {
            }
        }
+15 −6
Original line number Diff line number Diff line
@@ -63,23 +63,32 @@ interface IBackupManager {
     * Identify the currently selected transport.  Callers must hold the
     * android.permission.BACKUP permission to use this method.
     */
    int getCurrentTransport();
    String getCurrentTransport();

    /**
     * Specify a default backup transport.  Callers must hold the
     * Request a list of all available backup transports' names.  Callers must
     * hold the android.permission.BACKUP permission to use this method.
     */
    String[] listAllTransports();

    /**
     * Specify the current backup transport.  Callers must hold the
     * android.permission.BACKUP permission to use this method.
     *
     * @param transportID The ID of the transport to select.  This should be one
     * @param transport The name of the transport to select.  This should be one
     * of {@link BackupManager.TRANSPORT_GOOGLE} or {@link BackupManager.TRANSPORT_ADB}.
     * @return The ID of the previously selected transport.
     * @return The name of the previously selected transport.  If the given transport
     *   name is not one of the currently available transports, no change is made to
     *   the current transport setting and the method returns null.
     */
    int selectBackupTransport(int transportID);
    String selectBackupTransport(String transport);

    /**
     * Begin a restore session with the given transport (which may differ from the
     * currently-active backup transport).
     *
     * @param transport The name of the transport to use for the restore operation.
     * @return An interface to the restore session, or null on error.
     */
    IRestoreSession beginRestoreSession(int transportID);
    IRestoreSession beginRestoreSession(String transportID);
}
+83 −35
Original line number Diff line number Diff line
@@ -42,13 +42,13 @@ import android.os.Message;
import android.os.ParcelFileDescriptor;
import android.os.Process;
import android.os.RemoteException;
import android.os.SystemProperties;
import android.util.Log;
import android.util.SparseArray;

import android.backup.IBackupManager;
import android.backup.IRestoreObserver;
import android.backup.IRestoreSession;
import android.backup.BackupManager;
import android.backup.RestoreSet;

import com.android.internal.backup.LocalTransport;
@@ -68,6 +68,7 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;

class BackupManagerService extends IBackupManager.Stub {
    private static final String TAG = "BackupManagerService";
@@ -79,7 +80,6 @@ class BackupManagerService extends IBackupManager.Stub {
    private static final int MSG_RUN_BACKUP = 1;
    private static final int MSG_RUN_FULL_BACKUP = 2;
    private static final int MSG_RUN_RESTORE = 3;
    private static final String RESTORE_OBSERVER_KEY = "_resOb";

    // Timeout interval for deciding that a bind or clear-data has taken too long
    static final long TIMEOUT_INTERVAL = 10 * 1000;
@@ -127,8 +127,11 @@ class BackupManagerService extends IBackupManager.Stub {
    private final Object mClearDataLock = new Object();
    private volatile boolean mClearingData;

    // Current active transport & restore session
    private int mTransportId;
    // Transport bookkeeping
    static private final String BACKUP_TRANSPORT_PROPERTY = "persist.service.bkup.trans";
    private final HashMap<String,IBackupTransport> mTransports
            = new HashMap<String,IBackupTransport>();
    private String mCurrentTransport;
    private IBackupTransport mLocalTransport, mGoogleTransport;
    private RestoreSession mActiveRestoreSession;

@@ -175,11 +178,19 @@ class BackupManagerService extends IBackupManager.Stub {
        // Set up our transport options and initialize the default transport
        // TODO: Have transports register themselves somehow?
        // TODO: Don't create transports that we don't need to?
        mTransportId = BackupManager.TRANSPORT_GOOGLE;
        mLocalTransport = new LocalTransport(context);  // This is actually pretty cheap
        mGoogleTransport = null;
        ComponentName localName = new ComponentName(context, LocalTransport.class);
        registerTransport(localName.flattenToShortString(), mLocalTransport);

        // Attach to the Google backup transport.
        mGoogleTransport = null;
        // !!! TODO: set up the default transport name "the right way"
        mCurrentTransport = SystemProperties.get(BACKUP_TRANSPORT_PROPERTY,
                "com.google.android.backup/.BackupTransportService");
        if (DEBUG) Log.v(TAG, "Starting with transport " + mCurrentTransport);

        // Attach to the Google backup transport.  When this comes up, it will set
        // itself as the current transport because we explicitly reset mCurrentTransport
        // to null.
        Intent intent = new Intent().setComponent(new ComponentName(
                "com.google.android.backup",
                "com.google.android.backup.BackupTransportService"));
@@ -238,6 +249,13 @@ class BackupManagerService extends IBackupManager.Stub {
        }
    }

    // Add a transport to our set of available backends
    private void registerTransport(String name, IBackupTransport transport) {
        synchronized (mTransports) {
            mTransports.put(name, transport);
        }
    }

    // ----- Track installation/removal of packages -----
    BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
        public void onReceive(Context context, Intent intent) {
@@ -283,11 +301,13 @@ class BackupManagerService extends IBackupManager.Stub {
        public void onServiceConnected(ComponentName name, IBinder service) {
            if (DEBUG) Log.v(TAG, "Connected to Google transport");
            mGoogleTransport = IBackupTransport.Stub.asInterface(service);
            registerTransport(name.flattenToShortString(), mGoogleTransport);
        }

        public void onServiceDisconnected(ComponentName name) {
            if (DEBUG) Log.v(TAG, "Disconnected from Google transport");
            mGoogleTransport = null;
            registerTransport(name.flattenToShortString(), null);
        }
    };

@@ -299,7 +319,7 @@ class BackupManagerService extends IBackupManager.Stub {
            switch (msg.what) {
            case MSG_RUN_BACKUP:
            {
                IBackupTransport transport = getTransport(mTransportId);
                IBackupTransport transport = getTransport(mCurrentTransport);
                if (transport == null) {
                    Log.v(TAG, "Backup requested but no transport available");
                    break;
@@ -474,19 +494,13 @@ class BackupManagerService extends IBackupManager.Stub {
    }

    // Return the given transport
    private IBackupTransport getTransport(int transportID) {
        switch (transportID) {
        case BackupManager.TRANSPORT_LOCAL:
            Log.v(TAG, "Supplying local transport");
            return mLocalTransport;

        case BackupManager.TRANSPORT_GOOGLE:
            Log.v(TAG, "Supplying Google transport");
            return mGoogleTransport;

        default:
            Log.e(TAG, "Asked for unknown transport " + transportID);
            return null;
    private IBackupTransport getTransport(String transportName) {
        synchronized (mTransports) {
            IBackupTransport transport = mTransports.get(transportName);
            if (transport == null) {
                Log.w(TAG, "Requested unavailable transport: " + transportName);
            }
            return transport;
        }
    }

@@ -1111,22 +1125,52 @@ class BackupManagerService extends IBackupManager.Stub {
        }
    }

    // Report the currently active transport
    public int getCurrentTransport() {
    // Report the name of the currently active transport
    public String getCurrentTransport() {
        mContext.enforceCallingPermission("android.permission.BACKUP", "selectBackupTransport");
        Log.v(TAG, "getCurrentTransport() returning " + mCurrentTransport);
        return mCurrentTransport;
    }

    // Report all known, available backup transports
    public String[] listAllTransports() {
        mContext.enforceCallingPermission("android.permission.BACKUP", "selectBackupTransport");
        Log.v(TAG, "getCurrentTransport() returning " + mTransportId);
        return mTransportId;

        String[] list = null;
        ArrayList<String> known = new ArrayList<String>();
        for (Map.Entry<String, IBackupTransport> entry : mTransports.entrySet()) {
            if (entry.getValue() != null) {
                known.add(entry.getKey());
            }
        }

        if (known.size() > 0) {
            list = new String[known.size()];
            known.toArray(list);
        }
        return list;
    }

    // Select which transport to use for the next backup operation
    public int selectBackupTransport(int transportId) {
    // Select which transport to use for the next backup operation.  If the given
    // name is not one of the available transports, no action is taken and the method
    // returns null.
    public String selectBackupTransport(String transport) {
        mContext.enforceCallingPermission("android.permission.BACKUP", "selectBackupTransport");

        int prevTransport = mTransportId;
        mTransportId = transportId;
        Log.v(TAG, "selectBackupTransport() set " + mTransportId + " returning " + prevTransport);
        synchronized (mTransports) {
            String prevTransport = null;
            if (mTransports.get(transport) != null) {
                prevTransport = mCurrentTransport;
                mCurrentTransport = transport;
                SystemProperties.set(BACKUP_TRANSPORT_PROPERTY, transport);
                Log.v(TAG, "selectBackupTransport() set " + mCurrentTransport
                        + " returning " + prevTransport);
            } else {
                Log.w(TAG, "Attempt to select unavailable transport " + transport);
            }
            return prevTransport;
        }
    }

    // Callback: a requested backup agent has been instantiated.  This should only
    // be called from the Activity Manager.
@@ -1163,7 +1207,7 @@ class BackupManagerService extends IBackupManager.Stub {
    }

    // Hand off a restore session
    public IRestoreSession beginRestoreSession(int transportID) {
    public IRestoreSession beginRestoreSession(String transport) {
        mContext.enforceCallingPermission("android.permission.BACKUP", "beginRestoreSession");

        synchronized(this) {
@@ -1171,7 +1215,7 @@ class BackupManagerService extends IBackupManager.Stub {
                Log.d(TAG, "Restore session requested but one already active");
                return null;
            }
            mActiveRestoreSession = new RestoreSession(transportID);
            mActiveRestoreSession = new RestoreSession(transport);
        }
        return mActiveRestoreSession;
    }
@@ -1184,8 +1228,8 @@ class BackupManagerService extends IBackupManager.Stub {
        private IBackupTransport mRestoreTransport = null;
        RestoreSet[] mRestoreSets = null;

        RestoreSession(int transportID) {
            mRestoreTransport = getTransport(transportID);
        RestoreSession(String transport) {
            mRestoreTransport = getTransport(transport);
        }

        // --- Binder interface ---
@@ -1246,6 +1290,10 @@ class BackupManagerService extends IBackupManager.Stub {
    @Override
    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
        synchronized (mQueueLock) {
            pw.println("Available transports:");
            for (String t : listAllTransports()) {
                pw.println("  " + t);
            }
            int N = mBackupParticipants.size();
            pw.println("Participants:");
            for (int i=0; i<N; i++) {