Merge "Do not write backup enabled status to file on init"
This commit is contained in:
committed by
Android (Google) Code Review
commit
7a3ff432a7
@@ -157,7 +157,6 @@ import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Queue;
|
||||
import java.util.Random;
|
||||
@@ -316,7 +315,7 @@ public class UserBackupManagerService {
|
||||
|
||||
private final IBackupManager mBackupManagerBinder;
|
||||
|
||||
private boolean mEnabled; // access to this is synchronized on 'this'
|
||||
private boolean mEnabled; // writes to this are synchronized on 'this'
|
||||
private boolean mSetupComplete;
|
||||
private boolean mAutoRestore;
|
||||
|
||||
@@ -508,6 +507,36 @@ public class UserBackupManagerService {
|
||||
!= 0;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
UserBackupManagerService(Context context) {
|
||||
mContext = context;
|
||||
|
||||
mUserId = 0;
|
||||
mRegisterTransportsRequestedTime = 0;
|
||||
|
||||
mBaseStateDir = null;
|
||||
mDataDir = null;
|
||||
mJournalDir = null;
|
||||
mFullBackupScheduleFile = null;
|
||||
mSetupObserver = null;
|
||||
mRunInitReceiver = null;
|
||||
mRunInitIntent = null;
|
||||
mAgentTimeoutParameters = null;
|
||||
mTransportManager = null;
|
||||
mPackageManager = null;
|
||||
mActivityManagerInternal = null;
|
||||
mAlarmManager = null;
|
||||
mConstants = null;
|
||||
mWakelock = null;
|
||||
mBackupHandler = null;
|
||||
mBackupPreferences = null;
|
||||
mBackupPasswordManager = null;
|
||||
mPackageManagerBinder = null;
|
||||
mActivityManager = null;
|
||||
mStorageManager = null;
|
||||
mBackupManagerBinder = null;
|
||||
}
|
||||
|
||||
private UserBackupManagerService(
|
||||
@UserIdInt int userId,
|
||||
Context context,
|
||||
@@ -627,9 +656,11 @@ public class UserBackupManagerService {
|
||||
initPackageTracking();
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void initializeBackupEnableState() {
|
||||
boolean isEnabled = UserBackupManagerFilePersistedSettings.readBackupEnableState(mUserId);
|
||||
setBackupEnabled(isEnabled);
|
||||
boolean isEnabled = readEnabledState();
|
||||
// Don't persist value to disk since we just read it from there.
|
||||
setBackupEnabled(isEnabled, /* persistToDisk */ false);
|
||||
}
|
||||
|
||||
/** Cleans up state when the user of this service is stopped. */
|
||||
@@ -2855,6 +2886,10 @@ public class UserBackupManagerService {
|
||||
|
||||
/** User-configurable enabling/disabling of backups. */
|
||||
public void setBackupEnabled(boolean enable) {
|
||||
setBackupEnabled(enable, /* persistToDisk */ true);
|
||||
}
|
||||
|
||||
private void setBackupEnabled(boolean enable, boolean persistToDisk) {
|
||||
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
|
||||
"setBackupEnabled");
|
||||
|
||||
@@ -2864,62 +2899,79 @@ public class UserBackupManagerService {
|
||||
try {
|
||||
boolean wasEnabled = mEnabled;
|
||||
synchronized (this) {
|
||||
UserBackupManagerFilePersistedSettings.writeBackupEnableState(mUserId, enable);
|
||||
if (persistToDisk) {
|
||||
writeEnabledState(enable);
|
||||
}
|
||||
mEnabled = enable;
|
||||
}
|
||||
|
||||
synchronized (mQueueLock) {
|
||||
if (enable && !wasEnabled && mSetupComplete) {
|
||||
// if we've just been enabled, start scheduling backup passes
|
||||
KeyValueBackupJob.schedule(mUserId, mContext, mConstants);
|
||||
scheduleNextFullBackupJob(0);
|
||||
} else if (!enable) {
|
||||
// No longer enabled, so stop running backups
|
||||
if (MORE_DEBUG) Slog.i(TAG, "Opting out of backup");
|
||||
|
||||
KeyValueBackupJob.cancel(mUserId, mContext);
|
||||
|
||||
// This also constitutes an opt-out, so we wipe any data for
|
||||
// this device from the backend. We start that process with
|
||||
// an alarm in order to guarantee wakelock states.
|
||||
if (wasEnabled && mSetupComplete) {
|
||||
// NOTE: we currently flush every registered transport, not just
|
||||
// the currently-active one.
|
||||
List<String> transportNames = new ArrayList<>();
|
||||
List<String> transportDirNames = new ArrayList<>();
|
||||
mTransportManager.forEachRegisteredTransport(
|
||||
name -> {
|
||||
final String dirName;
|
||||
try {
|
||||
dirName =
|
||||
mTransportManager
|
||||
.getTransportDirName(name);
|
||||
} catch (TransportNotRegisteredException e) {
|
||||
// Should never happen
|
||||
Slog.e(TAG, "Unexpected unregistered transport", e);
|
||||
return;
|
||||
}
|
||||
transportNames.add(name);
|
||||
transportDirNames.add(dirName);
|
||||
});
|
||||
|
||||
// build the set of transports for which we are posting an init
|
||||
for (int i = 0; i < transportNames.size(); i++) {
|
||||
recordInitPending(
|
||||
true,
|
||||
transportNames.get(i),
|
||||
transportDirNames.get(i));
|
||||
}
|
||||
mAlarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(),
|
||||
mRunInitIntent);
|
||||
}
|
||||
}
|
||||
}
|
||||
updateStateOnBackupEnabled(wasEnabled, enable);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(oldId);
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void updateStateOnBackupEnabled(boolean wasEnabled, boolean enable) {
|
||||
synchronized (mQueueLock) {
|
||||
if (enable && !wasEnabled && mSetupComplete) {
|
||||
// if we've just been enabled, start scheduling backup passes
|
||||
KeyValueBackupJob.schedule(mUserId, mContext, mConstants);
|
||||
scheduleNextFullBackupJob(0);
|
||||
} else if (!enable) {
|
||||
// No longer enabled, so stop running backups
|
||||
if (MORE_DEBUG) Slog.i(TAG, "Opting out of backup");
|
||||
|
||||
KeyValueBackupJob.cancel(mUserId, mContext);
|
||||
|
||||
// This also constitutes an opt-out, so we wipe any data for
|
||||
// this device from the backend. We start that process with
|
||||
// an alarm in order to guarantee wakelock states.
|
||||
if (wasEnabled && mSetupComplete) {
|
||||
// NOTE: we currently flush every registered transport, not just
|
||||
// the currently-active one.
|
||||
List<String> transportNames = new ArrayList<>();
|
||||
List<String> transportDirNames = new ArrayList<>();
|
||||
mTransportManager.forEachRegisteredTransport(
|
||||
name -> {
|
||||
final String dirName;
|
||||
try {
|
||||
dirName =
|
||||
mTransportManager
|
||||
.getTransportDirName(name);
|
||||
} catch (TransportNotRegisteredException e) {
|
||||
// Should never happen
|
||||
Slog.e(TAG, "Unexpected unregistered transport", e);
|
||||
return;
|
||||
}
|
||||
transportNames.add(name);
|
||||
transportDirNames.add(dirName);
|
||||
});
|
||||
|
||||
// build the set of transports for which we are posting an init
|
||||
for (int i = 0; i < transportNames.size(); i++) {
|
||||
recordInitPending(
|
||||
true,
|
||||
transportNames.get(i),
|
||||
transportDirNames.get(i));
|
||||
}
|
||||
mAlarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(),
|
||||
mRunInitIntent);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void writeEnabledState(boolean enable) {
|
||||
UserBackupManagerFilePersistedSettings.writeBackupEnableState(mUserId, enable);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
boolean readEnabledState() {
|
||||
return UserBackupManagerFilePersistedSettings.readBackupEnableState(mUserId);
|
||||
}
|
||||
|
||||
/** Enable/disable automatic restore of app data at install time. */
|
||||
public void setAutoRestore(boolean doAutoRestore) {
|
||||
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright (C) 2020 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 static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.content.Context;
|
||||
import android.platform.test.annotations.Presubmit;
|
||||
|
||||
import androidx.test.runner.AndroidJUnit4;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
@Presubmit
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class UserBackupManagerServiceTest {
|
||||
@Mock Context mContext;
|
||||
|
||||
private TestBackupService mService;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
mService = new TestBackupService(mContext);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initializeBackupEnableState_doesntWriteStateToDisk() {
|
||||
mService.initializeBackupEnableState();
|
||||
|
||||
assertThat(mService.isEnabledStatePersisted).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateBackupEnableState_writesStateToDisk() {
|
||||
mService.setBackupEnabled(true);
|
||||
|
||||
assertThat(mService.isEnabledStatePersisted).isTrue();
|
||||
}
|
||||
|
||||
private static class TestBackupService extends UserBackupManagerService {
|
||||
boolean isEnabledStatePersisted = false;
|
||||
|
||||
TestBackupService(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
void writeEnabledState(boolean enable) {
|
||||
isEnabledStatePersisted = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean readEnabledState() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
void updateStateOnBackupEnabled(boolean wasEnabled, boolean enable) {}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user