Loading core/java/android/app/backup/IBackupManager.aidl +12 −0 Original line number Original line Diff line number Diff line Loading @@ -291,4 +291,16 @@ interface IBackupManager { * {@hide} * {@hide} */ */ void opComplete(int token); void opComplete(int token); /** * Make the device's backup and restore machinery (in)active. When it is inactive, * the device will not perform any backup operations, nor will it deliver data for * restore, although clients can still safely call BackupManager methods. * * @param whichUser User handle of the defined user whose backup active state * is to be adjusted. * @param makeActive {@code true} when backup services are to be made active; * {@code false} otherwise. */ void setBackupServiceActive(int whichUser, boolean makeActive); } } services/backup/java/com/android/server/backup/BackupManagerService.java +19 −18 Original line number Original line Diff line number Diff line Loading @@ -153,7 +153,7 @@ import javax.crypto.spec.SecretKeySpec; import libcore.io.IoUtils; import libcore.io.IoUtils; public class BackupManagerService extends IBackupManager.Stub { public class BackupManagerService { private static final String TAG = "BackupManagerService"; private static final String TAG = "BackupManagerService"; private static final boolean DEBUG = true; private static final boolean DEBUG = true; Loading Loading @@ -322,8 +322,12 @@ public class BackupManagerService extends IBackupManager.Stub { // Watch the device provisioning operation during setup // Watch the device provisioning operation during setup ContentObserver mProvisionedObserver; ContentObserver mProvisionedObserver; static BackupManagerService sInstance; // The published binder is actually to a singleton trampoline object that calls static BackupManagerService getInstance() { // through to the proper code. This indirection lets us turn down the heavy // implementation object on the fly without disturbing binders that have been // cached elsewhere in the system. static Trampoline sInstance; static Trampoline getInstance() { // Always constructed during system bringup, so no need to lazy-init // Always constructed during system bringup, so no need to lazy-init return sInstance; return sInstance; } } Loading @@ -332,7 +336,7 @@ public class BackupManagerService extends IBackupManager.Stub { public Lifecycle(Context context) { public Lifecycle(Context context) { super(context); super(context); sInstance = new BackupManagerService(context); sInstance = new Trampoline(context); } } @Override @Override Loading @@ -342,11 +346,17 @@ public class BackupManagerService extends IBackupManager.Stub { @Override @Override public void onBootPhase(int phase) { public void onBootPhase(int phase) { if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) { if (phase == PHASE_SYSTEM_SERVICES_READY) { sInstance.initialize(UserHandle.USER_OWNER); } else if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) { ContentResolver r = sInstance.mContext.getContentResolver(); ContentResolver r = sInstance.mContext.getContentResolver(); boolean areEnabled = Settings.Secure.getInt(r, boolean areEnabled = Settings.Secure.getInt(r, Settings.Secure.BACKUP_ENABLED, 0) != 0; Settings.Secure.BACKUP_ENABLED, 0) != 0; try { sInstance.setBackupEnabled(areEnabled); sInstance.setBackupEnabled(areEnabled); } catch (RemoteException e) { // can't happen; it's a local object } } } } } } } Loading Loading @@ -934,7 +944,7 @@ public class BackupManagerService extends IBackupManager.Stub { // ----- Main service implementation ----- // ----- Main service implementation ----- public BackupManagerService(Context context) { public BackupManagerService(Context context, Trampoline parent) { mContext = context; mContext = context; mPackageManager = context.getPackageManager(); mPackageManager = context.getPackageManager(); mPackageManagerBinder = AppGlobals.getPackageManager(); mPackageManagerBinder = AppGlobals.getPackageManager(); Loading @@ -944,7 +954,7 @@ public class BackupManagerService extends IBackupManager.Stub { mPowerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE); mPowerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE); mMountService = IMountService.Stub.asInterface(ServiceManager.getService("mount")); mMountService = IMountService.Stub.asInterface(ServiceManager.getService("mount")); mBackupManagerBinder = asInterface(asBinder()); mBackupManagerBinder = Trampoline.asInterface(parent.asBinder()); // spin up the backup/restore handler thread // spin up the backup/restore handler thread mHandlerThread = new HandlerThread("backup", Process.THREAD_PRIORITY_BACKGROUND); mHandlerThread = new HandlerThread("backup", Process.THREAD_PRIORITY_BACKGROUND); Loading Loading @@ -1451,7 +1461,6 @@ public class BackupManagerService extends IBackupManager.Stub { return false; return false; } } @Override public boolean setBackupPassword(String currentPw, String newPw) { public boolean setBackupPassword(String currentPw, String newPw) { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP, mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP, "setBackupPassword"); "setBackupPassword"); Loading Loading @@ -1532,7 +1541,6 @@ public class BackupManagerService extends IBackupManager.Stub { return false; return false; } } @Override public boolean hasBackupPassword() { public boolean hasBackupPassword() { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP, mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP, "hasBackupPassword"); "hasBackupPassword"); Loading Loading @@ -8145,7 +8153,6 @@ if (MORE_DEBUG) Slog.v(TAG, " + got " + nRead + "; now wanting " + (size - soF // // // This is the variant used by 'adb backup'; it requires on-screen confirmation // This is the variant used by 'adb backup'; it requires on-screen confirmation // by the user because it can be used to offload data over untrusted USB. // by the user because it can be used to offload data over untrusted USB. @Override public void fullBackup(ParcelFileDescriptor fd, boolean includeApks, public void fullBackup(ParcelFileDescriptor fd, boolean includeApks, boolean includeObbs, boolean includeShared, boolean doWidgets, boolean includeObbs, boolean includeShared, boolean doWidgets, boolean doAllApps, boolean includeSystem, boolean compress, String[] pkgList) { boolean doAllApps, boolean includeSystem, boolean compress, String[] pkgList) { Loading Loading @@ -8217,7 +8224,6 @@ if (MORE_DEBUG) Slog.v(TAG, " + got " + nRead + "; now wanting " + (size - soF } } } } @Override public void fullTransportBackup(String[] pkgNames) { public void fullTransportBackup(String[] pkgNames) { mContext.enforceCallingPermission(android.Manifest.permission.BACKUP, mContext.enforceCallingPermission(android.Manifest.permission.BACKUP, "fullTransportBackup"); "fullTransportBackup"); Loading Loading @@ -8247,7 +8253,6 @@ if (MORE_DEBUG) Slog.v(TAG, " + got " + nRead + "; now wanting " + (size - soF } } } } @Override public void fullRestore(ParcelFileDescriptor fd) { public void fullRestore(ParcelFileDescriptor fd) { mContext.enforceCallingPermission(android.Manifest.permission.BACKUP, "fullRestore"); mContext.enforceCallingPermission(android.Manifest.permission.BACKUP, "fullRestore"); Loading Loading @@ -8343,7 +8348,6 @@ if (MORE_DEBUG) Slog.v(TAG, " + got " + nRead + "; now wanting " + (size - soF // Confirm that the previously-requested full backup/restore operation can proceed. This // Confirm that the previously-requested full backup/restore operation can proceed. This // is used to require a user-facing disclosure about the operation. // is used to require a user-facing disclosure about the operation. @Override public void acknowledgeFullBackupOrRestore(int token, boolean allow, public void acknowledgeFullBackupOrRestore(int token, boolean allow, String curPassword, String encPpassword, IFullBackupRestoreObserver observer) { String curPassword, String encPpassword, IFullBackupRestoreObserver observer) { if (DEBUG) Slog.d(TAG, "acknowledgeFullBackupOrRestore : token=" + token if (DEBUG) Slog.d(TAG, "acknowledgeFullBackupOrRestore : token=" + token Loading Loading @@ -8391,8 +8395,7 @@ if (MORE_DEBUG) Slog.v(TAG, " + got " + nRead + "; now wanting " + (size - soF } } } } // Enable/disable the backup service // Enable/disable backups @Override public void setBackupEnabled(boolean enable) { public void setBackupEnabled(boolean enable) { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP, mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP, "setBackupEnabled"); "setBackupEnabled"); Loading Loading @@ -8798,7 +8801,6 @@ if (MORE_DEBUG) Slog.v(TAG, " + got " + nRead + "; now wanting " + (size - soF // Note that a currently-active backup agent has notified us that it has // Note that a currently-active backup agent has notified us that it has // completed the given outstanding asynchronous backup/restore operation. // completed the given outstanding asynchronous backup/restore operation. @Override public void opComplete(int token) { public void opComplete(int token) { if (MORE_DEBUG) Slog.v(TAG, "opComplete: " + Integer.toHexString(token)); if (MORE_DEBUG) Slog.v(TAG, "opComplete: " + Integer.toHexString(token)); Operation op = null; Operation op = null; Loading Loading @@ -9147,7 +9149,6 @@ if (MORE_DEBUG) Slog.v(TAG, " + got " + nRead + "; now wanting " + (size - soF } } } } @Override public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG); mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG); Loading services/backup/java/com/android/server/backup/FullBackupJob.java +2 −2 Original line number Original line Diff line number Diff line Loading @@ -59,7 +59,7 @@ public class FullBackupJob extends JobService { @Override @Override public boolean onStartJob(JobParameters params) { public boolean onStartJob(JobParameters params) { mParams = params; mParams = params; BackupManagerService service = BackupManagerService.getInstance(); Trampoline service = BackupManagerService.getInstance(); return service.beginFullBackup(this); return service.beginFullBackup(this); } } Loading @@ -67,7 +67,7 @@ public class FullBackupJob extends JobService { public boolean onStopJob(JobParameters params) { public boolean onStopJob(JobParameters params) { if (mParams != null) { if (mParams != null) { mParams = null; mParams = null; BackupManagerService service = BackupManagerService.getInstance(); Trampoline service = BackupManagerService.getInstance(); service.endFullBackup(); service.endFullBackup(); } } return false; return false; Loading services/backup/java/com/android/server/backup/Trampoline.java 0 → 100644 +327 −0 Original line number Original line Diff line number Diff line /* * Copyright (C) 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.backup; import android.app.backup.IBackupManager; import android.app.backup.IFullBackupRestoreObserver; import android.app.backup.IRestoreSession; import android.content.Context; import android.content.Intent; import android.os.Binder; import android.os.Environment; import android.os.IBinder; import android.os.ParcelFileDescriptor; import android.os.Process; import android.os.RemoteException; import android.os.SystemProperties; import android.os.UserHandle; import android.util.Slog; import java.io.File; import java.io.FileDescriptor; import java.io.IOException; import java.io.PrintWriter; public class Trampoline extends IBackupManager.Stub { static final String TAG = "BackupManagerService"; static final boolean DEBUG_TRAMPOLINE = false; // When this file is present, the backup service is inactive static final String BACKUP_SUPPRESS_FILENAME = "backup-suppress"; // Product-level suppression of backup/restore static final String BACKUP_DISABLE_PROPERTY = "ro.backup.disable"; final Context mContext; final File mSuppressFile; // existence testing & creating synchronized on 'this' final boolean mGlobalDisable; volatile BackupManagerService mService; public Trampoline(Context context) { mContext = context; File dir = new File(Environment.getSecureDataDirectory(), "backup"); dir.mkdirs(); mSuppressFile = new File(dir, BACKUP_SUPPRESS_FILENAME); mGlobalDisable = SystemProperties.getBoolean(BACKUP_DISABLE_PROPERTY, false); } // internal control API public void initialize(final int whichUser) { // Note that only the owner user is currently involved in backup/restore if (whichUser == UserHandle.USER_OWNER) { // Does this product support backup/restore at all? if (mGlobalDisable) { Slog.i(TAG, "Backup/restore not supported"); return; } synchronized (this) { if (!mSuppressFile.exists()) { mService = new BackupManagerService(mContext, this); } else { Slog.i(TAG, "Backup inactive in user " + whichUser); } } } } public void setBackupServiceActive(final int userHandle, boolean makeActive) { // Only the DPM should be changing the active state of backup final int caller = Binder.getCallingUid(); if (caller != Process.SYSTEM_UID && caller != Process.ROOT_UID) { throw new SecurityException("No permission to configure backup activity"); } if (mGlobalDisable) { Slog.i(TAG, "Backup/restore not supported"); return; } if (userHandle == UserHandle.USER_OWNER) { synchronized (this) { if (makeActive != (mService != null)) { Slog.i(TAG, "Making backup " + (makeActive ? "" : "in") + "active in user " + userHandle); if (makeActive) { mService = new BackupManagerService(mContext, this); mSuppressFile.delete(); } else { mService = null; try { mSuppressFile.createNewFile(); } catch (IOException e) { Slog.e(TAG, "Unable to persist backup service inactivity"); } } } } } } // IBackupManager binder API @Override public void dataChanged(String packageName) throws RemoteException { BackupManagerService svc = mService; if (svc != null) { svc.dataChanged(packageName); } } @Override public void clearBackupData(String transportName, String packageName) throws RemoteException { BackupManagerService svc = mService; if (svc != null) { svc.clearBackupData(transportName, packageName); } } @Override public void agentConnected(String packageName, IBinder agent) throws RemoteException { BackupManagerService svc = mService; if (svc != null) { svc.agentConnected(packageName, agent); } } @Override public void agentDisconnected(String packageName) throws RemoteException { BackupManagerService svc = mService; if (svc != null) { svc.agentDisconnected(packageName); } } @Override public void restoreAtInstall(String packageName, int token) throws RemoteException { BackupManagerService svc = mService; if (svc != null) { svc.restoreAtInstall(packageName, token); } } @Override public void setBackupEnabled(boolean isEnabled) throws RemoteException { BackupManagerService svc = mService; if (svc != null) { svc.setBackupEnabled(isEnabled); } } @Override public void setAutoRestore(boolean doAutoRestore) throws RemoteException { BackupManagerService svc = mService; if (svc != null) { svc.setAutoRestore(doAutoRestore); } } @Override public void setBackupProvisioned(boolean isProvisioned) throws RemoteException { BackupManagerService svc = mService; if (svc != null) { svc.setBackupProvisioned(isProvisioned); } } @Override public boolean isBackupEnabled() throws RemoteException { BackupManagerService svc = mService; return (svc != null) ? svc.isBackupEnabled() : false; } @Override public boolean setBackupPassword(String currentPw, String newPw) throws RemoteException { BackupManagerService svc = mService; return (svc != null) ? svc.setBackupPassword(currentPw, newPw) : false; } @Override public boolean hasBackupPassword() throws RemoteException { BackupManagerService svc = mService; return (svc != null) ? svc.hasBackupPassword() : false; } @Override public void backupNow() throws RemoteException { BackupManagerService svc = mService; if (svc != null) { svc.backupNow(); } } @Override public void fullBackup(ParcelFileDescriptor fd, boolean includeApks, boolean includeObbs, boolean includeShared, boolean doWidgets, boolean allApps, boolean allIncludesSystem, boolean doCompress, String[] packageNames) throws RemoteException { BackupManagerService svc = mService; if (svc != null) { svc.fullBackup(fd, includeApks, includeObbs, includeShared, doWidgets, allApps, allIncludesSystem, doCompress, packageNames); } } @Override public void fullTransportBackup(String[] packageNames) throws RemoteException { BackupManagerService svc = mService; if (svc != null) { svc.fullTransportBackup(packageNames); } } @Override public void fullRestore(ParcelFileDescriptor fd) throws RemoteException { BackupManagerService svc = mService; if (svc != null) { svc.fullRestore(fd); } } @Override public void acknowledgeFullBackupOrRestore(int token, boolean allow, String curPassword, String encryptionPassword, IFullBackupRestoreObserver observer) throws RemoteException { BackupManagerService svc = mService; if (svc != null) { svc.acknowledgeFullBackupOrRestore(token, allow, curPassword, encryptionPassword, observer); } } @Override public String getCurrentTransport() throws RemoteException { BackupManagerService svc = mService; return (svc != null) ? svc.getCurrentTransport() : null; } @Override public String[] listAllTransports() throws RemoteException { BackupManagerService svc = mService; return (svc != null) ? svc.listAllTransports() : null; } @Override public String selectBackupTransport(String transport) throws RemoteException { BackupManagerService svc = mService; return (svc != null) ? svc.selectBackupTransport(transport) : null; } @Override public Intent getConfigurationIntent(String transport) throws RemoteException { BackupManagerService svc = mService; return (svc != null) ? svc.getConfigurationIntent(transport) : null; } @Override public String getDestinationString(String transport) throws RemoteException { BackupManagerService svc = mService; return (svc != null) ? svc.getDestinationString(transport) : null; } @Override public Intent getDataManagementIntent(String transport) throws RemoteException { BackupManagerService svc = mService; return (svc != null) ? svc.getDataManagementIntent(transport) : null; } @Override public String getDataManagementLabel(String transport) throws RemoteException { BackupManagerService svc = mService; return (svc != null) ? svc.getDataManagementLabel(transport) : null; } @Override public IRestoreSession beginRestoreSession(String packageName, String transportID) throws RemoteException { BackupManagerService svc = mService; return (svc != null) ? svc.beginRestoreSession(packageName, transportID) : null; } @Override public void opComplete(int token) throws RemoteException { BackupManagerService svc = mService; if (svc != null) { svc.opComplete(token); } } @Override public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { BackupManagerService svc = mService; if (svc != null) { svc.dump(fd, pw, args); } else { pw.println("Inactive"); } } // Full backup/restore entry points - non-Binder; called directly // by the full-backup scheduled job /* package */ boolean beginFullBackup(FullBackupJob scheduledJob) { BackupManagerService svc = mService; return (svc != null) ? svc.beginFullBackup(scheduledJob) : false; } /* package */ void endFullBackup() { BackupManagerService svc = mService; if (svc != null) { svc.endFullBackup(); } } } Loading
core/java/android/app/backup/IBackupManager.aidl +12 −0 Original line number Original line Diff line number Diff line Loading @@ -291,4 +291,16 @@ interface IBackupManager { * {@hide} * {@hide} */ */ void opComplete(int token); void opComplete(int token); /** * Make the device's backup and restore machinery (in)active. When it is inactive, * the device will not perform any backup operations, nor will it deliver data for * restore, although clients can still safely call BackupManager methods. * * @param whichUser User handle of the defined user whose backup active state * is to be adjusted. * @param makeActive {@code true} when backup services are to be made active; * {@code false} otherwise. */ void setBackupServiceActive(int whichUser, boolean makeActive); } }
services/backup/java/com/android/server/backup/BackupManagerService.java +19 −18 Original line number Original line Diff line number Diff line Loading @@ -153,7 +153,7 @@ import javax.crypto.spec.SecretKeySpec; import libcore.io.IoUtils; import libcore.io.IoUtils; public class BackupManagerService extends IBackupManager.Stub { public class BackupManagerService { private static final String TAG = "BackupManagerService"; private static final String TAG = "BackupManagerService"; private static final boolean DEBUG = true; private static final boolean DEBUG = true; Loading Loading @@ -322,8 +322,12 @@ public class BackupManagerService extends IBackupManager.Stub { // Watch the device provisioning operation during setup // Watch the device provisioning operation during setup ContentObserver mProvisionedObserver; ContentObserver mProvisionedObserver; static BackupManagerService sInstance; // The published binder is actually to a singleton trampoline object that calls static BackupManagerService getInstance() { // through to the proper code. This indirection lets us turn down the heavy // implementation object on the fly without disturbing binders that have been // cached elsewhere in the system. static Trampoline sInstance; static Trampoline getInstance() { // Always constructed during system bringup, so no need to lazy-init // Always constructed during system bringup, so no need to lazy-init return sInstance; return sInstance; } } Loading @@ -332,7 +336,7 @@ public class BackupManagerService extends IBackupManager.Stub { public Lifecycle(Context context) { public Lifecycle(Context context) { super(context); super(context); sInstance = new BackupManagerService(context); sInstance = new Trampoline(context); } } @Override @Override Loading @@ -342,11 +346,17 @@ public class BackupManagerService extends IBackupManager.Stub { @Override @Override public void onBootPhase(int phase) { public void onBootPhase(int phase) { if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) { if (phase == PHASE_SYSTEM_SERVICES_READY) { sInstance.initialize(UserHandle.USER_OWNER); } else if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) { ContentResolver r = sInstance.mContext.getContentResolver(); ContentResolver r = sInstance.mContext.getContentResolver(); boolean areEnabled = Settings.Secure.getInt(r, boolean areEnabled = Settings.Secure.getInt(r, Settings.Secure.BACKUP_ENABLED, 0) != 0; Settings.Secure.BACKUP_ENABLED, 0) != 0; try { sInstance.setBackupEnabled(areEnabled); sInstance.setBackupEnabled(areEnabled); } catch (RemoteException e) { // can't happen; it's a local object } } } } } } } Loading Loading @@ -934,7 +944,7 @@ public class BackupManagerService extends IBackupManager.Stub { // ----- Main service implementation ----- // ----- Main service implementation ----- public BackupManagerService(Context context) { public BackupManagerService(Context context, Trampoline parent) { mContext = context; mContext = context; mPackageManager = context.getPackageManager(); mPackageManager = context.getPackageManager(); mPackageManagerBinder = AppGlobals.getPackageManager(); mPackageManagerBinder = AppGlobals.getPackageManager(); Loading @@ -944,7 +954,7 @@ public class BackupManagerService extends IBackupManager.Stub { mPowerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE); mPowerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE); mMountService = IMountService.Stub.asInterface(ServiceManager.getService("mount")); mMountService = IMountService.Stub.asInterface(ServiceManager.getService("mount")); mBackupManagerBinder = asInterface(asBinder()); mBackupManagerBinder = Trampoline.asInterface(parent.asBinder()); // spin up the backup/restore handler thread // spin up the backup/restore handler thread mHandlerThread = new HandlerThread("backup", Process.THREAD_PRIORITY_BACKGROUND); mHandlerThread = new HandlerThread("backup", Process.THREAD_PRIORITY_BACKGROUND); Loading Loading @@ -1451,7 +1461,6 @@ public class BackupManagerService extends IBackupManager.Stub { return false; return false; } } @Override public boolean setBackupPassword(String currentPw, String newPw) { public boolean setBackupPassword(String currentPw, String newPw) { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP, mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP, "setBackupPassword"); "setBackupPassword"); Loading Loading @@ -1532,7 +1541,6 @@ public class BackupManagerService extends IBackupManager.Stub { return false; return false; } } @Override public boolean hasBackupPassword() { public boolean hasBackupPassword() { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP, mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP, "hasBackupPassword"); "hasBackupPassword"); Loading Loading @@ -8145,7 +8153,6 @@ if (MORE_DEBUG) Slog.v(TAG, " + got " + nRead + "; now wanting " + (size - soF // // // This is the variant used by 'adb backup'; it requires on-screen confirmation // This is the variant used by 'adb backup'; it requires on-screen confirmation // by the user because it can be used to offload data over untrusted USB. // by the user because it can be used to offload data over untrusted USB. @Override public void fullBackup(ParcelFileDescriptor fd, boolean includeApks, public void fullBackup(ParcelFileDescriptor fd, boolean includeApks, boolean includeObbs, boolean includeShared, boolean doWidgets, boolean includeObbs, boolean includeShared, boolean doWidgets, boolean doAllApps, boolean includeSystem, boolean compress, String[] pkgList) { boolean doAllApps, boolean includeSystem, boolean compress, String[] pkgList) { Loading Loading @@ -8217,7 +8224,6 @@ if (MORE_DEBUG) Slog.v(TAG, " + got " + nRead + "; now wanting " + (size - soF } } } } @Override public void fullTransportBackup(String[] pkgNames) { public void fullTransportBackup(String[] pkgNames) { mContext.enforceCallingPermission(android.Manifest.permission.BACKUP, mContext.enforceCallingPermission(android.Manifest.permission.BACKUP, "fullTransportBackup"); "fullTransportBackup"); Loading Loading @@ -8247,7 +8253,6 @@ if (MORE_DEBUG) Slog.v(TAG, " + got " + nRead + "; now wanting " + (size - soF } } } } @Override public void fullRestore(ParcelFileDescriptor fd) { public void fullRestore(ParcelFileDescriptor fd) { mContext.enforceCallingPermission(android.Manifest.permission.BACKUP, "fullRestore"); mContext.enforceCallingPermission(android.Manifest.permission.BACKUP, "fullRestore"); Loading Loading @@ -8343,7 +8348,6 @@ if (MORE_DEBUG) Slog.v(TAG, " + got " + nRead + "; now wanting " + (size - soF // Confirm that the previously-requested full backup/restore operation can proceed. This // Confirm that the previously-requested full backup/restore operation can proceed. This // is used to require a user-facing disclosure about the operation. // is used to require a user-facing disclosure about the operation. @Override public void acknowledgeFullBackupOrRestore(int token, boolean allow, public void acknowledgeFullBackupOrRestore(int token, boolean allow, String curPassword, String encPpassword, IFullBackupRestoreObserver observer) { String curPassword, String encPpassword, IFullBackupRestoreObserver observer) { if (DEBUG) Slog.d(TAG, "acknowledgeFullBackupOrRestore : token=" + token if (DEBUG) Slog.d(TAG, "acknowledgeFullBackupOrRestore : token=" + token Loading Loading @@ -8391,8 +8395,7 @@ if (MORE_DEBUG) Slog.v(TAG, " + got " + nRead + "; now wanting " + (size - soF } } } } // Enable/disable the backup service // Enable/disable backups @Override public void setBackupEnabled(boolean enable) { public void setBackupEnabled(boolean enable) { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP, mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP, "setBackupEnabled"); "setBackupEnabled"); Loading Loading @@ -8798,7 +8801,6 @@ if (MORE_DEBUG) Slog.v(TAG, " + got " + nRead + "; now wanting " + (size - soF // Note that a currently-active backup agent has notified us that it has // Note that a currently-active backup agent has notified us that it has // completed the given outstanding asynchronous backup/restore operation. // completed the given outstanding asynchronous backup/restore operation. @Override public void opComplete(int token) { public void opComplete(int token) { if (MORE_DEBUG) Slog.v(TAG, "opComplete: " + Integer.toHexString(token)); if (MORE_DEBUG) Slog.v(TAG, "opComplete: " + Integer.toHexString(token)); Operation op = null; Operation op = null; Loading Loading @@ -9147,7 +9149,6 @@ if (MORE_DEBUG) Slog.v(TAG, " + got " + nRead + "; now wanting " + (size - soF } } } } @Override public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG); mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG); Loading
services/backup/java/com/android/server/backup/FullBackupJob.java +2 −2 Original line number Original line Diff line number Diff line Loading @@ -59,7 +59,7 @@ public class FullBackupJob extends JobService { @Override @Override public boolean onStartJob(JobParameters params) { public boolean onStartJob(JobParameters params) { mParams = params; mParams = params; BackupManagerService service = BackupManagerService.getInstance(); Trampoline service = BackupManagerService.getInstance(); return service.beginFullBackup(this); return service.beginFullBackup(this); } } Loading @@ -67,7 +67,7 @@ public class FullBackupJob extends JobService { public boolean onStopJob(JobParameters params) { public boolean onStopJob(JobParameters params) { if (mParams != null) { if (mParams != null) { mParams = null; mParams = null; BackupManagerService service = BackupManagerService.getInstance(); Trampoline service = BackupManagerService.getInstance(); service.endFullBackup(); service.endFullBackup(); } } return false; return false; Loading
services/backup/java/com/android/server/backup/Trampoline.java 0 → 100644 +327 −0 Original line number Original line Diff line number Diff line /* * Copyright (C) 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.backup; import android.app.backup.IBackupManager; import android.app.backup.IFullBackupRestoreObserver; import android.app.backup.IRestoreSession; import android.content.Context; import android.content.Intent; import android.os.Binder; import android.os.Environment; import android.os.IBinder; import android.os.ParcelFileDescriptor; import android.os.Process; import android.os.RemoteException; import android.os.SystemProperties; import android.os.UserHandle; import android.util.Slog; import java.io.File; import java.io.FileDescriptor; import java.io.IOException; import java.io.PrintWriter; public class Trampoline extends IBackupManager.Stub { static final String TAG = "BackupManagerService"; static final boolean DEBUG_TRAMPOLINE = false; // When this file is present, the backup service is inactive static final String BACKUP_SUPPRESS_FILENAME = "backup-suppress"; // Product-level suppression of backup/restore static final String BACKUP_DISABLE_PROPERTY = "ro.backup.disable"; final Context mContext; final File mSuppressFile; // existence testing & creating synchronized on 'this' final boolean mGlobalDisable; volatile BackupManagerService mService; public Trampoline(Context context) { mContext = context; File dir = new File(Environment.getSecureDataDirectory(), "backup"); dir.mkdirs(); mSuppressFile = new File(dir, BACKUP_SUPPRESS_FILENAME); mGlobalDisable = SystemProperties.getBoolean(BACKUP_DISABLE_PROPERTY, false); } // internal control API public void initialize(final int whichUser) { // Note that only the owner user is currently involved in backup/restore if (whichUser == UserHandle.USER_OWNER) { // Does this product support backup/restore at all? if (mGlobalDisable) { Slog.i(TAG, "Backup/restore not supported"); return; } synchronized (this) { if (!mSuppressFile.exists()) { mService = new BackupManagerService(mContext, this); } else { Slog.i(TAG, "Backup inactive in user " + whichUser); } } } } public void setBackupServiceActive(final int userHandle, boolean makeActive) { // Only the DPM should be changing the active state of backup final int caller = Binder.getCallingUid(); if (caller != Process.SYSTEM_UID && caller != Process.ROOT_UID) { throw new SecurityException("No permission to configure backup activity"); } if (mGlobalDisable) { Slog.i(TAG, "Backup/restore not supported"); return; } if (userHandle == UserHandle.USER_OWNER) { synchronized (this) { if (makeActive != (mService != null)) { Slog.i(TAG, "Making backup " + (makeActive ? "" : "in") + "active in user " + userHandle); if (makeActive) { mService = new BackupManagerService(mContext, this); mSuppressFile.delete(); } else { mService = null; try { mSuppressFile.createNewFile(); } catch (IOException e) { Slog.e(TAG, "Unable to persist backup service inactivity"); } } } } } } // IBackupManager binder API @Override public void dataChanged(String packageName) throws RemoteException { BackupManagerService svc = mService; if (svc != null) { svc.dataChanged(packageName); } } @Override public void clearBackupData(String transportName, String packageName) throws RemoteException { BackupManagerService svc = mService; if (svc != null) { svc.clearBackupData(transportName, packageName); } } @Override public void agentConnected(String packageName, IBinder agent) throws RemoteException { BackupManagerService svc = mService; if (svc != null) { svc.agentConnected(packageName, agent); } } @Override public void agentDisconnected(String packageName) throws RemoteException { BackupManagerService svc = mService; if (svc != null) { svc.agentDisconnected(packageName); } } @Override public void restoreAtInstall(String packageName, int token) throws RemoteException { BackupManagerService svc = mService; if (svc != null) { svc.restoreAtInstall(packageName, token); } } @Override public void setBackupEnabled(boolean isEnabled) throws RemoteException { BackupManagerService svc = mService; if (svc != null) { svc.setBackupEnabled(isEnabled); } } @Override public void setAutoRestore(boolean doAutoRestore) throws RemoteException { BackupManagerService svc = mService; if (svc != null) { svc.setAutoRestore(doAutoRestore); } } @Override public void setBackupProvisioned(boolean isProvisioned) throws RemoteException { BackupManagerService svc = mService; if (svc != null) { svc.setBackupProvisioned(isProvisioned); } } @Override public boolean isBackupEnabled() throws RemoteException { BackupManagerService svc = mService; return (svc != null) ? svc.isBackupEnabled() : false; } @Override public boolean setBackupPassword(String currentPw, String newPw) throws RemoteException { BackupManagerService svc = mService; return (svc != null) ? svc.setBackupPassword(currentPw, newPw) : false; } @Override public boolean hasBackupPassword() throws RemoteException { BackupManagerService svc = mService; return (svc != null) ? svc.hasBackupPassword() : false; } @Override public void backupNow() throws RemoteException { BackupManagerService svc = mService; if (svc != null) { svc.backupNow(); } } @Override public void fullBackup(ParcelFileDescriptor fd, boolean includeApks, boolean includeObbs, boolean includeShared, boolean doWidgets, boolean allApps, boolean allIncludesSystem, boolean doCompress, String[] packageNames) throws RemoteException { BackupManagerService svc = mService; if (svc != null) { svc.fullBackup(fd, includeApks, includeObbs, includeShared, doWidgets, allApps, allIncludesSystem, doCompress, packageNames); } } @Override public void fullTransportBackup(String[] packageNames) throws RemoteException { BackupManagerService svc = mService; if (svc != null) { svc.fullTransportBackup(packageNames); } } @Override public void fullRestore(ParcelFileDescriptor fd) throws RemoteException { BackupManagerService svc = mService; if (svc != null) { svc.fullRestore(fd); } } @Override public void acknowledgeFullBackupOrRestore(int token, boolean allow, String curPassword, String encryptionPassword, IFullBackupRestoreObserver observer) throws RemoteException { BackupManagerService svc = mService; if (svc != null) { svc.acknowledgeFullBackupOrRestore(token, allow, curPassword, encryptionPassword, observer); } } @Override public String getCurrentTransport() throws RemoteException { BackupManagerService svc = mService; return (svc != null) ? svc.getCurrentTransport() : null; } @Override public String[] listAllTransports() throws RemoteException { BackupManagerService svc = mService; return (svc != null) ? svc.listAllTransports() : null; } @Override public String selectBackupTransport(String transport) throws RemoteException { BackupManagerService svc = mService; return (svc != null) ? svc.selectBackupTransport(transport) : null; } @Override public Intent getConfigurationIntent(String transport) throws RemoteException { BackupManagerService svc = mService; return (svc != null) ? svc.getConfigurationIntent(transport) : null; } @Override public String getDestinationString(String transport) throws RemoteException { BackupManagerService svc = mService; return (svc != null) ? svc.getDestinationString(transport) : null; } @Override public Intent getDataManagementIntent(String transport) throws RemoteException { BackupManagerService svc = mService; return (svc != null) ? svc.getDataManagementIntent(transport) : null; } @Override public String getDataManagementLabel(String transport) throws RemoteException { BackupManagerService svc = mService; return (svc != null) ? svc.getDataManagementLabel(transport) : null; } @Override public IRestoreSession beginRestoreSession(String packageName, String transportID) throws RemoteException { BackupManagerService svc = mService; return (svc != null) ? svc.beginRestoreSession(packageName, transportID) : null; } @Override public void opComplete(int token) throws RemoteException { BackupManagerService svc = mService; if (svc != null) { svc.opComplete(token); } } @Override public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { BackupManagerService svc = mService; if (svc != null) { svc.dump(fd, pw, args); } else { pw.println("Inactive"); } } // Full backup/restore entry points - non-Binder; called directly // by the full-backup scheduled job /* package */ boolean beginFullBackup(FullBackupJob scheduledJob) { BackupManagerService svc = mService; return (svc != null) ? svc.beginFullBackup(scheduledJob) : false; } /* package */ void endFullBackup() { BackupManagerService svc = mService; if (svc != null) { svc.endFullBackup(); } } }