1 /*
2  * Copyright (C) 2014 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.server.backup;
18 
19 import static java.util.Collections.emptySet;
20 
21 import android.Manifest;
22 import android.annotation.NonNull;
23 import android.annotation.Nullable;
24 import android.annotation.UserIdInt;
25 import android.app.ActivityManager;
26 import android.app.admin.DevicePolicyManager;
27 import android.app.backup.BackupManager;
28 import android.app.backup.BackupManager.OperationType;
29 import android.app.backup.IBackupManager;
30 import android.app.backup.IBackupManagerMonitor;
31 import android.app.backup.IBackupObserver;
32 import android.app.backup.IFullBackupRestoreObserver;
33 import android.app.backup.IRestoreSession;
34 import android.app.backup.ISelectBackupTransportCallback;
35 import android.app.compat.CompatChanges;
36 import android.app.job.JobParameters;
37 import android.app.job.JobScheduler;
38 import android.app.job.JobService;
39 import android.content.BroadcastReceiver;
40 import android.content.ComponentName;
41 import android.content.Context;
42 import android.content.Intent;
43 import android.content.IntentFilter;
44 import android.content.pm.PackageManager;
45 import android.os.Binder;
46 import android.os.FileUtils;
47 import android.os.Handler;
48 import android.os.HandlerThread;
49 import android.os.IBinder;
50 import android.os.ParcelFileDescriptor;
51 import android.os.Process;
52 import android.os.RemoteException;
53 import android.os.SystemProperties;
54 import android.os.Trace;
55 import android.os.UserHandle;
56 import android.os.UserManager;
57 import android.util.Slog;
58 import android.util.SparseArray;
59 
60 import com.android.internal.annotations.GuardedBy;
61 import com.android.internal.annotations.VisibleForTesting;
62 import com.android.internal.util.DumpUtils;
63 import com.android.server.SystemConfig;
64 import com.android.server.SystemService;
65 import com.android.server.backup.utils.RandomAccessFileUtils;
66 
67 import java.io.File;
68 import java.io.FileDescriptor;
69 import java.io.IOException;
70 import java.io.PrintWriter;
71 import java.util.List;
72 import java.util.Objects;
73 import java.util.Set;
74 
75 /**
76  * Definition of the system service that performs backup/restore operations.
77  *
78  * <p>This class is responsible for handling user-aware operations and acts as a delegator, routing
79  * incoming calls to the appropriate per-user {@link UserBackupManagerService} to handle the
80  * corresponding backup/restore operation.
81  *
82  * <p>It also determines whether the backup service is available. It can be disabled in the
83  * following two ways:
84  *
85  * <ul>
86  *  <li>Temporary - call {@link #setBackupServiceActive(int, boolean)}, or
87  *  <li>Permanent - set the system property {@link #BACKUP_DISABLE_PROPERTY} to true.
88  * </ul>
89  *
90  * Temporary disabling is controlled by {@link #setBackupServiceActive(int, boolean)} through
91  * privileged callers (currently {@link DevicePolicyManager}). If called on {@link
92  * UserHandle#USER_SYSTEM}, backup is disabled for all users.
93  */
94 public class BackupManagerService extends IBackupManager.Stub {
95     public static final String TAG = "BackupManagerService";
96     public static final boolean DEBUG = true;
97     public static final boolean MORE_DEBUG = false;
98     public static final boolean DEBUG_SCHEDULING = true;
99 
100     @VisibleForTesting
101     static final String DUMP_RUNNING_USERS_MESSAGE = "Backup Manager is running for users:";
102 
103     /**
104      * Name of file that disables the backup service. If this file exists, then backup is disabled
105      * for all users.
106      */
107     private static final String BACKUP_SUPPRESS_FILENAME = "backup-suppress";
108 
109     /**
110      * Name of file for non-system users that enables the backup service for the user. Backup is
111      * disabled by default in non-system users.
112      */
113     private static final String BACKUP_ACTIVATED_FILENAME = "backup-activated";
114 
115     /**
116      * Name of file for non-system users that remembers whether backup was explicitly activated or
117      * deactivated with a call to setBackupServiceActive.
118      */
119     private static final String REMEMBER_ACTIVATED_FILENAME = "backup-remember-activated";
120 
121     // Product-level suppression of backup/restore.
122     private static final String BACKUP_DISABLE_PROPERTY = "ro.backup.disable";
123 
124     private static final String BACKUP_THREAD = "backup";
125 
126     static BackupManagerService sInstance;
127 
getInstance()128     static BackupManagerService getInstance() {
129         return Objects.requireNonNull(sInstance);
130     }
131 
132     private final Context mContext;
133     private final UserManager mUserManager;
134 
135     private final boolean mGlobalDisable;
136     // Lock to write backup suppress files.
137     // TODD(b/121198006): remove this object and synchronized all methods on "this".
138     private final Object mStateLock = new Object();
139 
140     private final Handler mHandler;
141     private final Set<ComponentName> mTransportWhitelist;
142 
143     /** Keeps track of all unlocked users registered with this service. Indexed by user id. */
144     private final SparseArray<UserBackupManagerService> mUserServices;
145 
146     private final BroadcastReceiver mUserRemovedReceiver = new BroadcastReceiver() {
147         @Override
148         public void onReceive(Context context, Intent intent) {
149             if (Intent.ACTION_USER_REMOVED.equals(intent.getAction())) {
150                 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
151                 if (userId > 0) { // for only non system users
152                     mHandler.post(() -> onRemovedNonSystemUser(userId));
153                 }
154             }
155         }
156     };
157 
BackupManagerService(Context context)158     public BackupManagerService(Context context) {
159         this(context, new SparseArray<>());
160     }
161 
162     @VisibleForTesting
BackupManagerService(Context context, SparseArray<UserBackupManagerService> userServices)163     BackupManagerService(Context context, SparseArray<UserBackupManagerService> userServices) {
164         mContext = context;
165         mGlobalDisable = isBackupDisabled();
166         HandlerThread handlerThread =
167                 new HandlerThread(BACKUP_THREAD, Process.THREAD_PRIORITY_BACKGROUND);
168         handlerThread.start();
169         mHandler = new Handler(handlerThread.getLooper());
170         mUserManager = UserManager.get(context);
171         mUserServices = userServices;
172         Set<ComponentName> transportWhitelist =
173                 SystemConfig.getInstance().getBackupTransportWhitelist();
174         mTransportWhitelist = (transportWhitelist == null) ? emptySet() : transportWhitelist;
175         mContext.registerReceiver(
176                 mUserRemovedReceiver, new IntentFilter(Intent.ACTION_USER_REMOVED));
177     }
178 
179     // TODO: Remove this when we implement DI by injecting in the construtor.
180     @VisibleForTesting
getBackupHandler()181     Handler getBackupHandler() {
182         return mHandler;
183     }
184 
isBackupDisabled()185     protected boolean isBackupDisabled() {
186         return SystemProperties.getBoolean(BACKUP_DISABLE_PROPERTY, false);
187     }
188 
binderGetCallingUserId()189     protected int binderGetCallingUserId() {
190         return Binder.getCallingUserHandle().getIdentifier();
191     }
192 
binderGetCallingUid()193     protected int binderGetCallingUid() {
194         return Binder.getCallingUid();
195     }
196 
197     /** Stored in the system user's directory. */
getSuppressFileForSystemUser()198     protected File getSuppressFileForSystemUser() {
199         return new File(UserBackupManagerFiles.getBaseStateDir(UserHandle.USER_SYSTEM),
200                 BACKUP_SUPPRESS_FILENAME);
201     }
202 
203     /** Stored in the system user's directory and the file is indexed by the user it refers to. */
getRememberActivatedFileForNonSystemUser(int userId)204     protected File getRememberActivatedFileForNonSystemUser(int userId) {
205         return UserBackupManagerFiles.getStateFileInSystemDir(REMEMBER_ACTIVATED_FILENAME, userId);
206     }
207 
208     /** Stored in the system user's directory and the file is indexed by the user it refers to. */
getActivatedFileForNonSystemUser(int userId)209     protected File getActivatedFileForNonSystemUser(int userId) {
210         return UserBackupManagerFiles.getStateFileInSystemDir(BACKUP_ACTIVATED_FILENAME, userId);
211     }
212 
213     /**
214      * Remove backup state for non system {@code userId} when the user is removed from the device.
215      * For non system users, backup state is stored in both the user's own dir and the system dir.
216      * When the user is removed, the user's own dir gets removed by the OS. This method ensures that
217      * the part of the user backup state which is in the system dir also gets removed.
218      */
onRemovedNonSystemUser(int userId)219     private void onRemovedNonSystemUser(int userId) {
220         Slog.i(TAG, "Removing state for non system user " + userId);
221         File dir = UserBackupManagerFiles.getStateDirInSystemDir(userId);
222         if (!FileUtils.deleteContentsAndDir(dir)) {
223             Slog.w(TAG, "Failed to delete state dir for removed user: " + userId);
224         }
225     }
226 
227     // TODO (b/124359804) move to util method in FileUtils
createFile(File file)228     private void createFile(File file) throws IOException {
229         if (file.exists()) {
230             return;
231         }
232 
233         file.getParentFile().mkdirs();
234         if (!file.createNewFile()) {
235             Slog.w(TAG, "Failed to create file " + file.getPath());
236         }
237     }
238 
239     // TODO (b/124359804) move to util method in FileUtils
deleteFile(File file)240     private void deleteFile(File file) {
241         if (!file.exists()) {
242             return;
243         }
244 
245         if (!file.delete()) {
246             Slog.w(TAG, "Failed to delete file " + file.getPath());
247         }
248     }
249 
250     /**
251      * Deactivates the backup service for user {@code userId}. If this is the system user, it
252      * creates a suppress file which disables backup for all users. If this is a non-system user, it
253      * only deactivates backup for that user by deleting its activate file.
254      */
255     @GuardedBy("mStateLock")
deactivateBackupForUserLocked(int userId)256     private void deactivateBackupForUserLocked(int userId) throws IOException {
257         if (userId == UserHandle.USER_SYSTEM) {
258             createFile(getSuppressFileForSystemUser());
259         } else {
260             deleteFile(getActivatedFileForNonSystemUser(userId));
261         }
262     }
263 
264     /**
265      * Enables the backup service for user {@code userId}. If this is the system user, it deletes
266      * the suppress file. If this is a non-system user, it creates the user's activate file. Note,
267      * deleting the suppress file does not automatically enable backup for non-system users, they
268      * need their own activate file in order to participate in the service.
269      */
270     @GuardedBy("mStateLock")
activateBackupForUserLocked(int userId)271     private void activateBackupForUserLocked(int userId) throws IOException {
272         if (userId == UserHandle.USER_SYSTEM) {
273             deleteFile(getSuppressFileForSystemUser());
274         } else {
275             createFile(getActivatedFileForNonSystemUser(userId));
276         }
277     }
278 
279     /**
280      * This method should not perform any I/O (e.g. do not call isBackupActivatedForUser),
281      * it's used in multiple places where I/O waits would cause system lock-ups.
282      * @param userId User id for which this operation should be performed.
283      * @return true if the user is ready for backup and false otherwise.
284      */
285     @Override
isUserReadyForBackup(int userId)286     public boolean isUserReadyForBackup(int userId) {
287         return mUserServices.get(UserHandle.USER_SYSTEM) != null
288                 && mUserServices.get(userId) != null;
289     }
290 
291     /**
292      * Backup is activated for the system user if the suppress file does not exist. Backup is
293      * activated for non-system users if the suppress file does not exist AND the user's activated
294      * file exists.
295      */
isBackupActivatedForUser(int userId)296     private boolean isBackupActivatedForUser(int userId) {
297         if (getSuppressFileForSystemUser().exists()) {
298             return false;
299         }
300 
301         return userId == UserHandle.USER_SYSTEM
302                 || getActivatedFileForNonSystemUser(userId).exists();
303     }
304 
getContext()305     protected Context getContext() {
306         return mContext;
307     }
308 
getUserManager()309     protected UserManager getUserManager() {
310         return mUserManager;
311     }
312 
postToHandler(Runnable runnable)313     protected void postToHandler(Runnable runnable) {
314         mHandler.post(runnable);
315     }
316 
317     /**
318      * Called from {@link BackupManagerService.Lifecycle} when a user {@code userId} is unlocked.
319      * Starts the backup service for this user if backup is active for this user. Offloads work onto
320      * the handler thread {@link #mHandlerThread} to keep unlock time low since backup is not
321      * essential for device functioning.
322      */
onUnlockUser(int userId)323     void onUnlockUser(int userId) {
324         postToHandler(() -> startServiceForUser(userId));
325     }
326 
327     /**
328      * Starts the backup service for user {@code userId} by creating a new instance of {@link
329      * UserBackupManagerService} and registering it with this service.
330      */
331     @VisibleForTesting
startServiceForUser(int userId)332     void startServiceForUser(int userId) {
333         // We know that the user is unlocked here because it is called from setBackupServiceActive
334         // and unlockUser which have these guarantees. So we can check if the file exists.
335         if (mGlobalDisable) {
336             Slog.i(TAG, "Backup service not supported");
337             return;
338         }
339         if (!isBackupActivatedForUser(userId)) {
340             Slog.i(TAG, "Backup not activated for user " + userId);
341             return;
342         }
343         if (mUserServices.get(userId) != null) {
344             Slog.i(TAG, "userId " + userId + " already started, so not starting again");
345             return;
346         }
347         Slog.i(TAG, "Starting service for user: " + userId);
348         UserBackupManagerService userBackupManagerService =
349                 UserBackupManagerService.createAndInitializeService(
350                         userId, mContext, this, mTransportWhitelist);
351         startServiceForUser(userId, userBackupManagerService);
352     }
353 
354     /**
355      * Starts the backup service for user {@code userId} by registering its instance of {@link
356      * UserBackupManagerService} with this service and setting enabled state.
357      */
startServiceForUser(int userId, UserBackupManagerService userBackupManagerService)358     void startServiceForUser(int userId, UserBackupManagerService userBackupManagerService) {
359         mUserServices.put(userId, userBackupManagerService);
360 
361         Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "backup enable");
362         userBackupManagerService.initializeBackupEnableState();
363         Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
364     }
365 
366     /** Stops the backup service for user {@code userId} when the user is stopped. */
367     @VisibleForTesting
stopServiceForUser(int userId)368     protected void stopServiceForUser(int userId) {
369         UserBackupManagerService userBackupManagerService = mUserServices.removeReturnOld(userId);
370 
371         if (userBackupManagerService != null) {
372             userBackupManagerService.tearDownService();
373 
374             KeyValueBackupJob.cancel(userId, mContext);
375             FullBackupJob.cancel(userId, mContext);
376         }
377     }
378 
379     /**
380      *  Returns a list of users currently unlocked that have a {@link UserBackupManagerService}
381      *  registered.
382      *
383      *  Warning: Do NOT modify returned object as it's used inside.
384      *
385      *  TODO: Return a copy or only expose read-only information through other means.
386      */
387     @VisibleForTesting
getUserServices()388     SparseArray<UserBackupManagerService> getUserServices() {
389         return mUserServices;
390     }
391 
392     /**
393      * Called from {@link BackupManagerService.Lifecycle} when a user {@code userId} is stopped.
394      * Offloads work onto the handler thread {@link #mHandlerThread} to keep stopping time low.
395      */
onStopUser(int userId)396     void onStopUser(int userId) {
397         postToHandler(
398                 () -> {
399                     if (!mGlobalDisable) {
400                         Slog.i(TAG, "Stopping service for user: " + userId);
401                         stopServiceForUser(userId);
402                     }
403                 });
404     }
405 
406     /** Returns {@link UserBackupManagerService} for user {@code userId}. */
407     @Nullable
getUserService(int userId)408     public UserBackupManagerService getUserService(int userId) {
409         return mUserServices.get(userId);
410     }
411 
412     /**
413      * The system user and managed profiles can only be acted on by callers in the system or root
414      * processes. Other users can be acted on by callers who have both android.permission.BACKUP and
415      * android.permission.INTERACT_ACROSS_USERS_FULL permissions.
416      */
enforcePermissionsOnUser(int userId)417     private void enforcePermissionsOnUser(int userId) throws SecurityException {
418         boolean isRestrictedUser =
419                 userId == UserHandle.USER_SYSTEM
420                         || getUserManager().getUserInfo(userId).isManagedProfile();
421 
422         if (isRestrictedUser) {
423             int caller = binderGetCallingUid();
424             if (caller != Process.SYSTEM_UID && caller != Process.ROOT_UID) {
425                 throw new SecurityException("No permission to configure backup activity");
426             }
427         } else {
428             mContext.enforceCallingOrSelfPermission(
429                     Manifest.permission.BACKUP, "No permission to configure backup activity");
430             mContext.enforceCallingOrSelfPermission(
431                     Manifest.permission.INTERACT_ACROSS_USERS_FULL,
432                     "No permission to configure backup activity");
433         }
434     }
435 
436     /**
437      * Only privileged callers should be changing the backup state. Deactivating backup in the
438      * system user also deactivates backup in all users. We are not guaranteed that {@code userId}
439      * is unlocked at this point yet, so handle both cases.
440      */
setBackupServiceActive(int userId, boolean makeActive)441     public void setBackupServiceActive(int userId, boolean makeActive) {
442         enforcePermissionsOnUser(userId);
443 
444         // In Q, backup is OFF by default for non-system users. In the future, we will change that
445         // to ON unless backup was explicitly deactivated with a (permissioned) call to
446         // setBackupServiceActive.
447         // Therefore, remember this for use in the future. Basically the default in the future will
448         // be: rememberFile.exists() ? rememberFile.value() : ON
449         // Note that this has to be done right after the permission checks and before any other
450         // action since we need to remember that a permissioned call was made irrespective of
451         // whether the call changes the state or not.
452         if (userId != UserHandle.USER_SYSTEM) {
453             try {
454                 File rememberFile = getRememberActivatedFileForNonSystemUser(userId);
455                 createFile(rememberFile);
456                 RandomAccessFileUtils.writeBoolean(rememberFile, makeActive);
457             } catch (IOException e) {
458                 Slog.e(TAG, "Unable to persist backup service activity", e);
459             }
460         }
461 
462         if (mGlobalDisable) {
463             Slog.i(TAG, "Backup service not supported");
464             return;
465         }
466 
467         synchronized (mStateLock) {
468             Slog.i(TAG, "Making backup " + (makeActive ? "" : "in") + "active");
469             if (makeActive) {
470                 try {
471                     activateBackupForUserLocked(userId);
472                 } catch (IOException e) {
473                     Slog.e(TAG, "Unable to persist backup service activity");
474                 }
475 
476                 // If the user is unlocked, we can start the backup service for it. Otherwise we
477                 // will start the service when the user is unlocked as part of its unlock callback.
478                 if (getUserManager().isUserUnlocked(userId)) {
479                     // Clear calling identity as initialization enforces the system identity but we
480                     // can be coming from shell.
481                     final long oldId = Binder.clearCallingIdentity();
482                     try {
483                         startServiceForUser(userId);
484                     } finally {
485                         Binder.restoreCallingIdentity(oldId);
486                     }
487                 }
488             } else {
489                 try {
490                     //TODO(b/121198006): what if this throws an exception?
491                     deactivateBackupForUserLocked(userId);
492                 } catch (IOException e) {
493                     Slog.e(TAG, "Unable to persist backup service inactivity");
494                 }
495                 //TODO(b/121198006): loop through active users that have work profile and
496                 // stop them as well.
497                 onStopUser(userId);
498             }
499         }
500     }
501 
502     // IBackupManager binder API
503 
504     /**
505      * Querying activity state of backup service.
506      *
507      * @param userId The user in which the activity state of backup service is queried.
508      * @return true if the service is active.
509      */
510     @Override
isBackupServiceActive(int userId)511     public boolean isBackupServiceActive(int userId) {
512         int callingUid = Binder.getCallingUid();
513         if (CompatChanges.isChangeEnabled(
514                 BackupManager.IS_BACKUP_SERVICE_ACTIVE_ENFORCE_PERMISSION_IN_SERVICE, callingUid)) {
515             mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
516                     "isBackupServiceActive");
517         }
518         synchronized (mStateLock) {
519             return !mGlobalDisable && isBackupActivatedForUser(userId);
520         }
521     }
522 
523     @Override
dataChangedForUser(int userId, String packageName)524     public void dataChangedForUser(int userId, String packageName) throws RemoteException {
525         if (isUserReadyForBackup(userId)) {
526             dataChanged(userId, packageName);
527         }
528     }
529 
530     @Override
dataChanged(String packageName)531     public void dataChanged(String packageName) throws RemoteException {
532         dataChangedForUser(binderGetCallingUserId(), packageName);
533     }
534 
535     /**
536      * An app's backup agent calls this method to let the service know that there's new data to
537      * backup for their app {@code packageName}. Only used for apps participating in key-value
538      * backup.
539      */
dataChanged(@serIdInt int userId, String packageName)540     public void dataChanged(@UserIdInt int userId, String packageName) {
541         UserBackupManagerService userBackupManagerService =
542                 getServiceForUserIfCallerHasPermission(userId, "dataChanged()");
543 
544         if (userBackupManagerService != null) {
545             userBackupManagerService.dataChanged(packageName);
546         }
547     }
548 
549     // ---------------------------------------------
550     // TRANSPORT OPERATIONS
551     // ---------------------------------------------
552 
553     @Override
initializeTransportsForUser( int userId, String[] transportNames, IBackupObserver observer)554     public void initializeTransportsForUser(
555             int userId, String[] transportNames, IBackupObserver observer) throws RemoteException {
556         if (isUserReadyForBackup(userId)) {
557             initializeTransports(userId, transportNames, observer);
558         }
559     }
560 
561     /** Run an initialize operation for the given transports {@code transportNames}. */
initializeTransports( @serIdInt int userId, String[] transportNames, IBackupObserver observer)562     public void initializeTransports(
563             @UserIdInt int userId, String[] transportNames, IBackupObserver observer) {
564         UserBackupManagerService userBackupManagerService =
565                 getServiceForUserIfCallerHasPermission(userId, "initializeTransports()");
566 
567         if (userBackupManagerService != null) {
568             userBackupManagerService.initializeTransports(transportNames, observer);
569         }
570     }
571 
572     @Override
clearBackupDataForUser(int userId, String transportName, String packageName)573     public void clearBackupDataForUser(int userId, String transportName, String packageName)
574             throws RemoteException {
575         if (isUserReadyForBackup(userId)) {
576             clearBackupData(userId, transportName, packageName);
577         }
578     }
579 
580     /**
581      * Clear the given package {@code packageName}'s backup data from the transport {@code
582      * transportName}.
583      */
clearBackupData(@serIdInt int userId, String transportName, String packageName)584     public void clearBackupData(@UserIdInt int userId, String transportName, String packageName) {
585         UserBackupManagerService userBackupManagerService =
586                 getServiceForUserIfCallerHasPermission(userId, "clearBackupData()");
587 
588         if (userBackupManagerService != null) {
589             userBackupManagerService.clearBackupData(transportName, packageName);
590         }
591     }
592 
593     @Override
clearBackupData(String transportName, String packageName)594     public void clearBackupData(String transportName, String packageName)
595             throws RemoteException {
596         clearBackupDataForUser(binderGetCallingUserId(), transportName, packageName);
597     }
598 
599     @Override
agentConnectedForUser(int userId, String packageName, IBinder agent)600     public void agentConnectedForUser(int userId, String packageName, IBinder agent)
601             throws RemoteException {
602         if (isUserReadyForBackup(userId)) {
603             agentConnected(userId, packageName, agent);
604         }
605     }
606 
607     @Override
agentConnected(String packageName, IBinder agent)608     public void agentConnected(String packageName, IBinder agent) throws RemoteException {
609         agentConnectedForUser(binderGetCallingUserId(), packageName, agent);
610     }
611 
612     /**
613      * Callback: a requested backup agent has been instantiated. This should only be called from the
614      * {@link ActivityManager}.
615      */
agentConnected(@serIdInt int userId, String packageName, IBinder agentBinder)616     public void agentConnected(@UserIdInt int userId, String packageName, IBinder agentBinder) {
617         UserBackupManagerService userBackupManagerService =
618                 getServiceForUserIfCallerHasPermission(userId, "agentConnected()");
619 
620         if (userBackupManagerService != null) {
621             userBackupManagerService.agentConnected(packageName, agentBinder);
622         }
623     }
624 
625     @Override
agentDisconnectedForUser(int userId, String packageName)626     public void agentDisconnectedForUser(int userId, String packageName) throws RemoteException {
627         if (isUserReadyForBackup(userId)) {
628             agentDisconnected(userId, packageName);
629         }
630     }
631 
632     @Override
agentDisconnected(String packageName)633     public void agentDisconnected(String packageName) throws RemoteException {
634         agentDisconnectedForUser(binderGetCallingUserId(), packageName);
635     }
636 
637     /**
638      * Callback: a backup agent has failed to come up, or has unexpectedly quit. This should only be
639      * called from the {@link ActivityManager}.
640      */
agentDisconnected(@serIdInt int userId, String packageName)641     public void agentDisconnected(@UserIdInt int userId, String packageName) {
642         UserBackupManagerService userBackupManagerService =
643                 getServiceForUserIfCallerHasPermission(userId, "agentDisconnected()");
644 
645         if (userBackupManagerService != null) {
646             userBackupManagerService.agentDisconnected(packageName);
647         }
648     }
649 
650     @Override
restoreAtInstallForUser(int userId, String packageName, int token)651     public void restoreAtInstallForUser(int userId, String packageName, int token)
652             throws RemoteException {
653         if (isUserReadyForBackup(userId)) {
654             restoreAtInstall(userId, packageName, token);
655         }
656     }
657 
658     @Override
restoreAtInstall(String packageName, int token)659     public void restoreAtInstall(String packageName, int token) throws RemoteException {
660         restoreAtInstallForUser(binderGetCallingUserId(), packageName, token);
661     }
662 
663     /**
664      * Used to run a restore pass for an application that is being installed. This should only be
665      * called from the {@link PackageManager}.
666      */
restoreAtInstall(@serIdInt int userId, String packageName, int token)667     public void restoreAtInstall(@UserIdInt int userId, String packageName, int token) {
668         UserBackupManagerService userBackupManagerService =
669                 getServiceForUserIfCallerHasPermission(userId, "restoreAtInstall()");
670 
671         if (userBackupManagerService != null) {
672             userBackupManagerService.restoreAtInstall(packageName, token);
673         }
674     }
675 
676     @Override
setBackupEnabledForUser(@serIdInt int userId, boolean isEnabled)677     public void setBackupEnabledForUser(@UserIdInt int userId, boolean isEnabled)
678             throws RemoteException {
679         if (isUserReadyForBackup(userId)) {
680             setBackupEnabled(userId, isEnabled);
681         }
682     }
683 
684     @Override
setBackupEnabled(boolean isEnabled)685     public void setBackupEnabled(boolean isEnabled) throws RemoteException {
686         setBackupEnabledForUser(binderGetCallingUserId(), isEnabled);
687     }
688 
689     /** Enable/disable the backup service. This is user-configurable via backup settings. */
setBackupEnabled(@serIdInt int userId, boolean enable)690     public void setBackupEnabled(@UserIdInt int userId, boolean enable) {
691         UserBackupManagerService userBackupManagerService =
692                 getServiceForUserIfCallerHasPermission(userId, "setBackupEnabled()");
693 
694         if (userBackupManagerService != null) {
695             userBackupManagerService.setBackupEnabled(enable);
696         }
697     }
698 
699     @Override
setAutoRestoreForUser(int userId, boolean doAutoRestore)700     public void setAutoRestoreForUser(int userId, boolean doAutoRestore) throws RemoteException {
701         if (isUserReadyForBackup(userId)) {
702             setAutoRestore(userId, doAutoRestore);
703         }
704     }
705 
706     @Override
setAutoRestore(boolean doAutoRestore)707     public void setAutoRestore(boolean doAutoRestore) throws RemoteException {
708         setAutoRestoreForUser(binderGetCallingUserId(), doAutoRestore);
709     }
710 
711     /** Enable/disable automatic restore of app data at install time. */
setAutoRestore(@serIdInt int userId, boolean autoRestore)712     public void setAutoRestore(@UserIdInt int userId, boolean autoRestore) {
713         UserBackupManagerService userBackupManagerService =
714                 getServiceForUserIfCallerHasPermission(userId, "setAutoRestore()");
715 
716         if (userBackupManagerService != null) {
717             userBackupManagerService.setAutoRestore(autoRestore);
718         }
719     }
720 
721     @Override
isBackupEnabledForUser(@serIdInt int userId)722     public boolean isBackupEnabledForUser(@UserIdInt int userId) throws RemoteException {
723         return isUserReadyForBackup(userId) && isBackupEnabled(userId);
724     }
725 
726     @Override
isBackupEnabled()727     public boolean isBackupEnabled() throws RemoteException {
728         return isBackupEnabledForUser(binderGetCallingUserId());
729     }
730 
731     /**
732      * Return {@code true} if the backup mechanism is currently enabled, else returns {@code false}.
733      */
isBackupEnabled(@serIdInt int userId)734     public boolean isBackupEnabled(@UserIdInt int userId) {
735         UserBackupManagerService userBackupManagerService =
736                 getServiceForUserIfCallerHasPermission(userId, "isBackupEnabled()");
737 
738         return userBackupManagerService != null && userBackupManagerService.isBackupEnabled();
739     }
740 
741     /** Sets the backup password used when running adb backup. */
742     @Override
setBackupPassword(String currentPassword, String newPassword)743     public boolean setBackupPassword(String currentPassword, String newPassword) {
744         int userId = binderGetCallingUserId();
745         if (!isUserReadyForBackup(userId)) {
746             return false;
747         }
748         UserBackupManagerService userBackupManagerService =
749                 getServiceForUserIfCallerHasPermission(
750                         UserHandle.USER_SYSTEM, "setBackupPassword()");
751 
752         return userBackupManagerService != null
753                 && userBackupManagerService.setBackupPassword(currentPassword, newPassword);
754     }
755 
756     /** Returns {@code true} if adb backup was run with a password, else returns {@code false}. */
757     @Override
hasBackupPassword()758     public boolean hasBackupPassword() throws RemoteException {
759         int userId = binderGetCallingUserId();
760         if (!isUserReadyForBackup(userId)) {
761             return false;
762         }
763         UserBackupManagerService userBackupManagerService =
764                 getServiceForUserIfCallerHasPermission(
765                         UserHandle.USER_SYSTEM, "hasBackupPassword()");
766 
767         return userBackupManagerService != null && userBackupManagerService.hasBackupPassword();
768     }
769 
770     @Override
backupNowForUser(@serIdInt int userId)771     public void backupNowForUser(@UserIdInt int userId) throws RemoteException {
772         if (isUserReadyForBackup(userId)) {
773             backupNow(userId);
774         }
775     }
776 
777     @Override
backupNow()778     public void backupNow() throws RemoteException {
779         backupNowForUser(binderGetCallingUserId());
780     }
781 
782     /**
783      * Run a backup pass immediately for any key-value backup applications that have declared that
784      * they have pending updates.
785      */
backupNow(@serIdInt int userId)786     public void backupNow(@UserIdInt int userId) {
787         UserBackupManagerService userBackupManagerService =
788                 getServiceForUserIfCallerHasPermission(userId, "backupNow()");
789 
790         if (userBackupManagerService != null) {
791             userBackupManagerService.backupNow();
792         }
793     }
794 
795     /**
796      * Used by 'adb backup' to run a backup pass for packages {@code packageNames} supplied via the
797      * command line, writing the resulting data stream to the supplied {@code fd}. This method is
798      * synchronous and does not return to the caller until the backup has been completed. It
799      * requires on-screen confirmation by the user.
800      */
801     @Override
adbBackup( @serIdInt int userId, ParcelFileDescriptor fd, boolean includeApks, boolean includeObbs, boolean includeShared, boolean doWidgets, boolean doAllApps, boolean includeSystem, boolean doCompress, boolean doKeyValue, String[] packageNames)802     public void adbBackup(
803             @UserIdInt int userId,
804             ParcelFileDescriptor fd,
805             boolean includeApks,
806             boolean includeObbs,
807             boolean includeShared,
808             boolean doWidgets,
809             boolean doAllApps,
810             boolean includeSystem,
811             boolean doCompress,
812             boolean doKeyValue,
813             String[] packageNames) {
814         if (!isUserReadyForBackup(userId)) {
815             return;
816         }
817         UserBackupManagerService userBackupManagerService =
818                 getServiceForUserIfCallerHasPermission(userId, "adbBackup()");
819 
820         if (userBackupManagerService != null) {
821             userBackupManagerService.adbBackup(
822                     fd,
823                     includeApks,
824                     includeObbs,
825                     includeShared,
826                     doWidgets,
827                     doAllApps,
828                     includeSystem,
829                     doCompress,
830                     doKeyValue,
831                     packageNames);
832         }
833     }
834 
835     @Override
fullTransportBackupForUser(int userId, String[] packageNames)836     public void fullTransportBackupForUser(int userId, String[] packageNames)
837             throws RemoteException {
838         if (isUserReadyForBackup(userId)) {
839             fullTransportBackup(userId, packageNames);
840         }
841     }
842 
843     /**
844      * Run a full backup pass for the given packages {@code packageNames}. Used by 'adb shell bmgr'.
845      */
fullTransportBackup(@serIdInt int userId, String[] packageNames)846     public void fullTransportBackup(@UserIdInt int userId, String[] packageNames) {
847         UserBackupManagerService userBackupManagerService =
848                 getServiceForUserIfCallerHasPermission(userId, "fullTransportBackup()");
849 
850         if (userBackupManagerService != null) {
851             userBackupManagerService.fullTransportBackup(packageNames);
852         }
853     }
854 
855     /**
856      * Used by 'adb restore' to run a restore pass reading from the supplied {@code fd}. This method
857      * is synchronous and does not return to the caller until the restore has been completed. It
858      * requires on-screen confirmation by the user.
859      */
860     @Override
adbRestore(@serIdInt int userId, ParcelFileDescriptor fd)861     public void adbRestore(@UserIdInt int userId, ParcelFileDescriptor fd) {
862         if (!isUserReadyForBackup(userId)) {
863             return;
864         }
865         UserBackupManagerService userBackupManagerService =
866                 getServiceForUserIfCallerHasPermission(userId, "adbRestore()");
867 
868         if (userBackupManagerService != null) {
869             userBackupManagerService.adbRestore(fd);
870         }
871     }
872 
873     @Override
acknowledgeFullBackupOrRestoreForUser( int userId, int token, boolean allow, String curPassword, String encryptionPassword, IFullBackupRestoreObserver observer)874     public void acknowledgeFullBackupOrRestoreForUser(
875             int userId,
876             int token,
877             boolean allow,
878             String curPassword,
879             String encryptionPassword,
880             IFullBackupRestoreObserver observer)
881             throws RemoteException {
882         if (isUserReadyForBackup(userId)) {
883             acknowledgeAdbBackupOrRestore(userId, token, allow,
884                     curPassword, encryptionPassword, observer);
885         }
886     }
887 
888     /**
889      * Confirm that the previously requested adb backup/restore operation can proceed. This is used
890      * to require a user-facing disclosure about the operation.
891      */
acknowledgeAdbBackupOrRestore( @serIdInt int userId, int token, boolean allow, String currentPassword, String encryptionPassword, IFullBackupRestoreObserver observer)892     public void acknowledgeAdbBackupOrRestore(
893             @UserIdInt int userId,
894             int token,
895             boolean allow,
896             String currentPassword,
897             String encryptionPassword,
898             IFullBackupRestoreObserver observer) {
899         UserBackupManagerService userBackupManagerService =
900                 getServiceForUserIfCallerHasPermission(userId, "acknowledgeAdbBackupOrRestore()");
901 
902         if (userBackupManagerService != null) {
903             userBackupManagerService.acknowledgeAdbBackupOrRestore(
904                     token, allow, currentPassword, encryptionPassword, observer);
905         }
906     }
907 
908     @Override
acknowledgeFullBackupOrRestore(int token, boolean allow, String curPassword, String encryptionPassword, IFullBackupRestoreObserver observer)909     public void acknowledgeFullBackupOrRestore(int token, boolean allow, String curPassword,
910             String encryptionPassword, IFullBackupRestoreObserver observer)
911             throws RemoteException {
912         acknowledgeFullBackupOrRestoreForUser(
913                 binderGetCallingUserId(), token, allow, curPassword, encryptionPassword, observer);
914     }
915 
916 
917     @Override
getCurrentTransportForUser(int userId)918     public String getCurrentTransportForUser(int userId) throws RemoteException {
919         return (isUserReadyForBackup(userId)) ? getCurrentTransport(userId) : null;
920     }
921 
922     @Override
getCurrentTransport()923     public String getCurrentTransport() throws RemoteException {
924         return getCurrentTransportForUser(binderGetCallingUserId());
925     }
926 
927     /** Return the name of the currently active transport. */
928     @Nullable
getCurrentTransport(@serIdInt int userId)929     public String getCurrentTransport(@UserIdInt int userId) {
930         UserBackupManagerService userBackupManagerService =
931                 getServiceForUserIfCallerHasPermission(userId, "getCurrentTransport()");
932 
933         return userBackupManagerService == null
934                 ? null
935                 : userBackupManagerService.getCurrentTransport();
936     }
937 
938     /**
939      * Returns the {@link ComponentName} of the host service of the selected transport or
940      * {@code null} if no transport selected or if the transport selected is not registered.
941      */
942     @Override
943     @Nullable
getCurrentTransportComponentForUser(int userId)944     public ComponentName getCurrentTransportComponentForUser(int userId) {
945         return (isUserReadyForBackup(userId)) ? getCurrentTransportComponent(userId) : null;
946     }
947 
948     /**
949      * Returns the {@link ComponentName} of the host service of the selected transport or {@code
950      * null} if no transport selected or if the transport selected is not registered.
951      */
952     @Nullable
getCurrentTransportComponent(@serIdInt int userId)953     public ComponentName getCurrentTransportComponent(@UserIdInt int userId) {
954         UserBackupManagerService userBackupManagerService =
955                 getServiceForUserIfCallerHasPermission(userId, "getCurrentTransportComponent()");
956 
957         return userBackupManagerService == null
958                 ? null
959                 : userBackupManagerService.getCurrentTransportComponent();
960     }
961 
962     @Override
listAllTransportsForUser(int userId)963     public String[] listAllTransportsForUser(int userId) throws RemoteException {
964         return (isUserReadyForBackup(userId)) ? listAllTransports(userId) : null;
965     }
966 
967     /** Report all known, available backup transports by name. */
968     @Nullable
listAllTransports(@serIdInt int userId)969     public String[] listAllTransports(@UserIdInt int userId) {
970         UserBackupManagerService userBackupManagerService =
971                 getServiceForUserIfCallerHasPermission(userId, "listAllTransports()");
972 
973         return userBackupManagerService == null
974                 ? null
975                 : userBackupManagerService.listAllTransports();
976     }
977 
978     @Override
listAllTransports()979     public String[] listAllTransports() throws RemoteException {
980         return listAllTransportsForUser(binderGetCallingUserId());
981     }
982 
983     @Override
listAllTransportComponentsForUser(int userId)984     public ComponentName[] listAllTransportComponentsForUser(int userId) throws RemoteException {
985         return (isUserReadyForBackup(userId))
986                 ? listAllTransportComponents(userId) : null;
987     }
988 
989     /** Report all known, available backup transports by {@link ComponentName}. */
990     @Nullable
listAllTransportComponents(@serIdInt int userId)991     public ComponentName[] listAllTransportComponents(@UserIdInt int userId) {
992         UserBackupManagerService userBackupManagerService =
993                 getServiceForUserIfCallerHasPermission(userId, "listAllTransportComponents()");
994 
995         return userBackupManagerService == null
996                 ? null
997                 : userBackupManagerService.listAllTransportComponents();
998     }
999 
1000     @Override
getTransportWhitelist()1001     public String[] getTransportWhitelist() {
1002         int userId = binderGetCallingUserId();
1003         if (!isUserReadyForBackup(userId)) {
1004             return null;
1005         }
1006         // No permission check, intentionally.
1007         String[] whitelistedTransports = new String[mTransportWhitelist.size()];
1008         int i = 0;
1009         for (ComponentName component : mTransportWhitelist) {
1010             whitelistedTransports[i] = component.flattenToShortString();
1011             i++;
1012         }
1013         return whitelistedTransports;
1014     }
1015 
1016     @Override
updateTransportAttributesForUser( int userId, ComponentName transportComponent, String name, @Nullable Intent configurationIntent, String currentDestinationString, @Nullable Intent dataManagementIntent, CharSequence dataManagementLabel)1017     public void updateTransportAttributesForUser(
1018             int userId,
1019             ComponentName transportComponent,
1020             String name,
1021             @Nullable Intent configurationIntent,
1022             String currentDestinationString,
1023             @Nullable Intent dataManagementIntent,
1024             CharSequence dataManagementLabel) {
1025         if (isUserReadyForBackup(userId)) {
1026             updateTransportAttributes(
1027                     userId,
1028                     transportComponent,
1029                     name,
1030                     configurationIntent,
1031                     currentDestinationString,
1032                     dataManagementIntent,
1033                     dataManagementLabel);
1034         }
1035     }
1036 
1037     /**
1038      * Update the attributes of the transport identified by {@code transportComponent}. If the
1039      * specified transport has not been bound at least once (for registration), this call will be
1040      * ignored. Only the host process of the transport can change its description, otherwise a
1041      * {@link SecurityException} will be thrown.
1042      *
1043      * @param transportComponent The identity of the transport being described.
1044      * @param name A {@link String} with the new name for the transport. This is NOT for
1045      *     identification. MUST NOT be {@code null}.
1046      * @param configurationIntent An {@link Intent} that can be passed to {@link
1047      *     Context#startActivity} in order to launch the transport's configuration UI. It may be
1048      *     {@code null} if the transport does not offer any user-facing configuration UI.
1049      * @param currentDestinationString A {@link String} describing the destination to which the
1050      *     transport is currently sending data. MUST NOT be {@code null}.
1051      * @param dataManagementIntent An {@link Intent} that can be passed to {@link
1052      *     Context#startActivity} in order to launch the transport's data-management UI. It may be
1053      *     {@code null} if the transport does not offer any user-facing data management UI.
1054      * @param dataManagementLabel A {@link CharSequence} to be used as the label for the transport's
1055      *     data management affordance. This MUST be {@code null} when dataManagementIntent is {@code
1056      *     null} and MUST NOT be {@code null} when dataManagementIntent is not {@code null}.
1057      * @throws SecurityException If the UID of the calling process differs from the package UID of
1058      *     {@code transportComponent} or if the caller does NOT have BACKUP permission.
1059      */
updateTransportAttributes( @serIdInt int userId, ComponentName transportComponent, String name, @Nullable Intent configurationIntent, String currentDestinationString, @Nullable Intent dataManagementIntent, CharSequence dataManagementLabel)1060     public void updateTransportAttributes(
1061             @UserIdInt int userId,
1062             ComponentName transportComponent,
1063             String name,
1064             @Nullable Intent configurationIntent,
1065             String currentDestinationString,
1066             @Nullable Intent dataManagementIntent,
1067             CharSequence dataManagementLabel) {
1068         UserBackupManagerService userBackupManagerService =
1069                 getServiceForUserIfCallerHasPermission(userId, "updateTransportAttributes()");
1070 
1071         if (userBackupManagerService != null) {
1072             userBackupManagerService.updateTransportAttributes(
1073                     transportComponent,
1074                     name,
1075                     configurationIntent,
1076                     currentDestinationString,
1077                     dataManagementIntent,
1078                     dataManagementLabel);
1079         }
1080     }
1081 
1082     @Override
selectBackupTransportForUser(int userId, String transport)1083     public String selectBackupTransportForUser(int userId, String transport)
1084             throws RemoteException {
1085         return (isUserReadyForBackup(userId))
1086                 ? selectBackupTransport(userId, transport) : null;
1087     }
1088 
1089     @Override
selectBackupTransport(String transport)1090     public String selectBackupTransport(String transport) throws RemoteException {
1091         return selectBackupTransportForUser(binderGetCallingUserId(), transport);
1092     }
1093 
1094     /**
1095      * Selects transport {@code transportName} and returns the previously selected transport.
1096      *
1097      * @deprecated Use {@link #selectBackupTransportAsync(ComponentName,
1098      *     ISelectBackupTransportCallback)} instead.
1099      */
1100     @Deprecated
1101     @Nullable
selectBackupTransport(@serIdInt int userId, String transportName)1102     public String selectBackupTransport(@UserIdInt int userId, String transportName) {
1103         UserBackupManagerService userBackupManagerService =
1104                 getServiceForUserIfCallerHasPermission(userId, "selectBackupTransport()");
1105 
1106         return userBackupManagerService == null
1107                 ? null
1108                 : userBackupManagerService.selectBackupTransport(transportName);
1109     }
1110 
1111     @Override
selectBackupTransportAsyncForUser(int userId, ComponentName transport, ISelectBackupTransportCallback listener)1112     public void selectBackupTransportAsyncForUser(int userId, ComponentName transport,
1113             ISelectBackupTransportCallback listener) throws RemoteException {
1114         if (isUserReadyForBackup(userId)) {
1115             selectBackupTransportAsync(userId, transport, listener);
1116         } else {
1117             if (listener != null) {
1118                 try {
1119                     listener.onFailure(BackupManager.ERROR_BACKUP_NOT_ALLOWED);
1120                 } catch (RemoteException ex) {
1121                     // ignore
1122                 }
1123             }
1124         }
1125     }
1126 
1127     /**
1128      * Selects transport {@code transportComponent} asynchronously and notifies {@code listener}
1129      * with the result upon completion.
1130      */
selectBackupTransportAsync( @serIdInt int userId, ComponentName transportComponent, ISelectBackupTransportCallback listener)1131     public void selectBackupTransportAsync(
1132             @UserIdInt int userId,
1133             ComponentName transportComponent,
1134             ISelectBackupTransportCallback listener) {
1135         UserBackupManagerService userBackupManagerService =
1136                 getServiceForUserIfCallerHasPermission(userId, "selectBackupTransportAsync()");
1137 
1138         if (userBackupManagerService != null) {
1139             userBackupManagerService.selectBackupTransportAsync(transportComponent, listener);
1140         }
1141     }
1142 
1143     @Override
getConfigurationIntentForUser(int userId, String transport)1144     public Intent getConfigurationIntentForUser(int userId, String transport)
1145             throws RemoteException {
1146         return isUserReadyForBackup(userId) ? getConfigurationIntent(userId, transport)
1147                 : null;
1148     }
1149 
1150     @Override
getConfigurationIntent(String transport)1151     public Intent getConfigurationIntent(String transport)
1152             throws RemoteException {
1153         return getConfigurationIntentForUser(binderGetCallingUserId(), transport);
1154     }
1155 
1156     /**
1157      * Supply the configuration intent for the given transport. If the name is not one of the
1158      * available transports, or if the transport does not supply any configuration UI, the method
1159      * returns {@code null}.
1160      */
1161     @Nullable
getConfigurationIntent(@serIdInt int userId, String transportName)1162     public Intent getConfigurationIntent(@UserIdInt int userId, String transportName) {
1163         UserBackupManagerService userBackupManagerService =
1164                 getServiceForUserIfCallerHasPermission(userId, "getConfigurationIntent()");
1165 
1166         return userBackupManagerService == null
1167                 ? null
1168                 : userBackupManagerService.getConfigurationIntent(transportName);
1169     }
1170 
1171     @Override
getDestinationStringForUser(int userId, String transport)1172     public String getDestinationStringForUser(int userId, String transport) throws RemoteException {
1173         return isUserReadyForBackup(userId) ? getDestinationString(userId, transport)
1174                 : null;
1175     }
1176 
1177     @Override
getDestinationString(String transport)1178     public String getDestinationString(String transport) throws RemoteException {
1179         return getDestinationStringForUser(binderGetCallingUserId(), transport);
1180     }
1181 
1182     /**
1183      * Supply the current destination string for the given transport. If the name is not one of the
1184      * registered transports the method will return null.
1185      *
1186      * <p>This string is used VERBATIM as the summary text of the relevant Settings item.
1187      *
1188      * @param transportName The name of the registered transport.
1189      * @return The current destination string or null if the transport is not registered.
1190      */
1191     @Nullable
getDestinationString(@serIdInt int userId, String transportName)1192     public String getDestinationString(@UserIdInt int userId, String transportName) {
1193         UserBackupManagerService userBackupManagerService =
1194                 getServiceForUserIfCallerHasPermission(userId, "getDestinationString()");
1195 
1196         return userBackupManagerService == null
1197                 ? null
1198                 : userBackupManagerService.getDestinationString(transportName);
1199     }
1200 
1201     @Override
getDataManagementIntentForUser(int userId, String transport)1202     public Intent getDataManagementIntentForUser(int userId, String transport)
1203             throws RemoteException {
1204         return isUserReadyForBackup(userId)
1205                 ? getDataManagementIntent(userId, transport) : null;
1206     }
1207 
1208     @Override
getDataManagementIntent(String transport)1209     public Intent getDataManagementIntent(String transport)
1210             throws RemoteException {
1211         return getDataManagementIntentForUser(binderGetCallingUserId(), transport);
1212     }
1213 
1214     /** Supply the manage-data intent for the given transport. */
1215     @Nullable
getDataManagementIntent(@serIdInt int userId, String transportName)1216     public Intent getDataManagementIntent(@UserIdInt int userId, String transportName) {
1217         UserBackupManagerService userBackupManagerService =
1218                 getServiceForUserIfCallerHasPermission(userId, "getDataManagementIntent()");
1219 
1220         return userBackupManagerService == null
1221                 ? null
1222                 : userBackupManagerService.getDataManagementIntent(transportName);
1223     }
1224 
1225     @Override
getDataManagementLabelForUser(int userId, String transport)1226     public CharSequence getDataManagementLabelForUser(int userId, String transport)
1227             throws RemoteException {
1228         return isUserReadyForBackup(userId) ? getDataManagementLabel(userId, transport)
1229                 : null;
1230     }
1231 
1232     /**
1233      * Supply the menu label for affordances that fire the manage-data intent for the given
1234      * transport.
1235      */
1236     @Nullable
getDataManagementLabel(@serIdInt int userId, String transportName)1237     public CharSequence getDataManagementLabel(@UserIdInt int userId, String transportName) {
1238         UserBackupManagerService userBackupManagerService =
1239                 getServiceForUserIfCallerHasPermission(userId, "getDataManagementLabel()");
1240 
1241         return userBackupManagerService == null
1242                 ? null
1243                 : userBackupManagerService.getDataManagementLabel(transportName);
1244     }
1245 
1246     @Override
beginRestoreSessionForUser( int userId, String packageName, String transportID)1247     public IRestoreSession beginRestoreSessionForUser(
1248             int userId, String packageName, String transportID) throws RemoteException {
1249         return isUserReadyForBackup(userId)
1250                 ? beginRestoreSession(userId, packageName, transportID) : null;
1251     }
1252 
1253     /**
1254      * Begin a restore for the specified package {@code packageName} using the specified transport
1255      * {@code transportName}.
1256      */
1257     @Nullable
beginRestoreSession( @serIdInt int userId, String packageName, String transportName)1258     public IRestoreSession beginRestoreSession(
1259             @UserIdInt int userId, String packageName, String transportName) {
1260         UserBackupManagerService userBackupManagerService =
1261                 getServiceForUserIfCallerHasPermission(userId, "beginRestoreSession()");
1262 
1263         return userBackupManagerService == null
1264                 ? null
1265                 : userBackupManagerService.beginRestoreSession(packageName, transportName);
1266     }
1267 
1268     @Override
opCompleteForUser(int userId, int token, long result)1269     public void opCompleteForUser(int userId, int token, long result) throws RemoteException {
1270         if (isUserReadyForBackup(userId)) {
1271             opComplete(userId, token, result);
1272         }
1273     }
1274 
1275     @Override
opComplete(int token, long result)1276     public void opComplete(int token, long result) throws RemoteException {
1277         opCompleteForUser(binderGetCallingUserId(), token, result);
1278     }
1279 
1280     /**
1281      * Used by a currently-active backup agent to notify the service that it has completed its given
1282      * outstanding asynchronous backup/restore operation.
1283      */
opComplete(@serIdInt int userId, int token, long result)1284     public void opComplete(@UserIdInt int userId, int token, long result) {
1285         UserBackupManagerService userBackupManagerService =
1286                 getServiceForUserIfCallerHasPermission(userId, "opComplete()");
1287 
1288         if (userBackupManagerService != null) {
1289             userBackupManagerService.opComplete(token, result);
1290         }
1291     }
1292 
1293     @Override
getAvailableRestoreTokenForUser(int userId, String packageName)1294     public long getAvailableRestoreTokenForUser(int userId, String packageName) {
1295         return isUserReadyForBackup(userId) ? getAvailableRestoreToken(userId, packageName) : 0;
1296     }
1297 
1298     /**
1299      * Get the restore-set token for the best-available restore set for this {@code packageName}:
1300      * the active set if possible, else the ancestral one. Returns zero if none available.
1301      */
getAvailableRestoreToken(@serIdInt int userId, String packageName)1302     public long getAvailableRestoreToken(@UserIdInt int userId, String packageName) {
1303         UserBackupManagerService userBackupManagerService =
1304                 getServiceForUserIfCallerHasPermission(userId, "getAvailableRestoreToken()");
1305 
1306         return userBackupManagerService == null
1307                 ? 0
1308                 : userBackupManagerService.getAvailableRestoreToken(packageName);
1309     }
1310 
1311     @Override
isAppEligibleForBackupForUser(int userId, String packageName)1312     public boolean isAppEligibleForBackupForUser(int userId, String packageName) {
1313         return isUserReadyForBackup(userId) && isAppEligibleForBackup(userId,
1314                 packageName);
1315     }
1316 
1317     /** Checks if the given package {@code packageName} is eligible for backup. */
isAppEligibleForBackup(@serIdInt int userId, String packageName)1318     public boolean isAppEligibleForBackup(@UserIdInt int userId, String packageName) {
1319         UserBackupManagerService userBackupManagerService =
1320                 getServiceForUserIfCallerHasPermission(userId, "isAppEligibleForBackup()");
1321 
1322         return userBackupManagerService != null
1323                 && userBackupManagerService.isAppEligibleForBackup(packageName);
1324     }
1325 
1326     @Override
filterAppsEligibleForBackupForUser(int userId, String[] packages)1327     public String[] filterAppsEligibleForBackupForUser(int userId, String[] packages) {
1328         return isUserReadyForBackup(userId) ? filterAppsEligibleForBackup(userId, packages) : null;
1329     }
1330 
1331     /**
1332      * Returns from the inputted packages {@code packages}, the ones that are eligible for backup.
1333      */
1334     @Nullable
filterAppsEligibleForBackup(@serIdInt int userId, String[] packages)1335     public String[] filterAppsEligibleForBackup(@UserIdInt int userId, String[] packages) {
1336         UserBackupManagerService userBackupManagerService =
1337                 getServiceForUserIfCallerHasPermission(userId, "filterAppsEligibleForBackup()");
1338 
1339         return userBackupManagerService == null
1340                 ? null
1341                 : userBackupManagerService.filterAppsEligibleForBackup(packages);
1342     }
1343 
1344     @Override
requestBackupForUser(@serIdInt int userId, String[] packages, IBackupObserver observer, IBackupManagerMonitor monitor, int flags)1345     public int requestBackupForUser(@UserIdInt int userId, String[] packages, IBackupObserver
1346             observer, IBackupManagerMonitor monitor, int flags) throws RemoteException {
1347         if (!isUserReadyForBackup(userId)) {
1348             return BackupManager.ERROR_BACKUP_NOT_ALLOWED;
1349         }
1350         return requestBackup(userId, packages, observer, monitor, flags);
1351     }
1352 
1353     @Override
requestBackup(String[] packages, IBackupObserver observer, IBackupManagerMonitor monitor, int flags)1354     public int requestBackup(String[] packages, IBackupObserver observer,
1355             IBackupManagerMonitor monitor, int flags)
1356             throws RemoteException {
1357         return requestBackup(binderGetCallingUserId(), packages,
1358                 observer, monitor, flags);
1359     }
1360 
1361     /**
1362      * Requests a backup for the inputted {@code packages} with a specified callback {@link
1363      * IBackupManagerMonitor} for receiving events during the operation.
1364      */
requestBackup( @serIdInt int userId, String[] packages, IBackupObserver observer, IBackupManagerMonitor monitor, int flags)1365     public int requestBackup(
1366             @UserIdInt int userId,
1367             String[] packages,
1368             IBackupObserver observer,
1369             IBackupManagerMonitor monitor,
1370             int flags) {
1371         UserBackupManagerService userBackupManagerService =
1372                 getServiceForUserIfCallerHasPermission(userId, "requestBackup()");
1373 
1374         return userBackupManagerService == null
1375                 ? BackupManager.ERROR_BACKUP_NOT_ALLOWED
1376                 : userBackupManagerService.requestBackup(packages, observer, monitor, flags);
1377     }
1378 
1379     @Override
cancelBackupsForUser(@serIdInt int userId)1380     public void cancelBackupsForUser(@UserIdInt int userId) throws RemoteException {
1381         if (isUserReadyForBackup(userId)) {
1382             cancelBackups(userId);
1383         }
1384     }
1385 
1386     @Override
cancelBackups()1387     public void cancelBackups() throws RemoteException {
1388         cancelBackupsForUser(binderGetCallingUserId());
1389     }
1390 
1391     /** Cancel all running backup operations. */
cancelBackups(@serIdInt int userId)1392     public void cancelBackups(@UserIdInt int userId) {
1393         UserBackupManagerService userBackupManagerService =
1394                 getServiceForUserIfCallerHasPermission(userId, "cancelBackups()");
1395 
1396         if (userBackupManagerService != null) {
1397             userBackupManagerService.cancelBackups();
1398         }
1399     }
1400 
1401     /**
1402      * Returns a {@link UserHandle} for the user that has {@code ancestralSerialNumber} as the
1403      * serial number of its ancestral work profile or null if there is no {@link
1404      * UserBackupManagerService} associated with that user.
1405      *
1406      * <p> The ancestral work profile is set by {@link #setAncestralSerialNumber(long)}
1407      * and it corresponds to the profile that was used to restore to the callers profile.
1408      */
1409     @Override
1410     @Nullable
getUserForAncestralSerialNumber(long ancestralSerialNumber)1411     public UserHandle getUserForAncestralSerialNumber(long ancestralSerialNumber) {
1412         if (mGlobalDisable) {
1413             return null;
1414         }
1415         int callingUserId = Binder.getCallingUserHandle().getIdentifier();
1416         final int[] userIds;
1417         final long oldId = Binder.clearCallingIdentity();
1418         try {
1419             userIds = getUserManager().getProfileIds(callingUserId, false);
1420         } finally {
1421             Binder.restoreCallingIdentity(oldId);
1422         }
1423 
1424         for (int userId : userIds) {
1425             UserBackupManagerService userBackupManagerService = mUserServices.get(userId);
1426             if (userBackupManagerService != null) {
1427                 if (userBackupManagerService.getAncestralSerialNumber() == ancestralSerialNumber) {
1428                     return UserHandle.of(userId);
1429                 }
1430             }
1431         }
1432 
1433         return null;
1434     }
1435 
1436     /**
1437      * Sets the ancestral work profile for the calling user.
1438      *
1439      * <p> The ancestral work profile corresponds to the profile that was used to restore to the
1440      * callers profile.
1441      */
1442     @Override
setAncestralSerialNumber(long ancestralSerialNumber)1443     public void setAncestralSerialNumber(long ancestralSerialNumber) {
1444         if (mGlobalDisable) {
1445             return;
1446         }
1447         UserBackupManagerService userBackupManagerService =
1448                 getServiceForUserIfCallerHasPermission(
1449                         Binder.getCallingUserHandle().getIdentifier(),
1450                         "setAncestralSerialNumber()");
1451 
1452         if (userBackupManagerService != null) {
1453             userBackupManagerService.setAncestralSerialNumber(ancestralSerialNumber);
1454         }
1455     }
1456 
1457     @Override
dump(FileDescriptor fd, PrintWriter pw, String[] args)1458     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1459         if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) {
1460             return;
1461         }
1462         dumpWithoutCheckingPermission(fd, pw, args);
1463     }
1464 
1465     @VisibleForTesting
dumpWithoutCheckingPermission(FileDescriptor fd, PrintWriter pw, String[] args)1466     void dumpWithoutCheckingPermission(FileDescriptor fd, PrintWriter pw, String[] args) {
1467         int userId = binderGetCallingUserId();
1468         if (!isUserReadyForBackup(userId)) {
1469             pw.println("Inactive");
1470             return;
1471         }
1472 
1473         if (args != null) {
1474             for (String arg : args) {
1475                 if ("-h".equals(arg)) {
1476                     pw.println("'dumpsys backup' optional arguments:");
1477                     pw.println("  -h       : this help text");
1478                     pw.println("  a[gents] : dump information about defined backup agents");
1479                     pw.println("  transportclients : dump information about transport clients");
1480                     pw.println("  transportstats : dump transport statts");
1481                     pw.println("  users    : dump the list of users for which backup service "
1482                             + "is running");
1483                     return;
1484                 } else if ("users".equals(arg.toLowerCase())) {
1485                     pw.print(DUMP_RUNNING_USERS_MESSAGE);
1486                     for (int i = 0; i < mUserServices.size(); i++) {
1487                         pw.print(" " + mUserServices.keyAt(i));
1488                     }
1489                     pw.println();
1490                     return;
1491                 }
1492             }
1493         }
1494 
1495         for (int i = 0; i < mUserServices.size(); i++) {
1496             UserBackupManagerService userBackupManagerService =
1497                     getServiceForUserIfCallerHasPermission(mUserServices.keyAt(i), "dump()");
1498             if (userBackupManagerService != null) {
1499                 userBackupManagerService.dump(fd, pw, args);
1500             }
1501         }
1502     }
1503 
1504     /**
1505      * Used by the {@link JobScheduler} to run a full backup when conditions are right. The model we
1506      * use is to perform one app backup per scheduled job execution, and to reschedule the job with
1507      * zero latency as long as conditions remain right and we still have work to do.
1508      *
1509      * @return Whether ongoing work will continue. The return value here will be passed along as the
1510      *     return value to the callback {@link JobService#onStartJob(JobParameters)}.
1511      */
beginFullBackup(@serIdInt int userId, FullBackupJob scheduledJob)1512     public boolean beginFullBackup(@UserIdInt int userId, FullBackupJob scheduledJob) {
1513         if (!isUserReadyForBackup(userId)) {
1514             return false;
1515         }
1516         UserBackupManagerService userBackupManagerService =
1517                 getServiceForUserIfCallerHasPermission(userId, "beginFullBackup()");
1518 
1519         return userBackupManagerService != null
1520                 && userBackupManagerService.beginFullBackup(scheduledJob);
1521     }
1522 
1523     /**
1524      * Used by the {@link JobScheduler} to end the current full backup task when conditions are no
1525      * longer met for running the full backup job.
1526      */
endFullBackup(@serIdInt int userId)1527     public void endFullBackup(@UserIdInt int userId) {
1528         if (!isUserReadyForBackup(userId)) {
1529             return;
1530         }
1531         UserBackupManagerService userBackupManagerService =
1532                 getServiceForUserIfCallerHasPermission(userId, "endFullBackup()");
1533 
1534         if (userBackupManagerService != null) {
1535             userBackupManagerService.endFullBackup();
1536         }
1537     }
1538 
1539     /**
1540      * Excludes keys from KV restore for a given package. The corresponding data will be excluded
1541      * from the data set available the backup agent during restore. However,  final list  of keys
1542      * that have been excluded will be passed to the agent to make it aware of the exclusions.
1543      */
excludeKeysFromRestore(String packageName, List<String> keys)1544     public void excludeKeysFromRestore(String packageName, List<String> keys) {
1545         int userId = Binder.getCallingUserHandle().getIdentifier();
1546         if (!isUserReadyForBackup(userId)) {
1547             Slog.w(TAG, "Returning from excludeKeysFromRestore as backup for user" + userId +
1548                     " is not initialized yet");
1549             return;
1550         }
1551         UserBackupManagerService userBackupManagerService =
1552                 getServiceForUserIfCallerHasPermission(userId, "excludeKeysFromRestore()");
1553 
1554         if (userBackupManagerService != null) {
1555             userBackupManagerService.excludeKeysFromRestore(packageName, keys);
1556         }
1557     }
1558 
1559     /**
1560      * Returns the {@link UserBackupManagerService} instance for the specified user {@code userId}.
1561      * If the user is not registered with the service (either the user is locked or not eligible for
1562      * the backup service) then return {@code null}.
1563      *
1564      * @param userId The id of the user to retrieve its instance of {@link
1565      *     UserBackupManagerService}.
1566      * @param caller A {@link String} identifying the caller for logging purposes.
1567      * @throws SecurityException if {@code userId} is different from the calling user id and the
1568      *     caller does NOT have the android.permission.INTERACT_ACROSS_USERS_FULL permission.
1569      */
1570     @Nullable
1571     @VisibleForTesting
getServiceForUserIfCallerHasPermission( @serIdInt int userId, String caller)1572     UserBackupManagerService getServiceForUserIfCallerHasPermission(
1573             @UserIdInt int userId, String caller) {
1574         enforceCallingPermissionOnUserId(userId, caller);
1575         UserBackupManagerService userBackupManagerService = mUserServices.get(userId);
1576         if (userBackupManagerService == null) {
1577             Slog.w(TAG, "Called " + caller + " for unknown user: " + userId);
1578         }
1579         return userBackupManagerService;
1580     }
1581 
1582     /**
1583      * If {@code userId} is different from the calling user id, then the caller must hold the
1584      * android.permission.INTERACT_ACROSS_USERS_FULL permission.
1585      *
1586      * @param userId User id on which the backup operation is being requested.
1587      * @param message A message to include in the exception if it is thrown.
1588      */
enforceCallingPermissionOnUserId(@serIdInt int userId, String message)1589     void enforceCallingPermissionOnUserId(@UserIdInt int userId, String message) {
1590         if (Binder.getCallingUserHandle().getIdentifier() != userId) {
1591             mContext.enforceCallingOrSelfPermission(
1592                     Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
1593         }
1594     }
1595 
1596     /** Implementation to receive lifecycle event callbacks for system services. */
1597     public static class Lifecycle extends SystemService {
Lifecycle(Context context)1598         public Lifecycle(Context context) {
1599             this(context, new BackupManagerService(context));
1600         }
1601 
1602         @VisibleForTesting
Lifecycle(Context context, BackupManagerService backupManagerService)1603         Lifecycle(Context context, BackupManagerService backupManagerService) {
1604             super(context);
1605             sInstance = backupManagerService;
1606         }
1607 
1608         @Override
onStart()1609         public void onStart() {
1610             publishService(Context.BACKUP_SERVICE, BackupManagerService.sInstance);
1611         }
1612 
1613         @Override
onUserUnlocking(@onNull TargetUser user)1614         public void onUserUnlocking(@NonNull TargetUser user) {
1615             sInstance.onUnlockUser(user.getUserIdentifier());
1616         }
1617 
1618         @Override
onUserStopping(@onNull TargetUser user)1619         public void onUserStopping(@NonNull TargetUser user) {
1620             sInstance.onStopUser(user.getUserIdentifier());
1621         }
1622 
1623         @VisibleForTesting
publishService(String name, IBinder service)1624         void publishService(String name, IBinder service) {
1625             publishBinderService(name, service);
1626         }
1627     }
1628 }
1629