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