diff options
| -rw-r--r-- | services/core/java/com/android/server/content/SyncManager.java | 18 | ||||
| -rw-r--r-- | services/tests/servicestests/src/com/android/server/content/SyncManagerTest.java | 106 |
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(); + } } |