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

Commit fa51853a authored by Bernardo Rufino's avatar Bernardo Rufino
Browse files

Binding on-demand #8: Miscellaneous usages

Migrate usages of the transport binder to binding on-demand:
* getDestinationString()
* isAppEligibleForBackup()
* dump()

For getDestinationString() we'll be introducing an invisible bug for
people that haven't updated GMSCore to include the usage of
updateTransportAttributes() API introduced in earlier CL. The bug is
that that text won't change, it'll remain constant. It's invisible
because currently only place that uses that method is Settings in some
circumstances that depend on the transport, and those circunstances
don't happen with our transports. Check http://ag/1831025.

For isAppEligibleForBackup(), a new filterAppsEligibleForBackup() is
created and there we bind on-demand.

Change-Id: Idc9e31f0e8eda8531e204c05a84fafdaf0247d08
Ref: http://go/br-binding-on-demand
Bug: 17140907
Test: adb shell dumpsys backup, observe destination of transports
Test: adb shell bmgr backupnow --all, observe only eligible apps got backed-up
Test: Force-loaded settings screen and observed destination string
Test: m -j RunFrameworksServicesRoboTests
parent dc4cb146
Loading
Loading
Loading
Loading
+11 −12
Original line number Diff line number Diff line
@@ -23,8 +23,8 @@ import android.app.backup.IBackupManager;
import android.app.backup.IBackupObserver;
import android.app.backup.IRestoreObserver;
import android.app.backup.IRestoreSession;
import android.app.backup.RestoreSet;
import android.app.backup.ISelectBackupTransportCallback;
import android.app.backup.RestoreSet;
import android.content.ComponentName;
import android.content.pm.IPackageManager;
import android.content.pm.PackageInfo;
@@ -37,6 +37,7 @@ import android.util.ArraySet;
import com.android.internal.annotations.GuardedBy;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.concurrent.CountDownLatch;
@@ -339,18 +340,16 @@ public final class Bmgr {
            System.err.println(PM_NOT_RUNNING_ERR);
        }
        if (installedPackages != null) {
            List<String> packages = new ArrayList<>();
            for (PackageInfo pi : installedPackages) {
            String[] packages =
                    installedPackages.stream().map(p -> p.packageName).toArray(String[]::new);
            String[] filteredPackages = {};
            try {
                    if (mBmgr.isAppEligibleForBackup(pi.packageName)) {
                        packages.add(pi.packageName);
                    }
                filteredPackages = mBmgr.filterAppsEligibleForBackup(packages);
            } catch (RemoteException e) {
                System.err.println(e.toString());
                System.err.println(BMGR_NOT_RUNNING_ERR);
            }
            }
            backupNowPackages(packages, nonIncrementalBackup);
            backupNowPackages(Arrays.asList(filteredPackages), nonIncrementalBackup);
        }
    }

+13 −0
Original line number Diff line number Diff line
@@ -402,6 +402,9 @@ interface IBackupManager {
    /**
     * Ask the framework whether this app is eligible for backup.
     *
     * <p>If you are calling this method multiple times, you should instead use
     * {@link #filterAppsEligibleForBackup(String[])} to save resources.
     *
     * <p>Callers must hold the android.permission.BACKUP permission to use this method.
     *
     * @param packageName The name of the package.
@@ -409,6 +412,16 @@ interface IBackupManager {
     */
    boolean isAppEligibleForBackup(String packageName);

    /**
     * Filter the packages that are eligible for backup and return the result.
     *
     * <p>Callers must hold the android.permission.BACKUP permission to use this method.
     *
     * @param packages The list of packages to filter.
     * @return The packages eligible for backup.
     */
    String[] filterAppsEligibleForBackup(in String[] packages);

    /**
     * Request an immediate backup, providing an observer to which results of the backup operation
     * will be published. The Android backup system will decide for each package whether it will
+2 −0
Original line number Diff line number Diff line
@@ -186,6 +186,8 @@ public interface BackupManagerServiceInterface {

  boolean isAppEligibleForBackup(String packageName);

  String[] filterAppsEligibleForBackup(String[] packages);

  void dump(FileDescriptor fd, PrintWriter pw, String[] args);

  IBackupManager getBackupManagerBinder();
+55 −43
Original line number Diff line number Diff line
@@ -148,6 +148,7 @@ import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Random;
@@ -3093,30 +3094,31 @@ public class RefactoredBackupManagerService implements BackupManagerServiceInter
        }
    }

    // Supply the configuration summary string for the given transport.  If the name is
    // not one of the available transports, or if the transport does not supply any
    // summary / destination string, the method can return null.
    //
    // This string is used VERBATIM as the summary text of the relevant Settings item!
    /**
     * Supply the current destination string for the given transport. If the name is not one of the
     * registered transports the method will return null.
     *
     * <p>This string is used VERBATIM as the summary text of the relevant Settings item.
     *
     * @param transportName The name of the registered transport.
     * @return The current destination string or null if the transport is not registered.
     */
    @Override
    public String getDestinationString(String transportName) {
        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
                "getDestinationString");
        mContext.enforceCallingOrSelfPermission(
                android.Manifest.permission.BACKUP, "getDestinationString");

        final IBackupTransport transport = mTransportManager.getTransportBinder(transportName);
        if (transport != null) {
        try {
                final String text = transport.currentDestinationString();
                if (MORE_DEBUG) Slog.d(TAG, "getDestinationString() returning " + text);
                return text;
            } catch (Exception e) {
                /* fall through to return null */
                Slog.e(TAG, "Unable to get string from transport: " + e.getMessage());
            }
            String string = mTransportManager.getTransportCurrentDestinationString(transportName);
            if (MORE_DEBUG) {
                Slog.d(TAG, "getDestinationString() returning " + string);
            }

            return string;
        } catch (TransportNotRegisteredException e) {
            Slog.e(TAG, "Unable to get destination string from transport: " + e.getMessage());
            return null;
        }
    }

    // Supply the manage-data intent for the given transport.
    @Override
@@ -3385,31 +3387,41 @@ public class RefactoredBackupManagerService implements BackupManagerServiceInter

    @Override
    public boolean isAppEligibleForBackup(String packageName) {
        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
                "isAppEligibleForBackup");
        try {
            PackageInfo packageInfo = mPackageManager.getPackageInfo(packageName,
                    PackageManager.GET_SIGNATURES);
            if (!AppBackupUtils.appIsEligibleForBackup(packageInfo.applicationInfo,
                            mPackageManager) ||
                    AppBackupUtils.appIsStopped(packageInfo.applicationInfo) ||
                    AppBackupUtils.appIsDisabled(packageInfo.applicationInfo, mPackageManager)) {
                return false;
        mContext.enforceCallingOrSelfPermission(
                android.Manifest.permission.BACKUP, "isAppEligibleForBackup");

        String callerLogString = "BMS.isAppEligibleForBackup";
        TransportClient transportClient =
                mTransportManager.getCurrentTransportClient(callerLogString);
        boolean eligible =
                AppBackupUtils.appIsRunningAndEligibleForBackupWithTransport(
                        transportClient, packageName, mPackageManager);
        if (transportClient != null) {
            mTransportManager.disposeOfTransportClient(transportClient, callerLogString);
        }
            IBackupTransport transport = mTransportManager.getCurrentTransportBinder();
            if (transport != null) {
                try {
                    return transport.isAppEligibleForBackup(packageInfo,
                            AppBackupUtils.appGetsFullBackup(packageInfo));
                } catch (Exception e) {
                    Slog.e(TAG, "Unable to ask about eligibility: " + e.getMessage());
        return eligible;
    }

    @Override
    public String[] filterAppsEligibleForBackup(String[] packages) {
        mContext.enforceCallingOrSelfPermission(
                android.Manifest.permission.BACKUP, "filterAppsEligibleForBackup");

        String callerLogString = "BMS.filterAppsEligibleForBackup";
        TransportClient transportClient =
                mTransportManager.getCurrentTransportClient(callerLogString);
        List<String> eligibleApps = new LinkedList<>();
        for (String packageName : packages) {
            if (AppBackupUtils
                    .appIsRunningAndEligibleForBackupWithTransport(
                            transportClient, packageName, mPackageManager)) {
                eligibleApps.add(packageName);
            }
            // If transport is not present we couldn't tell that the package is not eligible.
            return true;
        } catch (NameNotFoundException e) {
            return false;
        }
        if (transportClient != null) {
            mTransportManager.disposeOfTransportClient(transportClient, callerLogString);
        }
        return eligibleApps.toArray(new String[eligibleApps.size()]);
    }

    @Override
@@ -3473,10 +3485,10 @@ public class RefactoredBackupManagerService implements BackupManagerServiceInter
                    pw.println((t.equals(mTransportManager.getCurrentTransportName()) ? "  * "
                            : "    ") + t);
                    try {
                        IBackupTransport transport = mTransportManager.getTransportBinder(t);
                        File dir = new File(mBaseStateDir,
                                mTransportManager.getTransportDirName(t));
                        pw.println("       destination: " + transport.currentDestinationString());
                        pw.println("       destination: "
                                + mTransportManager.getTransportCurrentDestinationString(t));
                        pw.println("       intent: "
                                + mTransportManager.getTransportConfigurationIntent(t));
                        for (File f : dir.listFiles()) {
+6 −0
Original line number Diff line number Diff line
@@ -451,6 +451,12 @@ public class Trampoline extends IBackupManager.Stub {
        return (svc != null) ? svc.isAppEligibleForBackup(packageName) : false;
    }

    @Override
    public String[] filterAppsEligibleForBackup(String[] packages) {
        BackupManagerServiceInterface svc = mService;
        return (svc != null) ? svc.filterAppsEligibleForBackup(packages) : null;
    }

    @Override
    public int requestBackup(String[] packages, IBackupObserver observer,
            IBackupManagerMonitor monitor, int flags) throws RemoteException {
Loading