1 /*
2  * Copyright (C) 2018 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 com.android.internal.util.Preconditions.checkNotNull;
20 
21 import android.Manifest;
22 import android.annotation.Nullable;
23 import android.annotation.UserIdInt;
24 import android.app.ActivityManager;
25 import android.app.backup.BackupManager;
26 import android.app.backup.IBackupManagerMonitor;
27 import android.app.backup.IBackupObserver;
28 import android.app.backup.IFullBackupRestoreObserver;
29 import android.app.backup.IRestoreSession;
30 import android.app.backup.ISelectBackupTransportCallback;
31 import android.app.job.JobParameters;
32 import android.app.job.JobScheduler;
33 import android.app.job.JobService;
34 import android.content.BroadcastReceiver;
35 import android.content.ComponentName;
36 import android.content.Context;
37 import android.content.Intent;
38 import android.content.IntentFilter;
39 import android.content.pm.PackageManager;
40 import android.os.Binder;
41 import android.os.FileUtils;
42 import android.os.HandlerThread;
43 import android.os.IBinder;
44 import android.os.ParcelFileDescriptor;
45 import android.os.Trace;
46 import android.os.UserHandle;
47 import android.os.UserManager;
48 import android.util.Slog;
49 import android.util.SparseArray;
50 
51 import com.android.internal.annotations.VisibleForTesting;
52 import com.android.internal.util.DumpUtils;
53 import com.android.server.SystemConfig;
54 import com.android.server.SystemService;
55 
56 import java.io.File;
57 import java.io.FileDescriptor;
58 import java.io.PrintWriter;
59 import java.util.Collections;
60 import java.util.Set;
61 
62 /**
63  * Definition of the system service that performs backup/restore operations.
64  *
65  * <p>This class is responsible for handling user-aware operations and acts as a delegator, routing
66  * incoming calls to the appropriate per-user {@link UserBackupManagerService} to handle the
67  * corresponding backup/restore operation.
68  */
69 public class BackupManagerService {
70     public static final String TAG = "BackupManagerService";
71     public static final boolean DEBUG = true;
72     public static final boolean MORE_DEBUG = false;
73     public static final boolean DEBUG_SCHEDULING = true;
74 
75     @VisibleForTesting
76     static final String DUMP_RUNNING_USERS_MESSAGE = "Backup Manager is running for users:";
77 
78     // The published binder is a singleton Trampoline object that calls through to the proper code.
79     // This indirection lets us turn down the heavy implementation object on the fly without
80     // disturbing binders that have been cached elsewhere in the system.
81     private static Trampoline sInstance;
82 
getInstance()83     static Trampoline getInstance() {
84         // Always constructed during system bring up, so no need to lazy-init.
85         return sInstance;
86     }
87 
88     private final Context mContext;
89     private final Trampoline mTrampoline;
90     private final HandlerThread mBackupThread;
91 
92     // Keeps track of all unlocked users registered with this service. Indexed by user id.
93     private final SparseArray<UserBackupManagerService> mServiceUsers = new SparseArray<>();
94 
95     private Set<ComponentName> mTransportWhitelist;
96 
97     private final BroadcastReceiver mUserRemovedReceiver = new BroadcastReceiver() {
98         @Override
99         public void onReceive(Context context, Intent intent) {
100             if (Intent.ACTION_USER_REMOVED.equals(intent.getAction())) {
101                 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
102                 if (userId > 0) { // for only non system users
103                     onRemovedNonSystemUser(userId);
104                 }
105             }
106         }
107     };
108 
109     /** Instantiate a new instance of {@link BackupManagerService}. */
BackupManagerService( Context context, Trampoline trampoline, HandlerThread backupThread)110     public BackupManagerService(
111             Context context, Trampoline trampoline, HandlerThread backupThread) {
112         mContext = checkNotNull(context);
113         mTrampoline = checkNotNull(trampoline);
114         mBackupThread = checkNotNull(backupThread);
115 
116         // Set up our transport options.
117         SystemConfig systemConfig = SystemConfig.getInstance();
118         mTransportWhitelist = systemConfig.getBackupTransportWhitelist();
119         if (mTransportWhitelist == null) {
120             mTransportWhitelist = Collections.emptySet();
121         }
122 
123         mContext.registerReceiver(mUserRemovedReceiver,
124                 new IntentFilter(Intent.ACTION_USER_REMOVED));
125     }
126 
127     /**
128      * Remove backup state for non system {@code userId} when the user is removed from the device.
129      * For non system users, backup state is stored in both the user's own dir and the system dir.
130      * When the user is removed, the user's own dir gets removed by the OS. This method ensures that
131      * the part of the user backup state which is in the system dir also gets removed.
132      */
onRemovedNonSystemUser(int userId)133     private void onRemovedNonSystemUser(int userId) {
134         Slog.i(TAG, "Removing state for non system user " + userId);
135         File dir = UserBackupManagerFiles.getStateDirInSystemDir(userId);
136         if (!FileUtils.deleteContentsAndDir(dir)) {
137             Slog.w(TAG, "Failed to delete state dir for removed user: " + userId);
138         }
139     }
140 
141     /**
142      * If {@code userId} is different from the calling user id, then the caller must hold the
143      * android.permission.INTERACT_ACROSS_USERS_FULL permission.
144      *
145      * @param userId User id on which the backup operation is being requested.
146      * @param message A message to include in the exception if it is thrown.
147      */
enforceCallingPermissionOnUserId(@serIdInt int userId, String message)148     private void enforceCallingPermissionOnUserId(@UserIdInt int userId, String message) {
149         if (Binder.getCallingUserHandle().getIdentifier() != userId) {
150             mContext.enforceCallingOrSelfPermission(
151                     Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
152         }
153     }
154 
155     // ---------------------------------------------
156     // USER LIFECYCLE CALLBACKS
157     // ---------------------------------------------
158 
159     /**
160      * Starts the backup service for user {@code userId} by creating a new instance of {@link
161      * UserBackupManagerService} and registering it with this service.
162      */
163     @VisibleForTesting
startServiceForUser(int userId)164     protected void startServiceForUser(int userId) {
165         if (mServiceUsers.get(userId) != null) {
166             Slog.i(TAG, "userId " + userId + " already started, so not starting again");
167             return;
168         }
169 
170         UserBackupManagerService userBackupManagerService =
171                 UserBackupManagerService.createAndInitializeService(
172                         userId, mContext, mTrampoline, mTransportWhitelist);
173         startServiceForUser(userId, userBackupManagerService);
174     }
175 
176     /**
177      * Starts the backup service for user {@code userId} by registering its instance of {@link
178      * UserBackupManagerService} with this service and setting enabled state.
179      */
startServiceForUser(int userId, UserBackupManagerService userBackupManagerService)180     void startServiceForUser(int userId, UserBackupManagerService userBackupManagerService) {
181         mServiceUsers.put(userId, userBackupManagerService);
182 
183         Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "backup enable");
184         userBackupManagerService.initializeBackupEnableState();
185         Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
186     }
187 
188     /** Stops the backup service for user {@code userId} when the user is stopped. */
189     @VisibleForTesting
stopServiceForUser(int userId)190     protected void stopServiceForUser(int userId) {
191         UserBackupManagerService userBackupManagerService = mServiceUsers.removeReturnOld(userId);
192 
193         if (userBackupManagerService != null) {
194             userBackupManagerService.tearDownService();
195 
196             KeyValueBackupJob.cancel(userId, mContext);
197             FullBackupJob.cancel(userId, mContext);
198         }
199     }
200 
201     /**
202      *  Returns a lst of users currently unlocked that have a
203      *  {@link UserBackupManagerService} registered.
204      */
205     @VisibleForTesting
getServiceUsers()206     public SparseArray<UserBackupManagerService> getServiceUsers() {
207         return mServiceUsers;
208     }
209 
210     /**
211      * Returns the {@link UserBackupManagerService} instance for the specified user {@code userId}.
212      * If the user is not registered with the service (either the user is locked or not eligible for
213      * the backup service) then return {@code null}.
214      *
215      * @param userId The id of the user to retrieve its instance of {@link
216      *     UserBackupManagerService}.
217      * @param caller A {@link String} identifying the caller for logging purposes.
218      * @throws SecurityException if {@code userId} is different from the calling user id and the
219      *     caller does NOT have the android.permission.INTERACT_ACROSS_USERS_FULL permission.
220      */
221     @Nullable
222     @VisibleForTesting
getServiceForUserIfCallerHasPermission( @serIdInt int userId, String caller)223     UserBackupManagerService getServiceForUserIfCallerHasPermission(
224             @UserIdInt int userId, String caller) {
225         enforceCallingPermissionOnUserId(userId, caller);
226         UserBackupManagerService userBackupManagerService = mServiceUsers.get(userId);
227         if (userBackupManagerService == null) {
228             Slog.w(TAG, "Called " + caller + " for unknown user: " + userId);
229         }
230         return userBackupManagerService;
231     }
232 
233     /*
234      * The following methods are implementations of IBackupManager methods called from Trampoline.
235      * They delegate to the appropriate per-user instance of UserBackupManagerService to perform the
236      * action on the passed in user. Currently this is a straight redirection (see TODO).
237      */
238     // TODO (b/118520567): Stop hardcoding system user when we pass in user id as a parameter
239 
240     // ---------------------------------------------
241     // BACKUP AGENT OPERATIONS
242     // ---------------------------------------------
243 
244     /**
245      * An app's backup agent calls this method to let the service know that there's new data to
246      * backup for their app {@code packageName}. Only used for apps participating in key-value
247      * backup.
248      */
dataChanged(@serIdInt int userId, String packageName)249     public void dataChanged(@UserIdInt int userId, String packageName) {
250         UserBackupManagerService userBackupManagerService =
251                 getServiceForUserIfCallerHasPermission(userId, "dataChanged()");
252 
253         if (userBackupManagerService != null) {
254             userBackupManagerService.dataChanged(packageName);
255         }
256     }
257 
258     /**
259      * Callback: a requested backup agent has been instantiated. This should only be called from the
260      * {@link ActivityManager}.
261      */
agentConnected(@serIdInt int userId, String packageName, IBinder agentBinder)262     public void agentConnected(@UserIdInt int userId, String packageName, IBinder agentBinder) {
263         UserBackupManagerService userBackupManagerService =
264                 getServiceForUserIfCallerHasPermission(userId, "agentConnected()");
265 
266         if (userBackupManagerService != null) {
267             userBackupManagerService.agentConnected(packageName, agentBinder);
268         }
269     }
270 
271     /**
272      * Callback: a backup agent has failed to come up, or has unexpectedly quit. This should only be
273      * called from the {@link ActivityManager}.
274      */
agentDisconnected(@serIdInt int userId, String packageName)275     public void agentDisconnected(@UserIdInt int userId, String packageName) {
276         UserBackupManagerService userBackupManagerService =
277                 getServiceForUserIfCallerHasPermission(userId, "agentDisconnected()");
278 
279         if (userBackupManagerService != null) {
280             userBackupManagerService.agentDisconnected(packageName);
281         }
282     }
283 
284     /**
285      * Used by a currently-active backup agent to notify the service that it has completed its given
286      * outstanding asynchronous backup/restore operation.
287      */
opComplete(@serIdInt int userId, int token, long result)288     public void opComplete(@UserIdInt int userId, int token, long result) {
289         UserBackupManagerService userBackupManagerService =
290                 getServiceForUserIfCallerHasPermission(userId, "opComplete()");
291 
292         if (userBackupManagerService != null) {
293             userBackupManagerService.opComplete(token, result);
294         }
295     }
296 
297     // ---------------------------------------------
298     // TRANSPORT OPERATIONS
299     // ---------------------------------------------
300 
301     /** Run an initialize operation for the given transports {@code transportNames}. */
initializeTransports( @serIdInt int userId, String[] transportNames, IBackupObserver observer)302     public void initializeTransports(
303             @UserIdInt int userId, String[] transportNames, IBackupObserver observer) {
304         UserBackupManagerService userBackupManagerService =
305                 getServiceForUserIfCallerHasPermission(userId, "initializeTransports()");
306 
307         if (userBackupManagerService != null) {
308             userBackupManagerService.initializeTransports(transportNames, observer);
309         }
310     }
311 
312     /**
313      * Clear the given package {@code packageName}'s backup data from the transport {@code
314      * transportName}.
315      */
clearBackupData(@serIdInt int userId, String transportName, String packageName)316     public void clearBackupData(@UserIdInt int userId, String transportName, String packageName) {
317         UserBackupManagerService userBackupManagerService =
318                 getServiceForUserIfCallerHasPermission(userId, "clearBackupData()");
319 
320         if (userBackupManagerService != null) {
321             userBackupManagerService.clearBackupData(transportName, packageName);
322         }
323     }
324 
325     /** Return the name of the currently active transport. */
326     @Nullable
getCurrentTransport(@serIdInt int userId)327     public String getCurrentTransport(@UserIdInt int userId) {
328         UserBackupManagerService userBackupManagerService =
329                 getServiceForUserIfCallerHasPermission(userId, "getCurrentTransport()");
330 
331         return userBackupManagerService == null
332                 ? null
333                 : userBackupManagerService.getCurrentTransport();
334     }
335 
336     /**
337      * Returns the {@link ComponentName} of the host service of the selected transport or {@code
338      * null} if no transport selected or if the transport selected is not registered.
339      */
340     @Nullable
getCurrentTransportComponent(@serIdInt int userId)341     public ComponentName getCurrentTransportComponent(@UserIdInt int userId) {
342         UserBackupManagerService userBackupManagerService =
343                 getServiceForUserIfCallerHasPermission(userId, "getCurrentTransportComponent()");
344 
345         return userBackupManagerService == null
346                 ? null
347                 : userBackupManagerService.getCurrentTransportComponent();
348     }
349 
350     /** Report all known, available backup transports by name. */
351     @Nullable
listAllTransports(@serIdInt int userId)352     public String[] listAllTransports(@UserIdInt int userId) {
353         UserBackupManagerService userBackupManagerService =
354                 getServiceForUserIfCallerHasPermission(userId, "listAllTransports()");
355 
356         return userBackupManagerService == null
357                 ? null
358                 : userBackupManagerService.listAllTransports();
359     }
360 
361     /** Report all known, available backup transports by {@link ComponentName}. */
362     @Nullable
listAllTransportComponents(@serIdInt int userId)363     public ComponentName[] listAllTransportComponents(@UserIdInt int userId) {
364         UserBackupManagerService userBackupManagerService =
365                 getServiceForUserIfCallerHasPermission(userId, "listAllTransportComponents()");
366 
367         return userBackupManagerService == null
368                 ? null
369                 : userBackupManagerService.listAllTransportComponents();
370     }
371 
372     /** Report all system whitelisted transports. */
373     @Nullable
getTransportWhitelist()374     public String[] getTransportWhitelist() {
375         // No permission check, intentionally.
376         String[] whitelistedTransports = new String[mTransportWhitelist.size()];
377         int i = 0;
378         for (ComponentName component : mTransportWhitelist) {
379             whitelistedTransports[i] = component.flattenToShortString();
380             i++;
381         }
382         return whitelistedTransports;
383     }
384 
385     /**
386      * Update the attributes of the transport identified by {@code transportComponent}. If the
387      * specified transport has not been bound at least once (for registration), this call will be
388      * ignored. Only the host process of the transport can change its description, otherwise a
389      * {@link SecurityException} will be thrown.
390      *
391      * @param transportComponent The identity of the transport being described.
392      * @param name A {@link String} with the new name for the transport. This is NOT for
393      *     identification. MUST NOT be {@code null}.
394      * @param configurationIntent An {@link Intent} that can be passed to {@link
395      *     Context#startActivity} in order to launch the transport's configuration UI. It may be
396      *     {@code null} if the transport does not offer any user-facing configuration UI.
397      * @param currentDestinationString A {@link String} describing the destination to which the
398      *     transport is currently sending data. MUST NOT be {@code null}.
399      * @param dataManagementIntent An {@link Intent} that can be passed to {@link
400      *     Context#startActivity} in order to launch the transport's data-management UI. It may be
401      *     {@code null} if the transport does not offer any user-facing data management UI.
402      * @param dataManagementLabel A {@link CharSequence} to be used as the label for the transport's
403      *     data management affordance. This MUST be {@code null} when dataManagementIntent is {@code
404      *     null} and MUST NOT be {@code null} when dataManagementIntent is not {@code null}.
405      * @throws SecurityException If the UID of the calling process differs from the package UID of
406      *     {@code transportComponent} or if the caller does NOT have BACKUP permission.
407      */
updateTransportAttributes( @serIdInt int userId, ComponentName transportComponent, String name, @Nullable Intent configurationIntent, String currentDestinationString, @Nullable Intent dataManagementIntent, CharSequence dataManagementLabel)408     public void updateTransportAttributes(
409             @UserIdInt int userId,
410             ComponentName transportComponent,
411             String name,
412             @Nullable Intent configurationIntent,
413             String currentDestinationString,
414             @Nullable Intent dataManagementIntent,
415             CharSequence dataManagementLabel) {
416         UserBackupManagerService userBackupManagerService =
417                 getServiceForUserIfCallerHasPermission(userId, "updateTransportAttributes()");
418 
419         if (userBackupManagerService != null) {
420             userBackupManagerService.updateTransportAttributes(
421                     transportComponent,
422                     name,
423                     configurationIntent,
424                     currentDestinationString,
425                     dataManagementIntent,
426                     dataManagementLabel);
427         }
428     }
429 
430     /**
431      * Selects transport {@code transportName} and returns the previously selected transport.
432      *
433      * @deprecated Use {@link #selectBackupTransportAsync(ComponentName,
434      *     ISelectBackupTransportCallback)} instead.
435      */
436     @Deprecated
437     @Nullable
selectBackupTransport(@serIdInt int userId, String transportName)438     public String selectBackupTransport(@UserIdInt int userId, String transportName) {
439         UserBackupManagerService userBackupManagerService =
440                 getServiceForUserIfCallerHasPermission(userId, "selectBackupTransport()");
441 
442         return userBackupManagerService == null
443                 ? null
444                 : userBackupManagerService.selectBackupTransport(transportName);
445     }
446 
447     /**
448      * Selects transport {@code transportComponent} asynchronously and notifies {@code listener}
449      * with the result upon completion.
450      */
selectBackupTransportAsync( @serIdInt int userId, ComponentName transportComponent, ISelectBackupTransportCallback listener)451     public void selectBackupTransportAsync(
452             @UserIdInt int userId,
453             ComponentName transportComponent,
454             ISelectBackupTransportCallback listener) {
455         UserBackupManagerService userBackupManagerService =
456                 getServiceForUserIfCallerHasPermission(userId, "selectBackupTransportAsync()");
457 
458         if (userBackupManagerService != null) {
459             userBackupManagerService.selectBackupTransportAsync(transportComponent, listener);
460         }
461     }
462 
463     /**
464      * Supply the configuration intent for the given transport. If the name is not one of the
465      * available transports, or if the transport does not supply any configuration UI, the method
466      * returns {@code null}.
467      */
468     @Nullable
getConfigurationIntent(@serIdInt int userId, String transportName)469     public Intent getConfigurationIntent(@UserIdInt int userId, String transportName) {
470         UserBackupManagerService userBackupManagerService =
471                 getServiceForUserIfCallerHasPermission(userId, "getConfigurationIntent()");
472 
473         return userBackupManagerService == null
474             ? null
475             : userBackupManagerService.getConfigurationIntent(transportName);
476     }
477 
478     /**
479      * Sets the ancestral work profile for the calling user.
480      *
481      * <p> The ancestral work profile corresponds to the profile that was used to restore to the
482      * callers profile.
483      */
setAncestralSerialNumber(long ancestralSerialNumber)484     public void setAncestralSerialNumber(long ancestralSerialNumber) {
485         UserBackupManagerService userBackupManagerService =
486                 getServiceForUserIfCallerHasPermission(
487                         Binder.getCallingUserHandle().getIdentifier(),
488                         "setAncestralSerialNumber()");
489 
490         if (userBackupManagerService != null) {
491             userBackupManagerService.setAncestralSerialNumber(ancestralSerialNumber);
492         }
493     }
494 
495     /**
496      * Returns a {@link UserHandle} for the user that has {@code ancestralSerialNumber} as the
497      * serial number of the its ancestral work profile.
498      *
499      * <p> The ancestral work profile is set by {@link #setAncestralSerialNumber(long)}
500      * and it corresponds to the profile that was used to restore to the callers profile.
501      */
502     @Nullable
getUserForAncestralSerialNumber(long ancestralSerialNumber)503     public UserHandle getUserForAncestralSerialNumber(long ancestralSerialNumber) {
504         int callingUserId = Binder.getCallingUserHandle().getIdentifier();
505         long oldId = Binder.clearCallingIdentity();
506         int[] userIds;
507         try {
508             userIds = mContext.getSystemService(UserManager.class).getProfileIds(callingUserId,
509                     false);
510         } finally {
511             Binder.restoreCallingIdentity(oldId);
512         }
513 
514         for (int userId : userIds) {
515             UserBackupManagerService userBackupManagerService = getServiceUsers().get(userId);
516             if (userBackupManagerService != null) {
517                 if (userBackupManagerService.getAncestralSerialNumber() == ancestralSerialNumber) {
518                     return UserHandle.of(userId);
519                 }
520             }
521         }
522 
523         return null;
524     }
525 
526     /**
527      * Supply the current destination string for the given transport. If the name is not one of the
528      * registered transports the method will return null.
529      *
530      * <p>This string is used VERBATIM as the summary text of the relevant Settings item.
531      *
532      * @param transportName The name of the registered transport.
533      * @return The current destination string or null if the transport is not registered.
534      */
535     @Nullable
getDestinationString(@serIdInt int userId, String transportName)536     public String getDestinationString(@UserIdInt int userId, String transportName) {
537         UserBackupManagerService userBackupManagerService =
538                 getServiceForUserIfCallerHasPermission(userId, "getDestinationString()");
539 
540         return userBackupManagerService == null
541                 ? null
542                 : userBackupManagerService.getDestinationString(transportName);
543     }
544 
545     /** Supply the manage-data intent for the given transport. */
546     @Nullable
getDataManagementIntent(@serIdInt int userId, String transportName)547     public Intent getDataManagementIntent(@UserIdInt int userId, String transportName) {
548         UserBackupManagerService userBackupManagerService =
549                 getServiceForUserIfCallerHasPermission(userId, "getDataManagementIntent()");
550 
551         return userBackupManagerService == null
552                 ? null
553                 : userBackupManagerService.getDataManagementIntent(transportName);
554     }
555 
556     /**
557      * Supply the menu label for affordances that fire the manage-data intent for the given
558      * transport.
559      */
560     @Nullable
getDataManagementLabel(@serIdInt int userId, String transportName)561     public CharSequence getDataManagementLabel(@UserIdInt int userId, String transportName) {
562         UserBackupManagerService userBackupManagerService =
563                 getServiceForUserIfCallerHasPermission(userId, "getDataManagementLabel()");
564 
565         return userBackupManagerService == null
566                 ? null
567                 : userBackupManagerService.getDataManagementLabel(transportName);
568     }
569 
570     // ---------------------------------------------
571     // SETTINGS OPERATIONS
572     // ---------------------------------------------
573 
574     /** Enable/disable the backup service. This is user-configurable via backup settings. */
setBackupEnabled(@serIdInt int userId, boolean enable)575     public void setBackupEnabled(@UserIdInt int userId, boolean enable) {
576         UserBackupManagerService userBackupManagerService =
577                 getServiceForUserIfCallerHasPermission(userId, "setBackupEnabled()");
578 
579         if (userBackupManagerService != null) {
580             userBackupManagerService.setBackupEnabled(enable);
581         }
582     }
583 
584     /** Enable/disable automatic restore of app data at install time. */
setAutoRestore(@serIdInt int userId, boolean autoRestore)585     public void setAutoRestore(@UserIdInt int userId, boolean autoRestore) {
586         UserBackupManagerService userBackupManagerService =
587                 getServiceForUserIfCallerHasPermission(userId, "setAutoRestore()");
588 
589         if (userBackupManagerService != null) {
590             userBackupManagerService.setAutoRestore(autoRestore);
591         }
592     }
593 
594     /**
595      * Return {@code true} if the backup mechanism is currently enabled, else returns {@code false}.
596      */
isBackupEnabled(@serIdInt int userId)597     public boolean isBackupEnabled(@UserIdInt int userId) {
598         UserBackupManagerService userBackupManagerService =
599                 getServiceForUserIfCallerHasPermission(userId, "isBackupEnabled()");
600 
601         return userBackupManagerService != null && userBackupManagerService.isBackupEnabled();
602     }
603 
604     // ---------------------------------------------
605     // BACKUP OPERATIONS
606     // ---------------------------------------------
607 
608     /** Checks if the given package {@code packageName} is eligible for backup. */
isAppEligibleForBackup(@serIdInt int userId, String packageName)609     public boolean isAppEligibleForBackup(@UserIdInt int userId, String packageName) {
610         UserBackupManagerService userBackupManagerService =
611                 getServiceForUserIfCallerHasPermission(userId, "isAppEligibleForBackup()");
612 
613         return userBackupManagerService != null
614                 && userBackupManagerService.isAppEligibleForBackup(packageName);
615     }
616 
617     /**
618      * Returns from the inputted packages {@code packages}, the ones that are eligible for backup.
619      */
620     @Nullable
filterAppsEligibleForBackup(@serIdInt int userId, String[] packages)621     public String[] filterAppsEligibleForBackup(@UserIdInt int userId, String[] packages) {
622         UserBackupManagerService userBackupManagerService =
623                 getServiceForUserIfCallerHasPermission(userId, "filterAppsEligibleForBackup()");
624 
625         return userBackupManagerService == null
626                 ? null
627                 : userBackupManagerService.filterAppsEligibleForBackup(packages);
628     }
629 
630     /**
631      * Run a backup pass immediately for any key-value backup applications that have declared that
632      * they have pending updates.
633      */
backupNow(@serIdInt int userId)634     public void backupNow(@UserIdInt int userId) {
635         UserBackupManagerService userBackupManagerService =
636                 getServiceForUserIfCallerHasPermission(userId, "backupNow()");
637 
638         if (userBackupManagerService != null) {
639             userBackupManagerService.backupNow();
640         }
641     }
642 
643     /**
644      * Requests a backup for the inputted {@code packages} with a specified callback {@link
645      * IBackupManagerMonitor} for receiving events during the operation.
646      */
requestBackup( @serIdInt int userId, String[] packages, IBackupObserver observer, IBackupManagerMonitor monitor, int flags)647     public int requestBackup(
648             @UserIdInt int userId,
649             String[] packages,
650             IBackupObserver observer,
651             IBackupManagerMonitor monitor,
652             int flags) {
653         UserBackupManagerService userBackupManagerService =
654                 getServiceForUserIfCallerHasPermission(userId, "requestBackup()");
655 
656         return userBackupManagerService == null
657                 ? BackupManager.ERROR_BACKUP_NOT_ALLOWED
658                 : userBackupManagerService.requestBackup(packages, observer, monitor, flags);
659     }
660 
661     /** Cancel all running backup operations. */
cancelBackups(@serIdInt int userId)662     public void cancelBackups(@UserIdInt int userId) {
663         UserBackupManagerService userBackupManagerService =
664                 getServiceForUserIfCallerHasPermission(userId, "cancelBackups()");
665 
666         if (userBackupManagerService != null) {
667             userBackupManagerService.cancelBackups();
668         }
669     }
670 
671     /**
672      * Used by the {@link JobScheduler} to run a full backup when conditions are right. The model we
673      * use is to perform one app backup per scheduled job execution, and to reschedule the job with
674      * zero latency as long as conditions remain right and we still have work to do.
675      *
676      * @return Whether ongoing work will continue. The return value here will be passed along as the
677      *     return value to the callback {@link JobService#onStartJob(JobParameters)}.
678      */
beginFullBackup(@serIdInt int userId, FullBackupJob scheduledJob)679     public boolean beginFullBackup(@UserIdInt int userId, FullBackupJob scheduledJob) {
680         UserBackupManagerService userBackupManagerService =
681                 getServiceForUserIfCallerHasPermission(userId, "beginFullBackup()");
682 
683         return userBackupManagerService != null
684                 && userBackupManagerService.beginFullBackup(scheduledJob);
685     }
686 
687     /**
688      * Used by the {@link JobScheduler} to end the current full backup task when conditions are no
689      * longer met for running the full backup job.
690      */
endFullBackup(@serIdInt int userId)691     public void endFullBackup(@UserIdInt int userId) {
692         UserBackupManagerService userBackupManagerService =
693                 getServiceForUserIfCallerHasPermission(userId, "endFullBackup()");
694 
695         if (userBackupManagerService != null) {
696             userBackupManagerService.endFullBackup();
697         }
698     }
699 
700     /**
701      * Run a full backup pass for the given packages {@code packageNames}. Used by 'adb shell bmgr'.
702      */
fullTransportBackup(@serIdInt int userId, String[] packageNames)703     public void fullTransportBackup(@UserIdInt int userId, String[] packageNames) {
704         UserBackupManagerService userBackupManagerService =
705                 getServiceForUserIfCallerHasPermission(userId, "fullTransportBackup()");
706 
707         if (userBackupManagerService != null) {
708             userBackupManagerService.fullTransportBackup(packageNames);
709         }
710     }
711 
712     // ---------------------------------------------
713     // RESTORE OPERATIONS
714     // ---------------------------------------------
715 
716     /**
717      * Used to run a restore pass for an application that is being installed. This should only be
718      * called from the {@link PackageManager}.
719      */
restoreAtInstall(@serIdInt int userId, String packageName, int token)720     public void restoreAtInstall(@UserIdInt int userId, String packageName, int token) {
721         UserBackupManagerService userBackupManagerService =
722                 getServiceForUserIfCallerHasPermission(userId, "restoreAtInstall()");
723 
724         if (userBackupManagerService != null) {
725             userBackupManagerService.restoreAtInstall(packageName, token);
726         }
727     }
728 
729     /**
730      * Begin a restore for the specified package {@code packageName} using the specified transport
731      * {@code transportName}.
732      */
733     @Nullable
beginRestoreSession( @serIdInt int userId, String packageName, String transportName)734     public IRestoreSession beginRestoreSession(
735             @UserIdInt int userId, String packageName, String transportName) {
736         UserBackupManagerService userBackupManagerService =
737                 getServiceForUserIfCallerHasPermission(userId, "beginRestoreSession()");
738 
739         return userBackupManagerService == null
740                 ? null
741                 : userBackupManagerService.beginRestoreSession(packageName, transportName);
742     }
743 
744     /**
745      * Get the restore-set token for the best-available restore set for this {@code packageName}:
746      * the active set if possible, else the ancestral one. Returns zero if none available.
747      */
getAvailableRestoreToken(@serIdInt int userId, String packageName)748     public long getAvailableRestoreToken(@UserIdInt int userId, String packageName) {
749         UserBackupManagerService userBackupManagerService =
750                 getServiceForUserIfCallerHasPermission(userId, "getAvailableRestoreToken()");
751 
752         return userBackupManagerService == null
753                 ? 0
754                 : userBackupManagerService.getAvailableRestoreToken(packageName);
755     }
756 
757     // ---------------------------------------------
758     // ADB BACKUP/RESTORE OPERATIONS
759     // ---------------------------------------------
760 
761     /** Sets the backup password used when running adb backup. */
setBackupPassword(String currentPassword, String newPassword)762     public boolean setBackupPassword(String currentPassword, String newPassword) {
763         UserBackupManagerService userBackupManagerService =
764                 getServiceForUserIfCallerHasPermission(
765                         UserHandle.USER_SYSTEM, "setBackupPassword()");
766 
767         return userBackupManagerService != null
768                 && userBackupManagerService.setBackupPassword(currentPassword, newPassword);
769     }
770 
771     /** Returns {@code true} if adb backup was run with a password, else returns {@code false}. */
hasBackupPassword()772     public boolean hasBackupPassword() {
773         UserBackupManagerService userBackupManagerService =
774                 getServiceForUserIfCallerHasPermission(
775                         UserHandle.USER_SYSTEM, "hasBackupPassword()");
776 
777         return userBackupManagerService != null && userBackupManagerService.hasBackupPassword();
778     }
779 
780     /**
781      * Used by 'adb backup' to run a backup pass for packages {@code packageNames} supplied via the
782      * command line, writing the resulting data stream to the supplied {@code fd}. This method is
783      * synchronous and does not return to the caller until the backup has been completed. It
784      * requires on-screen confirmation by the user.
785      */
adbBackup( @serIdInt int userId, ParcelFileDescriptor fd, boolean includeApks, boolean includeObbs, boolean includeShared, boolean doWidgets, boolean doAllApps, boolean includeSystem, boolean doCompress, boolean doKeyValue, String[] packageNames)786     public void adbBackup(
787             @UserIdInt int userId,
788             ParcelFileDescriptor fd,
789             boolean includeApks,
790             boolean includeObbs,
791             boolean includeShared,
792             boolean doWidgets,
793             boolean doAllApps,
794             boolean includeSystem,
795             boolean doCompress,
796             boolean doKeyValue,
797             String[] packageNames) {
798         UserBackupManagerService userBackupManagerService =
799                 getServiceForUserIfCallerHasPermission(userId, "adbBackup()");
800 
801         if (userBackupManagerService != null) {
802             userBackupManagerService.adbBackup(
803                     fd,
804                     includeApks,
805                     includeObbs,
806                     includeShared,
807                     doWidgets,
808                     doAllApps,
809                     includeSystem,
810                     doCompress,
811                     doKeyValue,
812                     packageNames);
813         }
814     }
815 
816     /**
817      * Used by 'adb restore' to run a restore pass reading from the supplied {@code fd}. This method
818      * is synchronous and does not return to the caller until the restore has been completed. It
819      * requires on-screen confirmation by the user.
820      */
adbRestore(@serIdInt int userId, ParcelFileDescriptor fd)821     public void adbRestore(@UserIdInt int userId, ParcelFileDescriptor fd) {
822         UserBackupManagerService userBackupManagerService =
823                 getServiceForUserIfCallerHasPermission(userId, "adbRestore()");
824 
825         if (userBackupManagerService != null) {
826             userBackupManagerService.adbRestore(fd);
827         }
828     }
829 
830     /**
831      * Confirm that the previously requested adb backup/restore operation can proceed. This is used
832      * to require a user-facing disclosure about the operation.
833      */
acknowledgeAdbBackupOrRestore( @serIdInt int userId, int token, boolean allow, String currentPassword, String encryptionPassword, IFullBackupRestoreObserver observer)834     public void acknowledgeAdbBackupOrRestore(
835             @UserIdInt int userId,
836             int token,
837             boolean allow,
838             String currentPassword,
839             String encryptionPassword,
840             IFullBackupRestoreObserver observer) {
841         UserBackupManagerService userBackupManagerService =
842                 getServiceForUserIfCallerHasPermission(userId, "acknowledgeAdbBackupOrRestore()");
843 
844         if (userBackupManagerService != null) {
845             userBackupManagerService.acknowledgeAdbBackupOrRestore(
846                     token, allow, currentPassword, encryptionPassword, observer);
847         }
848     }
849 
850     // ---------------------------------------------
851     //  SERVICE OPERATIONS
852     // ---------------------------------------------
853 
854     /** Prints service state for 'dumpsys backup'. */
dump(FileDescriptor fd, PrintWriter pw, String[] args)855     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
856         if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) {
857             return;
858         }
859 
860         if (args != null) {
861             for (String arg : args) {
862                 if ("users".equals(arg.toLowerCase())) {
863                     pw.print(DUMP_RUNNING_USERS_MESSAGE);
864                     for (int i = 0; i < mServiceUsers.size(); i++) {
865                         pw.print(" " + mServiceUsers.keyAt(i));
866                     }
867                     pw.println();
868                     return;
869                 }
870             }
871         }
872 
873         UserBackupManagerService userBackupManagerService =
874                 getServiceForUserIfCallerHasPermission(UserHandle.USER_SYSTEM, "dump()");
875 
876         if (userBackupManagerService != null) {
877             userBackupManagerService.dump(fd, pw, args);
878         }
879     }
880 
881     /** Implementation to receive lifecycle event callbacks for system services. */
882     public static final class Lifecycle extends SystemService {
Lifecycle(Context context)883         public Lifecycle(Context context) {
884             super(context);
885             sInstance = new Trampoline(context);
886         }
887 
888         @Override
onStart()889         public void onStart() {
890             publishBinderService(Context.BACKUP_SERVICE, sInstance);
891         }
892 
893         @Override
onUnlockUser(int userId)894         public void onUnlockUser(int userId) {
895             if (userId == UserHandle.USER_SYSTEM) {
896                 sInstance.initializeService();
897             }
898             sInstance.unlockUser(userId);
899         }
900 
901         @Override
onStopUser(int userId)902         public void onStopUser(int userId) {
903             sInstance.stopUser(userId);
904         }
905     }
906 }
907