1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.content; 18 19 import static android.content.pm.UserProperties.INHERIT_DEVICE_POLICY_FROM_PARENT; 20 import static android.content.pm.UserProperties.SHOW_IN_LAUNCHER_WITH_PARENT; 21 import static android.content.pm.UserProperties.SHOW_IN_SETTINGS_WITH_PARENT; 22 23 import static com.google.common.truth.Truth.assertThat; 24 25 import static org.mockito.ArgumentMatchers.any; 26 import static org.mockito.Mockito.doNothing; 27 import static org.mockito.Mockito.doReturn; 28 import static org.mockito.Mockito.spy; 29 import static org.mockito.Mockito.when; 30 31 import android.accounts.AccountManagerInternal; 32 import android.content.ContentResolver; 33 import android.content.Context; 34 import android.content.pm.UserInfo; 35 import android.content.pm.UserProperties; 36 import android.os.Bundle; 37 import android.os.UserManager; 38 import android.provider.ContactsContract; 39 import android.test.suitebuilder.annotation.SmallTest; 40 41 import androidx.test.core.app.ApplicationProvider; 42 43 import junit.framework.TestCase; 44 45 import org.jetbrains.annotations.NotNull; 46 import org.junit.Before; 47 import org.mockito.Mock; 48 import org.mockito.MockitoAnnotations; 49 50 /** 51 * Tests for SyncManager. 52 * 53 * bit FrameworksServicesTests:com.android.server.content.SyncManagerTest 54 */ 55 @SmallTest 56 public class SyncManagerTest extends TestCase { 57 58 final String KEY_1 = "key_1"; 59 final String KEY_2 = "key_2"; 60 61 private SyncManager mSyncManager; 62 private Context mContext; 63 64 @Mock 65 private UserManager mUserManager; 66 @Mock 67 private AccountManagerInternal mAccountManagerInternal; 68 69 private class SyncManagerWithMockedServices extends SyncManager { 70 71 @Override getAccountManagerInternal()72 protected AccountManagerInternal getAccountManagerInternal() { 73 return mAccountManagerInternal; 74 } 75 SyncManagerWithMockedServices(Context context, boolean factoryTest)76 private SyncManagerWithMockedServices(Context context, boolean factoryTest) { 77 super(context, factoryTest); 78 } 79 } 80 81 @Before setUp()82 public void setUp() { 83 MockitoAnnotations.initMocks(this); 84 mContext = spy(ApplicationProvider.getApplicationContext()); 85 when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager); 86 doNothing().when(mAccountManagerInternal).addOnAppPermissionChangeListener(any()); 87 mSyncManager = spy(new SyncManagerWithMockedServices(mContext, true)); 88 } 89 testSyncExtrasEquals_WithNull()90 public void testSyncExtrasEquals_WithNull() throws Exception { 91 Bundle b1 = new Bundle(); 92 Bundle b2 = new Bundle(); 93 94 b1.putString(KEY_1, null); 95 b2.putString(KEY_1, null); 96 97 assertTrue("Null extra not properly compared between bundles.", 98 SyncManager.syncExtrasEquals(b1, b2, false /* don't care about system extras */)); 99 } 100 testSyncExtrasEqualsBigger_WithNull()101 public void testSyncExtrasEqualsBigger_WithNull() throws Exception { 102 Bundle b1 = new Bundle(); 103 Bundle b2 = new Bundle(); 104 105 b1.putString(KEY_1, null); 106 b2.putString(KEY_1, null); 107 108 b1.putString(KEY_2, "bla"); 109 b2.putString(KEY_2, "bla"); 110 111 assertTrue("Extras not properly compared between bundles.", 112 SyncManager.syncExtrasEquals(b1, b2, false /* don't care about system extras */)); 113 } 114 testSyncExtrasEqualsFails_WithNull()115 public void testSyncExtrasEqualsFails_WithNull() throws Exception { 116 Bundle b1 = new Bundle(); 117 b1.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true); 118 b1.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true); 119 120 Bundle b2 = new Bundle(); 121 b2.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true); 122 b2.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true); 123 b2.putString(null, "Hello NPE!"); 124 b2.putString("a", "b"); 125 b2.putString("c", "d"); 126 b2.putString("e", "f"); 127 128 assertFalse("Extras not properly compared between bundles.", 129 SyncManager.syncExtrasEquals(b1, b2, false /* don't care about system extras */)); 130 } 131 testSyncExtrasEqualsFails_differentValues()132 public void testSyncExtrasEqualsFails_differentValues() throws Exception { 133 Bundle b1 = new Bundle(); 134 Bundle b2 = new Bundle(); 135 136 b1.putString(KEY_1, null); 137 b2.putString(KEY_1, null); 138 139 b1.putString(KEY_2, "bla"); 140 b2.putString(KEY_2, "ble"); // different key 141 142 assertFalse("Extras considered equal when they are different.", 143 SyncManager.syncExtrasEquals(b1, b2, false /* don't care about system extras */)); 144 } 145 testSyncExtrasEqualsFails_differentNulls()146 public void testSyncExtrasEqualsFails_differentNulls() throws Exception { 147 Bundle b1 = new Bundle(); 148 Bundle b2 = new Bundle(); 149 150 b1.putString(KEY_1, null); 151 b2.putString(KEY_1, "bla"); // different key 152 153 b1.putString(KEY_2, "ble"); 154 b2.putString(KEY_2, "ble"); 155 156 assertFalse("Extras considered equal when they are different.", 157 SyncManager.syncExtrasEquals(b1, b2, false /* don't care about system extras */)); 158 } 159 testFormatDurationHMS()160 public void testFormatDurationHMS() { 161 checkFormatDurationHMS("0s", 0, 0, 0, 0); 162 checkFormatDurationHMS("1s", 0, 0, 0, 1); 163 checkFormatDurationHMS("9s", 0, 0, 0, 9); 164 checkFormatDurationHMS("10s", 0, 0, 0, 10); 165 checkFormatDurationHMS("59s", 0, 0, 0, 59); 166 checkFormatDurationHMS("1m00s", 0, 0, 1, 0); 167 checkFormatDurationHMS("1m01s", 0, 0, 1, 1); 168 checkFormatDurationHMS("1m09s", 0, 0, 1, 9); 169 checkFormatDurationHMS("1m10s", 0, 0, 1, 10); 170 checkFormatDurationHMS("1m59s", 0, 0, 1, 59); 171 checkFormatDurationHMS("1h00m00s", 0, 1, 0, 0); 172 checkFormatDurationHMS("1h00m01s", 0, 1, 0, 1); 173 checkFormatDurationHMS("1h01m01s", 0, 1, 1, 1); 174 checkFormatDurationHMS("1h09m10s", 0, 1, 9, 10); 175 checkFormatDurationHMS("1h10m59s", 0, 1, 10, 59); 176 checkFormatDurationHMS("1h59m00s", 0, 1, 59, 0); 177 178 checkFormatDurationHMS("1d00h00m00s", 1, 0, 0, 0); 179 checkFormatDurationHMS("1d00h00m00s", 1, 0, 0, 0); 180 checkFormatDurationHMS("1d01h00m00s", 1, 1, 0, 0); 181 checkFormatDurationHMS("1d09h00m00s", 1, 9, 0, 0); 182 checkFormatDurationHMS("1d10h00m00s", 1, 10, 0, 0); 183 checkFormatDurationHMS("1d23h00m00s", 1, 23, 0, 0); 184 checkFormatDurationHMS("123d01h00m00s", 123, 1, 0, 0); 185 186 final StringBuilder sb = new StringBuilder(); 187 assertEquals("-1m01s", SyncManager.formatDurationHMS(sb, -61000L).toString()); 188 } 189 checkFormatDurationHMS(String expected, int d, int h, int m, int s)190 private void checkFormatDurationHMS(String expected, 191 int d, int h, int m, int s) { 192 final long time = (d * 24 * 3600) + (h * 3600) + (m * 60) + s; 193 194 final StringBuilder sb = new StringBuilder(); 195 assertEquals(expected, SyncManager.formatDurationHMS(sb, time * 1000).toString()); 196 } 197 createUserInfo(String name, int id, int groupId, int flags)198 private UserInfo createUserInfo(String name, int id, int groupId, int flags) { 199 final UserInfo ui = new UserInfo(id, name, flags | UserInfo.FLAG_INITIALIZED); 200 ui.profileGroupId = groupId; 201 return ui; 202 } 203 204 @NotNull getCloneUserProperties()205 private UserProperties getCloneUserProperties() { 206 return new UserProperties.Builder() 207 .setStartWithParent(true) 208 .setShowInLauncher(SHOW_IN_LAUNCHER_WITH_PARENT) 209 .setShowInSettings(SHOW_IN_SETTINGS_WITH_PARENT) 210 .setUseParentsContacts(true) 211 .setInheritDevicePolicy(INHERIT_DEVICE_POLICY_FROM_PARENT) 212 .build(); 213 } 214 mockUserProperties(UserInfo primaryUserInfo, UserInfo cloneUserInfo)215 private void mockUserProperties(UserInfo primaryUserInfo, UserInfo cloneUserInfo) { 216 UserProperties cloneUserProperties = getCloneUserProperties(); 217 when(mUserManager.getUserProperties(cloneUserInfo.getUserHandle())) 218 .thenReturn(cloneUserProperties); 219 // Set default user properties for primary user 220 when(mUserManager.getUserProperties(primaryUserInfo.getUserHandle())) 221 .thenReturn(new UserProperties.Builder().build()); 222 } 223 testShouldDisableSync()224 public void testShouldDisableSync() { 225 doReturn(true).when(mSyncManager).isContactSharingAllowedForCloneProfile(); 226 UserInfo primaryUserInfo = createUserInfo("primary", 0 /* id */, 0 /* groupId */, 227 UserInfo.FLAG_PRIMARY | UserInfo.FLAG_ADMIN); 228 UserInfo cloneUserInfo = createUserInfo("clone", 10 /* id */, 0 /* groupId */, 229 UserInfo.FLAG_PROFILE); 230 231 mockUserProperties(primaryUserInfo, cloneUserInfo); 232 233 // Clone user accounts must have contact syncs disabled 234 assertThat(mSyncManager.shouldDisableSyncForUser(cloneUserInfo, 235 ContactsContract.AUTHORITY)).isTrue(); 236 assertThat(mSyncManager.shouldDisableSyncForUser(primaryUserInfo, 237 ContactsContract.AUTHORITY)).isFalse(); 238 } 239 } 240