summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/content/SyncManager.java18
-rw-r--r--services/tests/servicestests/src/com/android/server/content/SyncManagerTest.java106
2 files changed, 121 insertions, 3 deletions
diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java
index ebe1040d0ecc..dcc98e17fadf 100644
--- a/services/core/java/com/android/server/content/SyncManager.java
+++ b/services/core/java/com/android/server/content/SyncManager.java
@@ -102,6 +102,7 @@ import android.util.SparseBooleanArray;
import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.IBatteryStats;
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
import com.android.internal.notification.SystemNotificationChannels;
@@ -501,7 +502,7 @@ public class SyncManager {
}
mJobScheduler = (JobScheduler) mContext.getSystemService(
Context.JOB_SCHEDULER_SERVICE);
- mJobSchedulerInternal = LocalServices.getService(JobSchedulerInternal.class);
+ mJobSchedulerInternal = getJobSchedulerInternal();
// Get all persisted syncs from JobScheduler
List<JobInfo> pendingJobs = mJobScheduler.getAllPendingJobs();
@@ -539,6 +540,11 @@ public class SyncManager {
}
}
+ @VisibleForTesting
+ protected JobSchedulerInternal getJobSchedulerInternal() {
+ return LocalServices.getService(JobSchedulerInternal.class);
+ }
+
/**
* @return whether the device most likely has some periodic syncs.
*/
@@ -648,7 +654,7 @@ public class SyncManager {
mPowerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
mAccountManager = (AccountManager) mContext.getSystemService(Context.ACCOUNT_SERVICE);
- mAccountManagerInternal = LocalServices.getService(AccountManagerInternal.class);
+ mAccountManagerInternal = getAccountManagerInternal();
mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class);
mAmi = LocalServices.getService(ActivityManagerInternal.class);
@@ -722,6 +728,11 @@ public class SyncManager {
mLogger.log("Sync manager initialized: " + Build.FINGERPRINT);
}
+ @VisibleForTesting
+ protected AccountManagerInternal getAccountManagerInternal() {
+ return LocalServices.getService(AccountManagerInternal.class);
+ }
+
public void onStartUser(int userId) {
// Log on the handler to avoid slowing down device boot.
mSyncHandler.post(() -> mLogger.log("onStartUser: user=", userId));
@@ -823,7 +834,8 @@ public class SyncManager {
* @return true if sync for the account corresponding to the given user and provider should be
* disabled, false otherwise. Also returns false if either of the inputs are null.
*/
- private boolean shouldDisableSyncForUser(UserInfo userInfo, String providerName) {
+ @VisibleForTesting
+ protected boolean shouldDisableSyncForUser(UserInfo userInfo, String providerName) {
if (userInfo == null || providerName == null) return false;
return providerName.equals(ContactsContract.AUTHORITY)
&& !areContactWritesEnabledForUser(userInfo);
diff --git a/services/tests/servicestests/src/com/android/server/content/SyncManagerTest.java b/services/tests/servicestests/src/com/android/server/content/SyncManagerTest.java
index c2a81d9453e4..d4e3d4418c43 100644
--- a/services/tests/servicestests/src/com/android/server/content/SyncManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/content/SyncManagerTest.java
@@ -16,12 +16,40 @@
package com.android.server.content;
+import static android.content.pm.UserProperties.INHERIT_DEVICE_POLICY_FROM_PARENT;
+import static android.content.pm.UserProperties.SHOW_IN_LAUNCHER_WITH_PARENT;
+import static android.content.pm.UserProperties.SHOW_IN_SETTINGS_WITH_PARENT;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.accounts.AccountManagerInternal;
import android.content.ContentResolver;
+import android.content.Context;
+import android.content.pm.UserInfo;
+import android.content.pm.UserProperties;
import android.os.Bundle;
+import android.os.UserManager;
+import android.provider.ContactsContract;
import android.test.suitebuilder.annotation.SmallTest;
+import androidx.test.core.app.ApplicationProvider;
+
+import com.android.server.job.JobSchedulerInternal;
+
import junit.framework.TestCase;
+import org.jetbrains.annotations.NotNull;
+import org.junit.Before;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.ArrayList;
+
/**
* Tests for SyncManager.
*
@@ -33,6 +61,43 @@ public class SyncManagerTest extends TestCase {
final String KEY_1 = "key_1";
final String KEY_2 = "key_2";
+ private SyncManager mSyncManager;
+ private Context mContext;
+
+ @Mock
+ private UserManager mUserManager;
+ @Mock
+ private AccountManagerInternal mAccountManagerInternal;
+ @Mock
+ private JobSchedulerInternal mJobSchedulerInternal;
+
+ private class SyncManagerWithMockedServices extends SyncManager {
+
+ @Override
+ protected AccountManagerInternal getAccountManagerInternal() {
+ return mAccountManagerInternal;
+ }
+
+ @Override
+ protected JobSchedulerInternal getJobSchedulerInternal() {
+ return mJobSchedulerInternal;
+ }
+
+ private SyncManagerWithMockedServices(Context context, boolean factoryTest) {
+ super(context, factoryTest);
+ }
+ }
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mContext = spy(ApplicationProvider.getApplicationContext());
+ when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
+ doNothing().when(mAccountManagerInternal).addOnAppPermissionChangeListener(any());
+ when(mJobSchedulerInternal.getSystemScheduledPendingJobs()).thenReturn(new ArrayList<>());
+ mSyncManager = new SyncManagerWithMockedServices(mContext, true);
+ }
+
public void testSyncExtrasEquals_WithNull() throws Exception {
Bundle b1 = new Bundle();
Bundle b2 = new Bundle();
@@ -140,4 +205,45 @@ public class SyncManagerTest extends TestCase {
final StringBuilder sb = new StringBuilder();
assertEquals(expected, SyncManager.formatDurationHMS(sb, time * 1000).toString());
}
+
+ private UserInfo createUserInfo(String name, int id, int groupId, int flags) {
+ final UserInfo ui = new UserInfo(id, name, flags | UserInfo.FLAG_INITIALIZED);
+ ui.profileGroupId = groupId;
+ return ui;
+ }
+
+ @NotNull
+ private UserProperties getCloneUserProperties() {
+ return new UserProperties.Builder()
+ .setStartWithParent(true)
+ .setShowInLauncher(SHOW_IN_LAUNCHER_WITH_PARENT)
+ .setShowInSettings(SHOW_IN_SETTINGS_WITH_PARENT)
+ .setUseParentsContacts(true)
+ .setInheritDevicePolicy(INHERIT_DEVICE_POLICY_FROM_PARENT)
+ .build();
+ }
+
+ private void mockUserProperties(UserInfo primaryUserInfo, UserInfo cloneUserInfo) {
+ UserProperties cloneUserProperties = getCloneUserProperties();
+ when(mUserManager.getUserProperties(cloneUserInfo.getUserHandle()))
+ .thenReturn(cloneUserProperties);
+ // Set default user properties for primary user
+ when(mUserManager.getUserProperties(primaryUserInfo.getUserHandle()))
+ .thenReturn(new UserProperties.Builder().build());
+ }
+
+ public void testShouldDisableSync() {
+ UserInfo primaryUserInfo = createUserInfo("primary", 0 /* id */, 0 /* groupId */,
+ UserInfo.FLAG_PRIMARY | UserInfo.FLAG_ADMIN);
+ UserInfo cloneUserInfo = createUserInfo("clone", 10 /* id */, 0 /* groupId */,
+ UserInfo.FLAG_PROFILE);
+
+ mockUserProperties(primaryUserInfo, cloneUserInfo);
+
+ // Clone user accounts must have contact syncs disabled
+ assertThat(mSyncManager.shouldDisableSyncForUser(cloneUserInfo,
+ ContactsContract.AUTHORITY)).isTrue();
+ assertThat(mSyncManager.shouldDisableSyncForUser(primaryUserInfo,
+ ContactsContract.AUTHORITY)).isFalse();
+ }
}