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