1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file 5 * except in compliance with the License. You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software distributed under the 10 * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 11 * KIND, either express or implied. See the License for the specific language governing 12 * permissions and limitations under the License. 13 */ 14 15 package com.android.systemui.qs; 16 17 import static com.android.systemui.statusbar.phone.AutoTileManager.SAVER; 18 19 import static org.junit.Assert.assertEquals; 20 import static org.junit.Assert.assertFalse; 21 import static org.junit.Assert.assertTrue; 22 import static org.mockito.ArgumentMatchers.eq; 23 import static org.mockito.Mockito.any; 24 import static org.mockito.Mockito.anyInt; 25 import static org.mockito.Mockito.never; 26 import static org.mockito.Mockito.verify; 27 28 import android.content.BroadcastReceiver; 29 import android.content.Intent; 30 import android.content.IntentFilter; 31 import android.os.UserHandle; 32 import android.provider.Settings.Secure; 33 import android.testing.AndroidTestingRunner; 34 import android.testing.TestableLooper.RunWithLooper; 35 36 import androidx.test.filters.SmallTest; 37 38 import com.android.systemui.SysuiTestCase; 39 import com.android.systemui.broadcast.BroadcastDispatcher; 40 import com.android.systemui.dump.DumpManager; 41 import com.android.systemui.util.settings.FakeSettings; 42 import com.android.systemui.util.settings.SecureSettings; 43 44 import org.junit.Before; 45 import org.junit.Test; 46 import org.junit.runner.RunWith; 47 import org.mockito.ArgumentCaptor; 48 import org.mockito.Captor; 49 import org.mockito.InOrder; 50 import org.mockito.Mock; 51 import org.mockito.Mockito; 52 import org.mockito.MockitoAnnotations; 53 54 import java.util.List; 55 import java.util.concurrent.Executor; 56 57 @RunWith(AndroidTestingRunner.class) 58 @RunWithLooper 59 @SmallTest 60 public class AutoAddTrackerTest extends SysuiTestCase { 61 62 private static final int END_POSITION = -1; 63 private static final int USER = 0; 64 65 @Mock 66 private BroadcastDispatcher mBroadcastDispatcher; 67 @Mock 68 private QSHost mQSHost; 69 @Mock 70 private DumpManager mDumpManager; 71 @Captor 72 private ArgumentCaptor<BroadcastReceiver> mBroadcastReceiverArgumentCaptor; 73 @Captor 74 private ArgumentCaptor<IntentFilter> mIntentFilterArgumentCaptor; 75 76 private Executor mBackgroundExecutor = Runnable::run; // Direct executor 77 private AutoAddTracker mAutoTracker; 78 private SecureSettings mSecureSettings; 79 80 @Before setUp()81 public void setUp() { 82 MockitoAnnotations.initMocks(this); 83 84 mSecureSettings = new FakeSettings(); 85 86 mSecureSettings.putStringForUser(Secure.QS_AUTO_ADDED_TILES, null, USER); 87 88 mAutoTracker = createAutoAddTracker(USER); 89 mAutoTracker.initialize(); 90 } 91 92 @Test testChangeFromBackup()93 public void testChangeFromBackup() { 94 assertFalse(mAutoTracker.isAdded(SAVER)); 95 96 mSecureSettings.putStringForUser(Secure.QS_AUTO_ADDED_TILES, SAVER, USER); 97 98 assertTrue(mAutoTracker.isAdded(SAVER)); 99 100 mAutoTracker.destroy(); 101 } 102 103 @Test testSetAdded()104 public void testSetAdded() { 105 assertFalse(mAutoTracker.isAdded(SAVER)); 106 mAutoTracker.setTileAdded(SAVER); 107 108 assertTrue(mAutoTracker.isAdded(SAVER)); 109 110 mAutoTracker.destroy(); 111 } 112 113 @Test testPersist()114 public void testPersist() { 115 assertFalse(mAutoTracker.isAdded(SAVER)); 116 mAutoTracker.setTileAdded(SAVER); 117 118 mAutoTracker.destroy(); 119 mAutoTracker = createAutoAddTracker(USER); 120 mAutoTracker.initialize(); 121 122 assertTrue(mAutoTracker.isAdded(SAVER)); 123 124 mAutoTracker.destroy(); 125 } 126 127 @Test testIndependentUsers()128 public void testIndependentUsers() { 129 mAutoTracker.setTileAdded(SAVER); 130 131 mAutoTracker = createAutoAddTracker(USER + 1); 132 mAutoTracker.initialize(); 133 assertFalse(mAutoTracker.isAdded(SAVER)); 134 } 135 136 @Test testChangeUser()137 public void testChangeUser() { 138 mAutoTracker.setTileAdded(SAVER); 139 140 mAutoTracker = createAutoAddTracker(USER + 1); 141 mAutoTracker.changeUser(UserHandle.of(USER)); 142 assertTrue(mAutoTracker.isAdded(SAVER)); 143 } 144 145 @Test testRestoredTilePositionPreserved()146 public void testRestoredTilePositionPreserved() { 147 verify(mBroadcastDispatcher).registerReceiver( 148 mBroadcastReceiverArgumentCaptor.capture(), any(), any(), any(), anyInt(), any()); 149 String restoredTiles = "saver,internet,work,cast"; 150 Intent restoreTilesIntent = makeRestoreIntent(Secure.QS_TILES, null, restoredTiles); 151 152 mBroadcastReceiverArgumentCaptor.getValue().onReceive(mContext, restoreTilesIntent); 153 154 assertEquals(2, mAutoTracker.getRestoredTilePosition("work")); 155 } 156 157 @Test testNoRestoredTileReturnsEndPosition()158 public void testNoRestoredTileReturnsEndPosition() { 159 verify(mBroadcastDispatcher).registerReceiver( 160 mBroadcastReceiverArgumentCaptor.capture(), any(), any(), any(), anyInt(), any()); 161 Intent restoreTilesIntent = makeRestoreIntent(Secure.QS_TILES, null, null); 162 163 mBroadcastReceiverArgumentCaptor.getValue().onReceive(mContext, restoreTilesIntent); 164 165 assertEquals(END_POSITION, mAutoTracker.getRestoredTilePosition("work")); 166 } 167 168 @Test testBroadcastReceiverRegistered()169 public void testBroadcastReceiverRegistered() { 170 verify(mBroadcastDispatcher).registerReceiver( 171 any(), mIntentFilterArgumentCaptor.capture(), any(), eq(UserHandle.of(USER)), 172 anyInt(), any()); 173 174 assertTrue( 175 mIntentFilterArgumentCaptor.getValue().hasAction(Intent.ACTION_SETTING_RESTORED)); 176 } 177 178 @Test testBroadcastReceiverChangesWithUser()179 public void testBroadcastReceiverChangesWithUser() { 180 mAutoTracker.changeUser(UserHandle.of(USER + 1)); 181 182 InOrder inOrder = Mockito.inOrder(mBroadcastDispatcher); 183 inOrder.verify(mBroadcastDispatcher).unregisterReceiver(any()); 184 inOrder.verify(mBroadcastDispatcher) 185 .registerReceiver(any(), any(), any(), eq(UserHandle.of(USER + 1)), anyInt(), 186 any()); 187 } 188 189 @Test testSettingRestoredWithTilesNotRemovedInSource_noAutoAddedInTarget()190 public void testSettingRestoredWithTilesNotRemovedInSource_noAutoAddedInTarget() { 191 verify(mBroadcastDispatcher).registerReceiver( 192 mBroadcastReceiverArgumentCaptor.capture(), any(), any(), any(), anyInt(), any()); 193 194 // These tiles were present in the original device 195 String restoredTiles = "saver,work,internet,cast"; 196 Intent restoreTilesIntent = makeRestoreIntent(Secure.QS_TILES, null, restoredTiles); 197 mBroadcastReceiverArgumentCaptor.getValue().onReceive(mContext, restoreTilesIntent); 198 199 // And these tiles have been auto-added in the original device 200 // (no auto-added before restore) 201 String restoredAutoAddTiles = "work"; 202 Intent restoreAutoAddTilesIntent = 203 makeRestoreIntent(Secure.QS_AUTO_ADDED_TILES, null, restoredAutoAddTiles); 204 mBroadcastReceiverArgumentCaptor.getValue().onReceive(mContext, restoreAutoAddTilesIntent); 205 206 // Then, don't remove any current tiles 207 verify(mQSHost, never()).removeTiles(any()); 208 assertEquals(restoredAutoAddTiles, 209 mSecureSettings.getStringForUser(Secure.QS_AUTO_ADDED_TILES, USER)); 210 } 211 212 @Test testSettingRestoredWithTilesRemovedInSource_noAutoAddedInTarget()213 public void testSettingRestoredWithTilesRemovedInSource_noAutoAddedInTarget() { 214 verify(mBroadcastDispatcher) 215 .registerReceiver(mBroadcastReceiverArgumentCaptor.capture(), any(), any(), any(), 216 anyInt(), any()); 217 218 // These tiles were present in the original device 219 String restoredTiles = "saver,internet,cast"; 220 Intent restoreTilesIntent = makeRestoreIntent(Secure.QS_TILES, null, restoredTiles); 221 mBroadcastReceiverArgumentCaptor.getValue().onReceive(mContext, restoreTilesIntent); 222 223 // And these tiles have been auto-added in the original device 224 // (no auto-added before restore) 225 String restoredAutoAddTiles = "work"; 226 Intent restoreAutoAddTilesIntent = 227 makeRestoreIntent(Secure.QS_AUTO_ADDED_TILES, null, restoredAutoAddTiles); 228 mBroadcastReceiverArgumentCaptor.getValue().onReceive(mContext, restoreAutoAddTilesIntent); 229 230 // Then, remove work tile 231 verify(mQSHost).removeTiles(List.of("work")); 232 assertEquals(restoredAutoAddTiles, 233 mSecureSettings.getStringForUser(Secure.QS_AUTO_ADDED_TILES, USER)); 234 } 235 236 @Test testSettingRestoredWithTilesRemovedInSource_sameAutoAddedinTarget()237 public void testSettingRestoredWithTilesRemovedInSource_sameAutoAddedinTarget() { 238 verify(mBroadcastDispatcher) 239 .registerReceiver(mBroadcastReceiverArgumentCaptor.capture(), any(), any(), any(), 240 anyInt(), any()); 241 242 // These tiles were present in the original device 243 String restoredTiles = "saver,internet,cast"; 244 Intent restoreTilesIntent = 245 makeRestoreIntent(Secure.QS_TILES, "saver, internet, cast, work", restoredTiles); 246 mBroadcastReceiverArgumentCaptor.getValue().onReceive(mContext, restoreTilesIntent); 247 248 // And these tiles have been auto-added in the original device 249 // (no auto-added before restore) 250 String restoredAutoAddTiles = "work"; 251 Intent restoreAutoAddTilesIntent = 252 makeRestoreIntent(Secure.QS_AUTO_ADDED_TILES, "work", restoredAutoAddTiles); 253 mBroadcastReceiverArgumentCaptor.getValue().onReceive(mContext, restoreAutoAddTilesIntent); 254 255 // Then, remove work tile 256 verify(mQSHost).removeTiles(List.of("work")); 257 assertEquals(restoredAutoAddTiles, 258 mSecureSettings.getStringForUser(Secure.QS_AUTO_ADDED_TILES, USER)); 259 } 260 261 @Test testSettingRestoredWithTilesRemovedInSource_othersAutoAddedinTarget()262 public void testSettingRestoredWithTilesRemovedInSource_othersAutoAddedinTarget() { 263 verify(mBroadcastDispatcher) 264 .registerReceiver(mBroadcastReceiverArgumentCaptor.capture(), any(), any(), any(), 265 anyInt(), any()); 266 267 // These tiles were present in the original device 268 String restoredTiles = "saver,internet,cast"; 269 Intent restoreTilesIntent = 270 makeRestoreIntent(Secure.QS_TILES, "saver, internet, cast, work", restoredTiles); 271 mBroadcastReceiverArgumentCaptor.getValue().onReceive(mContext, restoreTilesIntent); 272 273 // And these tiles have been auto-added in the original device 274 // (no auto-added before restore) 275 String restoredAutoAddTiles = "work"; 276 Intent restoreAutoAddTilesIntent = 277 makeRestoreIntent(Secure.QS_AUTO_ADDED_TILES, "inversion", restoredAutoAddTiles); 278 mBroadcastReceiverArgumentCaptor.getValue().onReceive(mContext, restoreAutoAddTilesIntent); 279 280 // Then, remove work tile 281 verify(mQSHost).removeTiles(List.of("work")); 282 283 String setting = mSecureSettings.getStringForUser(Secure.QS_AUTO_ADDED_TILES, USER); 284 assertEquals(2, setting.split(",").length); 285 assertTrue(setting.contains("work")); 286 assertTrue(setting.contains("inversion")); 287 } 288 289 makeRestoreIntent( String settingName, String previousValue, String restoredValue)290 private Intent makeRestoreIntent( 291 String settingName, String previousValue, String restoredValue) { 292 Intent intent = new Intent(Intent.ACTION_SETTING_RESTORED); 293 intent.putExtra(Intent.EXTRA_SETTING_NAME, settingName); 294 intent.putExtra(Intent.EXTRA_SETTING_PREVIOUS_VALUE, previousValue); 295 intent.putExtra(Intent.EXTRA_SETTING_NEW_VALUE, restoredValue); 296 return intent; 297 } 298 createAutoAddTracker(int user)299 private AutoAddTracker createAutoAddTracker(int user) { 300 // Null handler wil dispatch sync. 301 return new AutoAddTracker( 302 mSecureSettings, 303 mBroadcastDispatcher, 304 mQSHost, 305 mDumpManager, 306 null, 307 mBackgroundExecutor, 308 user 309 ); 310 } 311 }