Skip to content
Snippets Groups Projects
Commit 223ae986 authored by Jason Macnak's avatar Jason Macnak Committed by Android (Google) Code Review
Browse files

Revert "- Allow disabling framework Backup scheduling"

This reverts commit 748c64d9.

Reason for revert: DroidMonitor: Potential culprit for b/265432205 - verifying through ABTD before revert submission. This is part of the standard investigation process, and does not mean your CL will be reverted

Bug: b/265432205
Change-Id: I11e21ad5048635716adb5724b7d78d5513fc60e9
parent 748c64d9
No related branches found
No related tags found
No related merge requests found
Showing
with 34 additions and 216 deletions
......@@ -195,35 +195,10 @@ public class Bmgr {
return;
}
if ("scheduling".equals(op)) {
setSchedulingEnabled(userId);
return;
}
System.err.println("Unknown command");
showUsage();
}
private void setSchedulingEnabled(int userId) {
String arg = nextArg();
if (arg == null) {
showUsage();
return;
}
try {
boolean enable = Boolean.parseBoolean(arg);
mBmgr.setFrameworkSchedulingEnabledForUser(userId, enable);
System.out.println(
"Backup scheduling is now "
+ (enable ? "enabled" : "disabled")
+ " for user "
+ userId);
} catch (RemoteException e) {
handleRemoteException(e);
}
}
private void handleRemoteException(RemoteException e) {
System.err.println(e.toString());
System.err.println(BMGR_NOT_RUNNING_ERR);
......@@ -969,7 +944,6 @@ public class Bmgr {
System.err.println(" bmgr activate BOOL");
System.err.println(" bmgr activated");
System.err.println(" bmgr autorestore BOOL");
System.err.println(" bmgr scheduling BOOL");
System.err.println("");
System.err.println("The '--user' option specifies the user on which the operation is run.");
System.err.println("It must be the first argument before the operation.");
......@@ -1047,9 +1021,6 @@ public class Bmgr {
System.err.println("");
System.err.println("The 'autorestore' command enables or disables automatic restore when");
System.err.println("a new package is installed.");
System.err.println("");
System.err.println("The 'scheduling' command enables or disables backup scheduling in the");
System.err.println("framework.");
}
private static class BackupMonitor extends IBackupManagerMonitor.Stub {
......
......@@ -16,6 +16,7 @@
package android.app.backup;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
......@@ -37,6 +38,8 @@ import android.os.UserHandle;
import android.util.Log;
import android.util.Pair;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.List;
/**
......@@ -406,33 +409,6 @@ public class BackupManager {
}
}
/**
* Enable/disable the framework backup scheduling entirely for the current user. When disabled,
* no Key/Value or Full backup jobs will be scheduled by the Android framework.
*
* <p>Note: This does not disable backups: only their scheduling is affected and backups can
* still be triggered manually.
*
* <p>Callers must hold the android.permission.BACKUP permission to use this method.
*
* @hide
*/
@RequiresPermission(allOf = {android.Manifest.permission.BACKUP,
android.Manifest.permission.INTERACT_ACROSS_USERS_FULL}, conditional = true)
public void setFrameworkSchedulingEnabled(boolean isEnabled) {
checkServiceBinder();
if (sService == null) {
Log.e(TAG, "setFrameworkSchedulingEnabled() couldn't connect");
return;
}
try {
sService.setFrameworkSchedulingEnabledForUser(mContext.getUserId(), isEnabled);
} catch (RemoteException e) {
Log.e(TAG, "setFrameworkSchedulingEnabled() couldn't connect");
}
}
/**
* Report whether the backup mechanism is currently enabled.
*
......
......@@ -155,22 +155,6 @@ interface IBackupManager {
*/
void setBackupEnabledForUser(int userId, boolean isEnabled);
/**
* Enable/disable the framework backup scheduling entirely. When disabled, no Key/Value or Full
* backup jobs will be scheduled by the Android framework.
*
* <p>Note: This does not disable backups: only their scheduling is affected and backups can
* still be triggered manually.
*
* <p>Callers must hold the android.permission.BACKUP permission to use this method. If
* {@code userId} is different from the calling user id, then the caller must additionally hold
* the android.permission.INTERACT_ACROSS_USERS_FULL permission.
*
* @param userId The user for which backup scheduling should be enabled/disabled.
*/
void setFrameworkSchedulingEnabledForUser(int userId, boolean isEnabled);
/**
* {@link android.app.backup.IBackupManager.setBackupEnabledForUser} for the calling user id.
*/
......
......@@ -8658,12 +8658,6 @@ public final class Settings {
@Readable
public static final String BACKUP_AUTO_RESTORE = "backup_auto_restore";
 
/**
* Controls whether framework backup scheduling is enabled.
* @hide
*/
public static final String BACKUP_SCHEDULING_ENABLED = "backup_scheduling_enabled";
/**
* Indicates whether settings backup has been fully provisioned.
* Type: int ( 0 = unprovisioned, 1 = fully provisioned )
......
......@@ -695,7 +695,6 @@ public class SettingsBackupTest {
Settings.Secure.BACKUP_AUTO_RESTORE,
Settings.Secure.BACKUP_ENABLED,
Settings.Secure.BACKUP_PROVISIONED,
Settings.Secure.BACKUP_SCHEDULING_ENABLED,
Settings.Secure.BACKUP_TRANSPORT,
Settings.Secure.CALL_SCREENING_DEFAULT_COMPONENT,
Settings.Secure.CAMERA_LIFT_TRIGGER_ENABLED, // Candidate for backup?
......
......@@ -25,6 +25,7 @@ import android.annotation.UserIdInt;
import android.app.ActivityManager;
import android.app.admin.DevicePolicyManager;
import android.app.backup.BackupManager;
import android.app.backup.BackupRestoreEventLogger;
import android.app.backup.BackupRestoreEventLogger.DataTypeResult;
import android.app.backup.IBackupManager;
import android.app.backup.IBackupManagerMonitor;
......@@ -721,17 +722,6 @@ public class BackupManagerService extends IBackupManager.Stub {
}
}
@Override
public void setFrameworkSchedulingEnabledForUser(int userId, boolean isEnabled) {
UserBackupManagerService userBackupManagerService =
getServiceForUserIfCallerHasPermission(userId,
"setFrameworkSchedulingEnabledForUser()");
if (userBackupManagerService != null) {
userBackupManagerService.setFrameworkSchedulingEnabled(isEnabled);
}
}
@Override
public void setBackupEnabledForUser(@UserIdInt int userId, boolean isEnabled)
throws RemoteException {
......
......@@ -45,12 +45,9 @@ public class FullBackupJob extends JobService {
private final SparseArray<JobParameters> mParamsForUser = new SparseArray<>();
public static void schedule(int userId, Context ctx, long minDelay,
UserBackupManagerService userBackupManagerService) {
if (!userBackupManagerService.isFrameworkSchedulingEnabled()) return;
BackupManagerConstants constants) {
JobScheduler js = (JobScheduler) ctx.getSystemService(Context.JOB_SCHEDULER_SERVICE);
JobInfo.Builder builder = new JobInfo.Builder(getJobIdForUserId(userId), sIdleService);
final BackupManagerConstants constants = userBackupManagerService.getConstants();
synchronized (constants) {
builder.setRequiresDeviceIdle(true)
.setRequiredNetworkType(constants.getFullBackupRequiredNetworkType())
......
......@@ -64,16 +64,14 @@ public class KeyValueBackupJob extends JobService {
@VisibleForTesting
public static final int MAX_JOB_ID = 52418896;
public static void schedule(int userId, Context ctx,
UserBackupManagerService userBackupManagerService) {
schedule(userId, ctx, 0, userBackupManagerService);
public static void schedule(int userId, Context ctx, BackupManagerConstants constants) {
schedule(userId, ctx, 0, constants);
}
public static void schedule(int userId, Context ctx, long delay,
UserBackupManagerService userBackupManagerService) {
BackupManagerConstants constants) {
synchronized (KeyValueBackupJob.class) {
if (sScheduledForUserId.get(userId)
|| !userBackupManagerService.isFrameworkSchedulingEnabled()) {
if (sScheduledForUserId.get(userId)) {
return;
}
......@@ -82,7 +80,6 @@ public class KeyValueBackupJob extends JobService {
final int networkType;
final boolean needsCharging;
final BackupManagerConstants constants = userBackupManagerService.getConstants();
synchronized (constants) {
interval = constants.getKeyValueBackupIntervalMilliseconds();
fuzz = constants.getKeyValueBackupFuzzMilliseconds();
......
......@@ -1958,8 +1958,8 @@ public class UserBackupManagerService {
}
// We don't want the backup jobs to kick in any time soon.
// Reschedules them to run in the distant future.
KeyValueBackupJob.schedule(mUserId, mContext, BUSY_BACKOFF_MIN_MILLIS, this);
FullBackupJob.schedule(mUserId, mContext, 2 * BUSY_BACKOFF_MIN_MILLIS, this);
KeyValueBackupJob.schedule(mUserId, mContext, BUSY_BACKOFF_MIN_MILLIS, mConstants);
FullBackupJob.schedule(mUserId, mContext, 2 * BUSY_BACKOFF_MIN_MILLIS, mConstants);
} finally {
Binder.restoreCallingIdentity(oldToken);
}
......@@ -2088,7 +2088,7 @@ public class UserBackupManagerService {
final long interval = mConstants.getFullBackupIntervalMilliseconds();
final long appLatency = (timeSinceLast < interval) ? (interval - timeSinceLast) : 0;
final long latency = Math.max(transportMinLatency, appLatency);
FullBackupJob.schedule(mUserId, mContext, latency, this);
FullBackupJob.schedule(mUserId, mContext, latency, mConstants);
} else {
if (DEBUG_SCHEDULING) {
Slog.i(
......@@ -2226,7 +2226,7 @@ public class UserBackupManagerService {
addUserIdToLogMessage(
mUserId, "Deferring scheduled full backups in battery saver mode"));
}
FullBackupJob.schedule(mUserId, mContext, keyValueBackupInterval, this);
FullBackupJob.schedule(mUserId, mContext, keyValueBackupInterval, mConstants);
return false;
}
......@@ -2392,7 +2392,7 @@ public class UserBackupManagerService {
+ "operation; rescheduling +" + latency));
}
final long deferTime = latency; // pin for the closure
FullBackupJob.schedule(mUserId, mContext, deferTime, this);
FullBackupJob.schedule(mUserId, mContext, deferTime, mConstants);
return false;
}
......@@ -2495,7 +2495,7 @@ public class UserBackupManagerService {
}
// ...and schedule a backup pass if necessary
KeyValueBackupJob.schedule(mUserId, mContext, this);
KeyValueBackupJob.schedule(mUserId, mContext, mConstants);
}
// Note: packageName is currently unused, but may be in the future
......@@ -2730,7 +2730,7 @@ public class UserBackupManagerService {
mUserId, "Not running backup while in battery save mode"));
}
// Try again in several hours.
KeyValueBackupJob.schedule(mUserId, mContext, this);
KeyValueBackupJob.schedule(mUserId, mContext, mConstants);
} else {
if (DEBUG) {
Slog.v(TAG, addUserIdToLogMessage(mUserId, "Scheduling immediate backup pass"));
......@@ -3208,49 +3208,12 @@ public class UserBackupManagerService {
}
}
synchronized void setFrameworkSchedulingEnabled(boolean isEnabled) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
"setFrameworkSchedulingEnabled");
boolean wasEnabled = isFrameworkSchedulingEnabled();
if (wasEnabled == isEnabled) return;
Slog.i(TAG, addUserIdToLogMessage(mUserId,
(isEnabled ? "Enabling" : "Disabling") + " backup scheduling"));
final long oldId = Binder.clearCallingIdentity();
try {
// TODO(b/264889098): Consider at a later point if we should us a sentinel file as
// setBackupEnabled.
Settings.Secure.putIntForUser(mContext.getContentResolver(),
Settings.Secure.BACKUP_SCHEDULING_ENABLED, isEnabled ? 1 : 0, mUserId);
if (!isEnabled) {
KeyValueBackupJob.cancel(mUserId, mContext);
FullBackupJob.cancel(mUserId, mContext);
} else {
KeyValueBackupJob.schedule(mUserId, mContext, this);
scheduleNextFullBackupJob(/* transportMinLatency */ 0);
}
} finally {
Binder.restoreCallingIdentity(oldId);
}
}
synchronized boolean isFrameworkSchedulingEnabled() {
// By default scheduling is enabled
final int defaultSetting = 1;
int isEnabled = Settings.Secure.getIntForUser(mContext.getContentResolver(),
Settings.Secure.BACKUP_SCHEDULING_ENABLED, defaultSetting, mUserId);
return isEnabled == 1;
}
@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, this);
KeyValueBackupJob.schedule(mUserId, mContext, mConstants);
scheduleNextFullBackupJob(0);
} else if (!enable) {
// No longer enabled, so stop running backups
......@@ -4164,8 +4127,6 @@ public class UserBackupManagerService {
pw.println("Auto-restore is " + (mAutoRestore ? "enabled" : "disabled"));
if (mBackupRunning) pw.println("Backup currently running");
pw.println(isBackupOperationInProgress() ? "Backup in progress" : "No backups running");
pw.println("Framework scheduling is "
+ (isFrameworkSchedulingEnabled() ? "enabled" : "disabled"));
pw.println("Last backup pass started: " + mLastBackupPass
+ " (now = " + System.currentTimeMillis() + ')');
pw.println(" next scheduled: " + KeyValueBackupJob.nextScheduled(mUserId));
......
......@@ -23,6 +23,7 @@ import static com.android.server.backup.UserBackupManagerService.getSetupComplet
import android.content.Context;
import android.database.ContentObserver;
import android.os.Handler;
import android.provider.Settings;
import android.util.Slog;
import com.android.server.backup.KeyValueBackupJob;
......@@ -77,7 +78,7 @@ public class SetupObserver extends ContentObserver {
Slog.d(TAG, "Setup complete so starting backups");
}
KeyValueBackupJob.schedule(mUserBackupManagerService.getUserId(), mContext,
mUserBackupManagerService);
mUserBackupManagerService.getConstants());
mUserBackupManagerService.scheduleNextFullBackupJob(0);
}
}
......
......@@ -1246,7 +1246,7 @@ public class KeyValueBackupTask implements BackupRestoreTask, Runnable {
delay = 0;
}
KeyValueBackupJob.schedule(mBackupManagerService.getUserId(),
mBackupManagerService.getContext(), delay, mBackupManagerService);
mBackupManagerService.getContext(), delay, mBackupManagerService.getConstants());
for (String packageName : mOriginalQueue) {
mBackupManagerService.dataChangedImpl(packageName);
......
......@@ -18,8 +18,6 @@ package com.android.server.backup;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.when;
import android.annotation.UserIdInt;
import android.app.job.JobScheduler;
import android.content.Context;
......@@ -33,8 +31,6 @@ import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.Shadows;
......@@ -49,20 +45,14 @@ public class FullBackupJobTest {
private BackupManagerConstants mConstants;
private ShadowJobScheduler mShadowJobScheduler;
@Mock
private UserBackupManagerService mUserBackupManagerService;
@UserIdInt private int mUserOneId;
@UserIdInt private int mUserTwoId;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
mContext = RuntimeEnvironment.application;
mConstants = new BackupManagerConstants(Handler.getMain(), mContext.getContentResolver());
mConstants.start();
when(mUserBackupManagerService.getConstants()).thenReturn(mConstants);
when(mUserBackupManagerService.isFrameworkSchedulingEnabled()).thenReturn(true);
mShadowJobScheduler = Shadows.shadowOf(mContext.getSystemService(JobScheduler.class));
......@@ -79,8 +69,8 @@ public class FullBackupJobTest {
@Test
public void testSchedule_afterScheduling_jobExists() {
FullBackupJob.schedule(mUserOneId, mContext, 0, mUserBackupManagerService);
FullBackupJob.schedule(mUserTwoId, mContext, 0, mUserBackupManagerService);
FullBackupJob.schedule(mUserOneId, mContext, 0, mConstants);
FullBackupJob.schedule(mUserTwoId, mContext, 0, mConstants);
assertThat(mShadowJobScheduler.getPendingJob(getJobIdForUserId(mUserOneId))).isNotNull();
assertThat(mShadowJobScheduler.getPendingJob(getJobIdForUserId(mUserTwoId))).isNotNull();
......@@ -88,34 +78,18 @@ public class FullBackupJobTest {
@Test
public void testCancel_afterCancelling_jobDoesntExist() {
FullBackupJob.schedule(mUserOneId, mContext, 0, mUserBackupManagerService);
FullBackupJob.schedule(mUserTwoId, mContext, 0, mUserBackupManagerService);
FullBackupJob.schedule(mUserOneId, mContext, 0, mConstants);
FullBackupJob.schedule(mUserTwoId, mContext, 0, mConstants);
FullBackupJob.cancel(mUserOneId, mContext);
FullBackupJob.cancel(mUserTwoId, mContext);
assertThat(mShadowJobScheduler.getPendingJob(getJobIdForUserId(mUserOneId))).isNull();
assertThat(mShadowJobScheduler.getPendingJob(getJobIdForUserId(mUserTwoId))).isNull();
}
@Test
public void testSchedule_isNoopIfDisabled() {
when(mUserBackupManagerService.isFrameworkSchedulingEnabled()).thenReturn(false);
FullBackupJob.schedule(mUserOneId, mContext, 0, mUserBackupManagerService);
assertThat(mShadowJobScheduler.getPendingJob(getJobIdForUserId(mUserOneId))).isNull();
}
@Test
public void testSchedule_schedulesJobIfEnabled() {
when(mUserBackupManagerService.isFrameworkSchedulingEnabled()).thenReturn(true);
FullBackupJob.schedule(mUserOneId, mContext, 0, mUserBackupManagerService);
assertThat(mShadowJobScheduler.getPendingJob(getJobIdForUserId(mUserOneId))).isNotNull();
}
//
@Test
public void testSchedule_onlySchedulesForRequestedUser() {
FullBackupJob.schedule(mUserOneId, mContext, 0, mUserBackupManagerService);
FullBackupJob.schedule(mUserOneId, mContext, 0, mConstants);
assertThat(mShadowJobScheduler.getPendingJob(getJobIdForUserId(mUserOneId))).isNotNull();
assertThat(mShadowJobScheduler.getPendingJob(getJobIdForUserId(mUserTwoId))).isNull();
......@@ -123,8 +97,8 @@ public class FullBackupJobTest {
//
@Test
public void testCancel_onlyCancelsForRequestedUser() {
FullBackupJob.schedule(mUserOneId, mContext, 0, mUserBackupManagerService);
FullBackupJob.schedule(mUserTwoId, mContext, 0, mUserBackupManagerService);
FullBackupJob.schedule(mUserOneId, mContext, 0, mConstants);
FullBackupJob.schedule(mUserTwoId, mContext, 0, mConstants);
FullBackupJob.cancel(mUserOneId, mContext);
assertThat(mShadowJobScheduler.getPendingJob(getJobIdForUserId(mUserOneId))).isNull();
......
......@@ -18,8 +18,6 @@ package com.android.server.backup;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.when;
import android.annotation.UserIdInt;
import android.content.Context;
import android.os.Handler;
......@@ -32,8 +30,6 @@ import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
......@@ -45,20 +41,14 @@ public class KeyValueBackupJobTest {
private Context mContext;
private BackupManagerConstants mConstants;
@Mock
private UserBackupManagerService mUserBackupManagerService;
@UserIdInt private int mUserOneId;
@UserIdInt private int mUserTwoId;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
mContext = RuntimeEnvironment.application;
mConstants = new BackupManagerConstants(Handler.getMain(), mContext.getContentResolver());
mConstants.start();
when(mUserBackupManagerService.getConstants()).thenReturn(mConstants);
when(mUserBackupManagerService.isFrameworkSchedulingEnabled()).thenReturn(true);
mUserOneId = UserHandle.USER_SYSTEM;
mUserTwoId = mUserOneId + 1;
......@@ -71,22 +61,6 @@ public class KeyValueBackupJobTest {
KeyValueBackupJob.cancel(mUserTwoId, mContext);
}
@Test
public void testSchedule_isNoopIfDisabled() {
when(mUserBackupManagerService.isFrameworkSchedulingEnabled()).thenReturn(false);
KeyValueBackupJob.schedule(mUserOneId, mContext, mUserBackupManagerService);
assertThat(KeyValueBackupJob.isScheduled(mUserOneId)).isFalse();
}
@Test
public void testSchedule_schedulesJobIfEnabled() {
when(mUserBackupManagerService.isFrameworkSchedulingEnabled()).thenReturn(true);
KeyValueBackupJob.schedule(mUserOneId, mContext, mUserBackupManagerService);
assertThat(KeyValueBackupJob.isScheduled(mUserOneId)).isTrue();
}
@Test
public void testIsScheduled_beforeScheduling_returnsFalse() {
assertThat(KeyValueBackupJob.isScheduled(mUserOneId)).isFalse();
......@@ -95,8 +69,8 @@ public class KeyValueBackupJobTest {
@Test
public void testIsScheduled_afterScheduling_returnsTrue() {
KeyValueBackupJob.schedule(mUserOneId, mContext, mUserBackupManagerService);
KeyValueBackupJob.schedule(mUserTwoId, mContext, mUserBackupManagerService);
KeyValueBackupJob.schedule(mUserOneId, mContext, mConstants);
KeyValueBackupJob.schedule(mUserTwoId, mContext, mConstants);
assertThat(KeyValueBackupJob.isScheduled(mUserOneId)).isTrue();
assertThat(KeyValueBackupJob.isScheduled(mUserTwoId)).isTrue();
......@@ -104,8 +78,8 @@ public class KeyValueBackupJobTest {
@Test
public void testIsScheduled_afterCancelling_returnsFalse() {
KeyValueBackupJob.schedule(mUserOneId, mContext, mUserBackupManagerService);
KeyValueBackupJob.schedule(mUserTwoId, mContext, mUserBackupManagerService);
KeyValueBackupJob.schedule(mUserOneId, mContext, mConstants);
KeyValueBackupJob.schedule(mUserTwoId, mContext, mConstants);
KeyValueBackupJob.cancel(mUserOneId, mContext);
KeyValueBackupJob.cancel(mUserTwoId, mContext);
......@@ -115,7 +89,7 @@ public class KeyValueBackupJobTest {
@Test
public void testIsScheduled_afterScheduling_returnsTrueOnlyForScheduledUser() {
KeyValueBackupJob.schedule(mUserOneId, mContext, mUserBackupManagerService);
KeyValueBackupJob.schedule(mUserOneId, mContext, mConstants);
assertThat(KeyValueBackupJob.isScheduled(mUserOneId)).isTrue();
assertThat(KeyValueBackupJob.isScheduled(mUserTwoId)).isFalse();
......@@ -123,8 +97,8 @@ public class KeyValueBackupJobTest {
@Test
public void testIsScheduled_afterCancelling_returnsFalseOnlyForCancelledUser() {
KeyValueBackupJob.schedule(mUserOneId, mContext, mUserBackupManagerService);
KeyValueBackupJob.schedule(mUserTwoId, mContext, mUserBackupManagerService);
KeyValueBackupJob.schedule(mUserOneId, mContext, mConstants);
KeyValueBackupJob.schedule(mUserTwoId, mContext, mConstants);
KeyValueBackupJob.cancel(mUserOneId, mContext);
assertThat(KeyValueBackupJob.isScheduled(mUserOneId)).isFalse();
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment