• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 android.app.backup.BackupManager;
20 import android.app.backup.IBackupManager;
21 import android.app.backup.IBackupObserver;
22 import android.app.backup.IBackupManagerMonitor;
23 import android.app.backup.IFullBackupRestoreObserver;
24 import android.app.backup.IRestoreSession;
25 import android.app.backup.ISelectBackupTransportCallback;
26 import android.content.ComponentName;
27 import android.content.Context;
28 import android.content.Intent;
29 import android.os.Binder;
30 import android.os.Environment;
31 import android.os.IBinder;
32 import android.os.ParcelFileDescriptor;
33 import android.os.Process;
34 import android.os.RemoteException;
35 import android.os.SystemProperties;
36 import android.os.UserHandle;
37 import android.util.Slog;
38 
39 import com.android.internal.util.DumpUtils;
40 
41 import java.io.File;
42 import java.io.FileDescriptor;
43 import java.io.IOException;
44 import java.io.PrintWriter;
45 
46 public class Trampoline extends IBackupManager.Stub {
47     static final String TAG = "BackupManagerService";
48     static final boolean DEBUG_TRAMPOLINE = false;
49 
50     // When this file is present, the backup service is inactive
51     static final String BACKUP_SUPPRESS_FILENAME = "backup-suppress";
52 
53     // Product-level suppression of backup/restore
54     static final String BACKUP_DISABLE_PROPERTY = "ro.backup.disable";
55 
56     final Context mContext;
57     final File mSuppressFile;   // existence testing & creating synchronized on 'this'
58     final boolean mGlobalDisable;
59     volatile BackupManagerService mService;
60 
Trampoline(Context context)61     public Trampoline(Context context) {
62         mContext = context;
63         File dir = new File(Environment.getDataDirectory(), "backup");
64         dir.mkdirs();
65         mSuppressFile = new File(dir, BACKUP_SUPPRESS_FILENAME);
66         mGlobalDisable = SystemProperties.getBoolean(BACKUP_DISABLE_PROPERTY, false);
67     }
68 
69     // internal control API
initialize(final int whichUser)70     public void initialize(final int whichUser) {
71         // Note that only the owner user is currently involved in backup/restore
72         // TODO: http://b/22388012
73         if (whichUser == UserHandle.USER_SYSTEM) {
74             // Does this product support backup/restore at all?
75             if (mGlobalDisable) {
76                 Slog.i(TAG, "Backup/restore not supported");
77                 return;
78             }
79 
80             synchronized (this) {
81                 if (!mSuppressFile.exists()) {
82                     mService = new BackupManagerService(mContext, this);
83                 } else {
84                     Slog.i(TAG, "Backup inactive in user " + whichUser);
85                 }
86             }
87         }
88     }
89 
setBackupServiceActive(final int userHandle, boolean makeActive)90     public void setBackupServiceActive(final int userHandle, boolean makeActive) {
91         // Only the DPM should be changing the active state of backup
92         final int caller = Binder.getCallingUid();
93         if (caller != Process.SYSTEM_UID
94                 && caller != Process.ROOT_UID) {
95             throw new SecurityException("No permission to configure backup activity");
96         }
97 
98         if (mGlobalDisable) {
99             Slog.i(TAG, "Backup/restore not supported");
100             return;
101         }
102         // TODO: http://b/22388012
103         if (userHandle == UserHandle.USER_SYSTEM) {
104             synchronized (this) {
105                 if (makeActive != isBackupServiceActive(userHandle)) {
106                     Slog.i(TAG, "Making backup "
107                             + (makeActive ? "" : "in") + "active in user " + userHandle);
108                     if (makeActive) {
109                         mService = new BackupManagerService(mContext, this);
110                         mSuppressFile.delete();
111                     } else {
112                         mService = null;
113                         try {
114                             mSuppressFile.createNewFile();
115                         } catch (IOException e) {
116                             Slog.e(TAG, "Unable to persist backup service inactivity");
117                         }
118                     }
119                 }
120             }
121         }
122     }
123 
124     /**
125      * Querying activity state of backup service. Calling this method before initialize yields
126      * undefined result.
127      * @param userHandle The user in which the activity state of backup service is queried.
128      * @return true if the service is active.
129      */
isBackupServiceActive(final int userHandle)130     public boolean isBackupServiceActive(final int userHandle) {
131         // TODO: http://b/22388012
132         if (userHandle == UserHandle.USER_SYSTEM) {
133             synchronized (this) {
134                 return mService != null;
135             }
136         }
137         return false;
138     }
139 
140     // IBackupManager binder API
141     @Override
dataChanged(String packageName)142     public void dataChanged(String packageName) throws RemoteException {
143         BackupManagerService svc = mService;
144         if (svc != null) {
145             svc.dataChanged(packageName);
146         }
147     }
148 
149     @Override
clearBackupData(String transportName, String packageName)150     public void clearBackupData(String transportName, String packageName)
151             throws RemoteException {
152         BackupManagerService svc = mService;
153         if (svc != null) {
154             svc.clearBackupData(transportName, packageName);
155         }
156     }
157 
158     @Override
agentConnected(String packageName, IBinder agent)159     public void agentConnected(String packageName, IBinder agent) throws RemoteException {
160         BackupManagerService svc = mService;
161         if (svc != null) {
162             svc.agentConnected(packageName, agent);
163         }
164     }
165 
166     @Override
agentDisconnected(String packageName)167     public void agentDisconnected(String packageName) throws RemoteException {
168         BackupManagerService svc = mService;
169         if (svc != null) {
170             svc.agentDisconnected(packageName);
171         }
172     }
173 
174     @Override
restoreAtInstall(String packageName, int token)175     public void restoreAtInstall(String packageName, int token) throws RemoteException {
176         BackupManagerService svc = mService;
177         if (svc != null) {
178             svc.restoreAtInstall(packageName, token);
179         }
180     }
181 
182     @Override
setBackupEnabled(boolean isEnabled)183     public void setBackupEnabled(boolean isEnabled) throws RemoteException {
184         BackupManagerService svc = mService;
185         if (svc != null) {
186             svc.setBackupEnabled(isEnabled);
187         }
188     }
189 
190     @Override
setAutoRestore(boolean doAutoRestore)191     public void setAutoRestore(boolean doAutoRestore) throws RemoteException {
192         BackupManagerService svc = mService;
193         if (svc != null) {
194             svc.setAutoRestore(doAutoRestore);
195         }
196     }
197 
198     @Override
setBackupProvisioned(boolean isProvisioned)199     public void setBackupProvisioned(boolean isProvisioned) throws RemoteException {
200         BackupManagerService svc = mService;
201         if (svc != null) {
202             svc.setBackupProvisioned(isProvisioned);
203         }
204     }
205 
206     @Override
isBackupEnabled()207     public boolean isBackupEnabled() throws RemoteException {
208         BackupManagerService svc = mService;
209         return (svc != null) ? svc.isBackupEnabled() : false;
210     }
211 
212     @Override
setBackupPassword(String currentPw, String newPw)213     public boolean setBackupPassword(String currentPw, String newPw) throws RemoteException {
214         BackupManagerService svc = mService;
215         return (svc != null) ? svc.setBackupPassword(currentPw, newPw) : false;
216     }
217 
218     @Override
hasBackupPassword()219     public boolean hasBackupPassword() throws RemoteException {
220         BackupManagerService svc = mService;
221         return (svc != null) ? svc.hasBackupPassword() : false;
222     }
223 
224     @Override
backupNow()225     public void backupNow() throws RemoteException {
226         BackupManagerService svc = mService;
227         if (svc != null) {
228             svc.backupNow();
229         }
230     }
231 
232     @Override
adbBackup(ParcelFileDescriptor fd, boolean includeApks, boolean includeObbs, boolean includeShared, boolean doWidgets, boolean allApps, boolean allIncludesSystem, boolean doCompress, boolean doKeyValue, String[] packageNames)233     public void adbBackup(ParcelFileDescriptor fd, boolean includeApks, boolean includeObbs,
234             boolean includeShared, boolean doWidgets, boolean allApps,
235             boolean allIncludesSystem, boolean doCompress, boolean doKeyValue, String[] packageNames)
236                     throws RemoteException {
237         BackupManagerService svc = mService;
238         if (svc != null) {
239             svc.adbBackup(fd, includeApks, includeObbs, includeShared, doWidgets,
240                     allApps, allIncludesSystem, doCompress, doKeyValue, packageNames);
241         }
242     }
243 
244     @Override
fullTransportBackup(String[] packageNames)245     public void fullTransportBackup(String[] packageNames) throws RemoteException {
246         BackupManagerService svc = mService;
247         if (svc != null) {
248             svc.fullTransportBackup(packageNames);
249         }
250     }
251 
252     @Override
adbRestore(ParcelFileDescriptor fd)253     public void adbRestore(ParcelFileDescriptor fd) throws RemoteException {
254         BackupManagerService svc = mService;
255         if (svc != null) {
256             svc.adbRestore(fd);
257         }
258     }
259 
260     @Override
acknowledgeFullBackupOrRestore(int token, boolean allow, String curPassword, String encryptionPassword, IFullBackupRestoreObserver observer)261     public void acknowledgeFullBackupOrRestore(int token, boolean allow, String curPassword,
262             String encryptionPassword, IFullBackupRestoreObserver observer)
263                     throws RemoteException {
264         BackupManagerService svc = mService;
265         if (svc != null) {
266             svc.acknowledgeAdbBackupOrRestore(token, allow,
267                     curPassword, encryptionPassword, observer);
268         }
269     }
270 
271     @Override
getCurrentTransport()272     public String getCurrentTransport() throws RemoteException {
273         BackupManagerService svc = mService;
274         return (svc != null) ? svc.getCurrentTransport() : null;
275     }
276 
277     @Override
listAllTransports()278     public String[] listAllTransports() throws RemoteException {
279         BackupManagerService svc = mService;
280         return (svc != null) ? svc.listAllTransports() : null;
281     }
282 
283     @Override
listAllTransportComponents()284     public ComponentName[] listAllTransportComponents() throws RemoteException {
285         BackupManagerService svc = mService;
286         return (svc != null) ? svc.listAllTransportComponents() : null;
287     }
288 
289     @Override
getTransportWhitelist()290     public String[] getTransportWhitelist() {
291         BackupManagerService svc = mService;
292         return (svc != null) ? svc.getTransportWhitelist() : null;
293     }
294 
295     @Override
selectBackupTransport(String transport)296     public String selectBackupTransport(String transport) throws RemoteException {
297         BackupManagerService svc = mService;
298         return (svc != null) ? svc.selectBackupTransport(transport) : null;
299     }
300 
301     @Override
selectBackupTransportAsync(ComponentName transport, ISelectBackupTransportCallback listener)302     public void selectBackupTransportAsync(ComponentName transport,
303             ISelectBackupTransportCallback listener) throws RemoteException {
304         BackupManagerService svc = mService;
305         if (svc != null) {
306             svc.selectBackupTransportAsync(transport, listener);
307         } else {
308             if (listener != null) {
309                 try {
310                     listener.onFailure(BackupManager.ERROR_BACKUP_NOT_ALLOWED);
311                 } catch (RemoteException ex) {
312                     // Ignore
313                 }
314             }
315         }
316     }
317 
318     @Override
getConfigurationIntent(String transport)319     public Intent getConfigurationIntent(String transport) throws RemoteException {
320         BackupManagerService svc = mService;
321         return (svc != null) ? svc.getConfigurationIntent(transport) : null;
322     }
323 
324     @Override
getDestinationString(String transport)325     public String getDestinationString(String transport) throws RemoteException {
326         BackupManagerService svc = mService;
327         return (svc != null) ? svc.getDestinationString(transport) : null;
328     }
329 
330     @Override
getDataManagementIntent(String transport)331     public Intent getDataManagementIntent(String transport) throws RemoteException {
332         BackupManagerService svc = mService;
333         return (svc != null) ? svc.getDataManagementIntent(transport) : null;
334     }
335 
336     @Override
getDataManagementLabel(String transport)337     public String getDataManagementLabel(String transport) throws RemoteException {
338         BackupManagerService svc = mService;
339         return (svc != null) ? svc.getDataManagementLabel(transport) : null;
340     }
341 
342     @Override
beginRestoreSession(String packageName, String transportID)343     public IRestoreSession beginRestoreSession(String packageName, String transportID)
344             throws RemoteException {
345         BackupManagerService svc = mService;
346         return (svc != null) ? svc.beginRestoreSession(packageName, transportID) : null;
347     }
348 
349     @Override
opComplete(int token, long result)350     public void opComplete(int token, long result) throws RemoteException {
351         BackupManagerService svc = mService;
352         if (svc != null) {
353             svc.opComplete(token, result);
354         }
355     }
356 
357     @Override
getAvailableRestoreToken(String packageName)358     public long getAvailableRestoreToken(String packageName) {
359         BackupManagerService svc = mService;
360         return (svc != null) ? svc.getAvailableRestoreToken(packageName) : 0;
361     }
362 
363     @Override
isAppEligibleForBackup(String packageName)364     public boolean isAppEligibleForBackup(String packageName) {
365         BackupManagerService svc = mService;
366         return (svc != null) ? svc.isAppEligibleForBackup(packageName) : false;
367     }
368 
369     @Override
requestBackup(String[] packages, IBackupObserver observer, IBackupManagerMonitor monitor, int flags)370     public int requestBackup(String[] packages, IBackupObserver observer,
371             IBackupManagerMonitor monitor, int flags) throws RemoteException {
372         BackupManagerService svc = mService;
373         if (svc == null) {
374             return BackupManager.ERROR_BACKUP_NOT_ALLOWED;
375         }
376         return svc.requestBackup(packages, observer, monitor, flags);
377     }
378 
379     @Override
cancelBackups()380     public void cancelBackups() throws RemoteException {
381         BackupManagerService svc = mService;
382         if (svc != null) {
383             svc.cancelBackups();
384         }
385     }
386 
387     @Override
dump(FileDescriptor fd, PrintWriter pw, String[] args)388     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
389         if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
390 
391         BackupManagerService svc = mService;
392         if (svc != null) {
393             svc.dump(fd, pw, args);
394         } else {
395             pw.println("Inactive");
396         }
397     }
398 
399     // Full backup/restore entry points - non-Binder; called directly
400     // by the full-backup scheduled job
beginFullBackup(FullBackupJob scheduledJob)401     /* package */ boolean beginFullBackup(FullBackupJob scheduledJob) {
402         BackupManagerService svc = mService;
403         return (svc != null) ? svc.beginFullBackup(scheduledJob) : false;
404     }
405 
endFullBackup()406     /* package */ void endFullBackup() {
407         BackupManagerService svc = mService;
408         if (svc != null) {
409             svc.endFullBackup();
410         }
411     }
412 }
413