Loading services/backup/java/com/android/server/backup/UserBackupManagerService.java +37 −0 Original line number Original line Diff line number Diff line Loading @@ -318,6 +318,9 @@ public class UserBackupManagerService { private static final String SERIAL_ID_FILE = "serial_id"; private static final String SERIAL_ID_FILE = "serial_id"; private static final String SKIP_USER_FACING_DATA = "backup_skip_user_facing_data"; private static final String WALLPAPER_PACKAGE = "com.android.wallpaperbackup"; private final @UserIdInt int mUserId; private final @UserIdInt int mUserId; private final BackupAgentTimeoutParameters mAgentTimeoutParameters; private final BackupAgentTimeoutParameters mAgentTimeoutParameters; private final TransportManager mTransportManager; private final TransportManager mTransportManager; Loading Loading @@ -3553,6 +3556,40 @@ public class UserBackupManagerService { } } } } /** * We want to skip backup/restore of certain packages if 'backup_skip_user_facing_data' is * set to true in secure settings. See b/153940088 for details. * * TODO(b/154822946): Remove this logic in the next release. */ public List<PackageInfo> filterUserFacingPackages(List<PackageInfo> packages) { if (!shouldSkipUserFacingData()) { return packages; } List<PackageInfo> filteredPackages = new ArrayList<>(packages.size()); for (PackageInfo packageInfo : packages) { if (!shouldSkipPackage(packageInfo.packageName)) { filteredPackages.add(packageInfo); } else { Slog.i(TAG, "Will skip backup/restore for " + packageInfo.packageName); } } return filteredPackages; } @VisibleForTesting public boolean shouldSkipUserFacingData() { return Settings.Secure.getInt(mContext.getContentResolver(), SKIP_USER_FACING_DATA, /* def */ 0) != 0; } @VisibleForTesting public boolean shouldSkipPackage(String packageName) { return WALLPAPER_PACKAGE.equals(packageName); } private void updateStateForTransport(String newTransportName) { private void updateStateForTransport(String newTransportName) { // Publish the name change // Publish the name change Settings.Secure.putStringForUser(mContext.getContentResolver(), Settings.Secure.putStringForUser(mContext.getContentResolver(), Loading services/backup/java/com/android/server/backup/fullbackup/PerformFullTransportBackupTask.java +4 −1 Original line number Original line Diff line number Diff line Loading @@ -61,6 +61,7 @@ import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.IOException; import java.util.ArrayList; import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.Objects; import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit; Loading Loading @@ -131,7 +132,7 @@ public class PerformFullTransportBackupTask extends FullBackupTask implements Ba private UserBackupManagerService mUserBackupManagerService; private UserBackupManagerService mUserBackupManagerService; private final Object mCancelLock = new Object(); private final Object mCancelLock = new Object(); ArrayList<PackageInfo> mPackages; List<PackageInfo> mPackages; PackageInfo mCurrentPackage; PackageInfo mCurrentPackage; boolean mUpdateSchedule; boolean mUpdateSchedule; CountDownLatch mLatch; CountDownLatch mLatch; Loading Loading @@ -249,6 +250,8 @@ public class PerformFullTransportBackupTask extends FullBackupTask implements Ba null); null); } } } } mPackages = backupManagerService.filterUserFacingPackages(mPackages); } } private void registerTask() { private void registerTask() { Loading services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java +2 −0 Original line number Original line Diff line number Diff line Loading @@ -270,6 +270,8 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask { } } } } mAcceptSet = backupManagerService.filterUserFacingPackages(mAcceptSet); if (MORE_DEBUG) { if (MORE_DEBUG) { Slog.v(TAG, "Restore; accept set size is " + mAcceptSet.size()); Slog.v(TAG, "Restore; accept set size is " + mAcceptSet.size()); for (PackageInfo info : mAcceptSet) { for (PackageInfo info : mAcceptSet) { Loading services/robotests/backup/src/com/android/server/backup/UserBackupManagerServiceTest.java +46 −0 Original line number Original line Diff line number Diff line Loading @@ -30,10 +30,13 @@ import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import static org.mockito.Mockito.when; import static org.robolectric.Shadows.shadowOf; import static org.robolectric.Shadows.shadowOf; import static org.testng.Assert.assertFalse; import static org.testng.Assert.assertTrue; import static org.testng.Assert.expectThrows; import static org.testng.Assert.expectThrows; import android.app.backup.BackupManager; import android.app.backup.BackupManager; Loading Loading @@ -86,6 +89,7 @@ import java.io.IOException; import java.io.PrintWriter; import java.io.PrintWriter; import java.io.StringWriter; import java.io.StringWriter; import java.util.ArrayList; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.List; /** /** Loading @@ -104,6 +108,7 @@ public class UserBackupManagerServiceTest { private static final String TAG = "BMSTest"; private static final String TAG = "BMSTest"; private static final String PACKAGE_1 = "some.package.1"; private static final String PACKAGE_1 = "some.package.1"; private static final String PACKAGE_2 = "some.package.2"; private static final String PACKAGE_2 = "some.package.2"; private static final String USER_FACING_PACKAGE = "user.facing.package"; private static final int USER_ID = 10; private static final int USER_ID = 10; @Mock private TransportManager mTransportManager; @Mock private TransportManager mTransportManager; Loading Loading @@ -1186,6 +1191,47 @@ public class UserBackupManagerServiceTest { eq(packageTrackingReceiver), eq(UserHandle.of(USER_ID)), any(), any(), any()); eq(packageTrackingReceiver), eq(UserHandle.of(USER_ID)), any(), any(), any()); } } @Test public void testFilterUserFacingPackages_shouldSkipUserFacing_filtersUserFacing() { List<PackageInfo> packages = Arrays.asList(getPackageInfo(USER_FACING_PACKAGE), getPackageInfo(PACKAGE_1)); UserBackupManagerService backupManagerService = spy( createUserBackupManagerServiceAndRunTasks()); when(backupManagerService.shouldSkipUserFacingData()).thenReturn(true); when(backupManagerService.shouldSkipPackage(eq(USER_FACING_PACKAGE))).thenReturn(true); List<PackageInfo> filteredPackages = backupManagerService.filterUserFacingPackages( packages); assertFalse(containsPackage(filteredPackages, USER_FACING_PACKAGE)); assertTrue(containsPackage(filteredPackages, PACKAGE_1)); } @Test public void testFilterUserFacingPackages_shouldNotSkipUserFacing_doesNotFilterUserFacing() { List<PackageInfo> packages = Arrays.asList(getPackageInfo(USER_FACING_PACKAGE), getPackageInfo(PACKAGE_1)); UserBackupManagerService backupManagerService = spy( createUserBackupManagerServiceAndRunTasks()); when(backupManagerService.shouldSkipUserFacingData()).thenReturn(false); when(backupManagerService.shouldSkipPackage(eq(USER_FACING_PACKAGE))).thenReturn(true); List<PackageInfo> filteredPackages = backupManagerService.filterUserFacingPackages( packages); assertTrue(containsPackage(filteredPackages, USER_FACING_PACKAGE)); assertTrue(containsPackage(filteredPackages, PACKAGE_1)); } private static boolean containsPackage(List<PackageInfo> packages, String targetPackage) { for (PackageInfo packageInfo : packages) { if (targetPackage.equals(packageInfo.packageName)) { return true; } } return false; } private UserBackupManagerService createUserBackupManagerServiceAndRunTasks() { private UserBackupManagerService createUserBackupManagerServiceAndRunTasks() { return BackupManagerServiceTestUtils.createUserBackupManagerServiceAndRunTasks( return BackupManagerServiceTestUtils.createUserBackupManagerServiceAndRunTasks( USER_ID, mContext, mBackupThread, mBaseStateDir, mDataDir, mTransportManager); USER_ID, mContext, mBackupThread, mBaseStateDir, mDataDir, mTransportManager); Loading Loading
services/backup/java/com/android/server/backup/UserBackupManagerService.java +37 −0 Original line number Original line Diff line number Diff line Loading @@ -318,6 +318,9 @@ public class UserBackupManagerService { private static final String SERIAL_ID_FILE = "serial_id"; private static final String SERIAL_ID_FILE = "serial_id"; private static final String SKIP_USER_FACING_DATA = "backup_skip_user_facing_data"; private static final String WALLPAPER_PACKAGE = "com.android.wallpaperbackup"; private final @UserIdInt int mUserId; private final @UserIdInt int mUserId; private final BackupAgentTimeoutParameters mAgentTimeoutParameters; private final BackupAgentTimeoutParameters mAgentTimeoutParameters; private final TransportManager mTransportManager; private final TransportManager mTransportManager; Loading Loading @@ -3553,6 +3556,40 @@ public class UserBackupManagerService { } } } } /** * We want to skip backup/restore of certain packages if 'backup_skip_user_facing_data' is * set to true in secure settings. See b/153940088 for details. * * TODO(b/154822946): Remove this logic in the next release. */ public List<PackageInfo> filterUserFacingPackages(List<PackageInfo> packages) { if (!shouldSkipUserFacingData()) { return packages; } List<PackageInfo> filteredPackages = new ArrayList<>(packages.size()); for (PackageInfo packageInfo : packages) { if (!shouldSkipPackage(packageInfo.packageName)) { filteredPackages.add(packageInfo); } else { Slog.i(TAG, "Will skip backup/restore for " + packageInfo.packageName); } } return filteredPackages; } @VisibleForTesting public boolean shouldSkipUserFacingData() { return Settings.Secure.getInt(mContext.getContentResolver(), SKIP_USER_FACING_DATA, /* def */ 0) != 0; } @VisibleForTesting public boolean shouldSkipPackage(String packageName) { return WALLPAPER_PACKAGE.equals(packageName); } private void updateStateForTransport(String newTransportName) { private void updateStateForTransport(String newTransportName) { // Publish the name change // Publish the name change Settings.Secure.putStringForUser(mContext.getContentResolver(), Settings.Secure.putStringForUser(mContext.getContentResolver(), Loading
services/backup/java/com/android/server/backup/fullbackup/PerformFullTransportBackupTask.java +4 −1 Original line number Original line Diff line number Diff line Loading @@ -61,6 +61,7 @@ import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.IOException; import java.util.ArrayList; import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.Objects; import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit; Loading Loading @@ -131,7 +132,7 @@ public class PerformFullTransportBackupTask extends FullBackupTask implements Ba private UserBackupManagerService mUserBackupManagerService; private UserBackupManagerService mUserBackupManagerService; private final Object mCancelLock = new Object(); private final Object mCancelLock = new Object(); ArrayList<PackageInfo> mPackages; List<PackageInfo> mPackages; PackageInfo mCurrentPackage; PackageInfo mCurrentPackage; boolean mUpdateSchedule; boolean mUpdateSchedule; CountDownLatch mLatch; CountDownLatch mLatch; Loading Loading @@ -249,6 +250,8 @@ public class PerformFullTransportBackupTask extends FullBackupTask implements Ba null); null); } } } } mPackages = backupManagerService.filterUserFacingPackages(mPackages); } } private void registerTask() { private void registerTask() { Loading
services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java +2 −0 Original line number Original line Diff line number Diff line Loading @@ -270,6 +270,8 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask { } } } } mAcceptSet = backupManagerService.filterUserFacingPackages(mAcceptSet); if (MORE_DEBUG) { if (MORE_DEBUG) { Slog.v(TAG, "Restore; accept set size is " + mAcceptSet.size()); Slog.v(TAG, "Restore; accept set size is " + mAcceptSet.size()); for (PackageInfo info : mAcceptSet) { for (PackageInfo info : mAcceptSet) { Loading
services/robotests/backup/src/com/android/server/backup/UserBackupManagerServiceTest.java +46 −0 Original line number Original line Diff line number Diff line Loading @@ -30,10 +30,13 @@ import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import static org.mockito.Mockito.when; import static org.robolectric.Shadows.shadowOf; import static org.robolectric.Shadows.shadowOf; import static org.testng.Assert.assertFalse; import static org.testng.Assert.assertTrue; import static org.testng.Assert.expectThrows; import static org.testng.Assert.expectThrows; import android.app.backup.BackupManager; import android.app.backup.BackupManager; Loading Loading @@ -86,6 +89,7 @@ import java.io.IOException; import java.io.PrintWriter; import java.io.PrintWriter; import java.io.StringWriter; import java.io.StringWriter; import java.util.ArrayList; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.List; /** /** Loading @@ -104,6 +108,7 @@ public class UserBackupManagerServiceTest { private static final String TAG = "BMSTest"; private static final String TAG = "BMSTest"; private static final String PACKAGE_1 = "some.package.1"; private static final String PACKAGE_1 = "some.package.1"; private static final String PACKAGE_2 = "some.package.2"; private static final String PACKAGE_2 = "some.package.2"; private static final String USER_FACING_PACKAGE = "user.facing.package"; private static final int USER_ID = 10; private static final int USER_ID = 10; @Mock private TransportManager mTransportManager; @Mock private TransportManager mTransportManager; Loading Loading @@ -1186,6 +1191,47 @@ public class UserBackupManagerServiceTest { eq(packageTrackingReceiver), eq(UserHandle.of(USER_ID)), any(), any(), any()); eq(packageTrackingReceiver), eq(UserHandle.of(USER_ID)), any(), any(), any()); } } @Test public void testFilterUserFacingPackages_shouldSkipUserFacing_filtersUserFacing() { List<PackageInfo> packages = Arrays.asList(getPackageInfo(USER_FACING_PACKAGE), getPackageInfo(PACKAGE_1)); UserBackupManagerService backupManagerService = spy( createUserBackupManagerServiceAndRunTasks()); when(backupManagerService.shouldSkipUserFacingData()).thenReturn(true); when(backupManagerService.shouldSkipPackage(eq(USER_FACING_PACKAGE))).thenReturn(true); List<PackageInfo> filteredPackages = backupManagerService.filterUserFacingPackages( packages); assertFalse(containsPackage(filteredPackages, USER_FACING_PACKAGE)); assertTrue(containsPackage(filteredPackages, PACKAGE_1)); } @Test public void testFilterUserFacingPackages_shouldNotSkipUserFacing_doesNotFilterUserFacing() { List<PackageInfo> packages = Arrays.asList(getPackageInfo(USER_FACING_PACKAGE), getPackageInfo(PACKAGE_1)); UserBackupManagerService backupManagerService = spy( createUserBackupManagerServiceAndRunTasks()); when(backupManagerService.shouldSkipUserFacingData()).thenReturn(false); when(backupManagerService.shouldSkipPackage(eq(USER_FACING_PACKAGE))).thenReturn(true); List<PackageInfo> filteredPackages = backupManagerService.filterUserFacingPackages( packages); assertTrue(containsPackage(filteredPackages, USER_FACING_PACKAGE)); assertTrue(containsPackage(filteredPackages, PACKAGE_1)); } private static boolean containsPackage(List<PackageInfo> packages, String targetPackage) { for (PackageInfo packageInfo : packages) { if (targetPackage.equals(packageInfo.packageName)) { return true; } } return false; } private UserBackupManagerService createUserBackupManagerServiceAndRunTasks() { private UserBackupManagerService createUserBackupManagerServiceAndRunTasks() { return BackupManagerServiceTestUtils.createUserBackupManagerServiceAndRunTasks( return BackupManagerServiceTestUtils.createUserBackupManagerServiceAndRunTasks( USER_ID, mContext, mBackupThread, mBaseStateDir, mDataDir, mTransportManager); USER_ID, mContext, mBackupThread, mBaseStateDir, mDataDir, mTransportManager); Loading