/* * Copyright (C) 2017 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under the * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the specific language governing * permissions and limitations under the License. */ package com.android.systemui.qs; import static com.android.systemui.statusbar.phone.AutoTileManager.SAVER; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.any; import static org.mockito.Mockito.anyInt; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import android.content.BroadcastReceiver; import android.content.Intent; import android.content.IntentFilter; import android.os.UserHandle; import android.provider.Settings.Secure; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper.RunWithLooper; import androidx.test.filters.SmallTest; import com.android.systemui.SysuiTestCase; import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.dump.DumpManager; import com.android.systemui.util.settings.FakeSettings; import com.android.systemui.util.settings.SecureSettings; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Captor; import org.mockito.InOrder; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; import java.util.List; import java.util.concurrent.Executor; @RunWith(AndroidTestingRunner.class) @RunWithLooper @SmallTest public class AutoAddTrackerTest extends SysuiTestCase { private static final int END_POSITION = -1; private static final int USER = 0; @Mock private BroadcastDispatcher mBroadcastDispatcher; @Mock private QSHost mQSHost; @Mock private DumpManager mDumpManager; @Captor private ArgumentCaptor mBroadcastReceiverArgumentCaptor; @Captor private ArgumentCaptor mIntentFilterArgumentCaptor; private Executor mBackgroundExecutor = Runnable::run; // Direct executor private AutoAddTracker mAutoTracker; private SecureSettings mSecureSettings; @Before public void setUp() { MockitoAnnotations.initMocks(this); mSecureSettings = new FakeSettings(); mSecureSettings.putStringForUser(Secure.QS_AUTO_ADDED_TILES, null, USER); mAutoTracker = createAutoAddTracker(USER); mAutoTracker.initialize(); } @Test public void testChangeFromBackup() { assertFalse(mAutoTracker.isAdded(SAVER)); mSecureSettings.putStringForUser(Secure.QS_AUTO_ADDED_TILES, SAVER, USER); assertTrue(mAutoTracker.isAdded(SAVER)); mAutoTracker.destroy(); } @Test public void testSetAdded() { assertFalse(mAutoTracker.isAdded(SAVER)); mAutoTracker.setTileAdded(SAVER); assertTrue(mAutoTracker.isAdded(SAVER)); mAutoTracker.destroy(); } @Test public void testPersist() { assertFalse(mAutoTracker.isAdded(SAVER)); mAutoTracker.setTileAdded(SAVER); mAutoTracker.destroy(); mAutoTracker = createAutoAddTracker(USER); mAutoTracker.initialize(); assertTrue(mAutoTracker.isAdded(SAVER)); mAutoTracker.destroy(); } @Test public void testIndependentUsers() { mAutoTracker.setTileAdded(SAVER); mAutoTracker = createAutoAddTracker(USER + 1); mAutoTracker.initialize(); assertFalse(mAutoTracker.isAdded(SAVER)); } @Test public void testChangeUser() { mAutoTracker.setTileAdded(SAVER); mAutoTracker = createAutoAddTracker(USER + 1); mAutoTracker.changeUser(UserHandle.of(USER)); assertTrue(mAutoTracker.isAdded(SAVER)); } @Test public void testRestoredTilePositionPreserved() { verify(mBroadcastDispatcher).registerReceiver( mBroadcastReceiverArgumentCaptor.capture(), any(), any(), any(), anyInt(), any()); String restoredTiles = "saver,internet,work,cast"; Intent restoreTilesIntent = makeRestoreIntent(Secure.QS_TILES, null, restoredTiles); mBroadcastReceiverArgumentCaptor.getValue().onReceive(mContext, restoreTilesIntent); assertEquals(2, mAutoTracker.getRestoredTilePosition("work")); } @Test public void testNoRestoredTileReturnsEndPosition() { verify(mBroadcastDispatcher).registerReceiver( mBroadcastReceiverArgumentCaptor.capture(), any(), any(), any(), anyInt(), any()); Intent restoreTilesIntent = makeRestoreIntent(Secure.QS_TILES, null, null); mBroadcastReceiverArgumentCaptor.getValue().onReceive(mContext, restoreTilesIntent); assertEquals(END_POSITION, mAutoTracker.getRestoredTilePosition("work")); } @Test public void testBroadcastReceiverRegistered() { verify(mBroadcastDispatcher).registerReceiver( any(), mIntentFilterArgumentCaptor.capture(), any(), eq(UserHandle.of(USER)), anyInt(), any()); assertTrue( mIntentFilterArgumentCaptor.getValue().hasAction(Intent.ACTION_SETTING_RESTORED)); } @Test public void testBroadcastReceiverChangesWithUser() { mAutoTracker.changeUser(UserHandle.of(USER + 1)); InOrder inOrder = Mockito.inOrder(mBroadcastDispatcher); inOrder.verify(mBroadcastDispatcher).unregisterReceiver(any()); inOrder.verify(mBroadcastDispatcher) .registerReceiver(any(), any(), any(), eq(UserHandle.of(USER + 1)), anyInt(), any()); } @Test public void testSettingRestoredWithTilesNotRemovedInSource_noAutoAddedInTarget() { verify(mBroadcastDispatcher).registerReceiver( mBroadcastReceiverArgumentCaptor.capture(), any(), any(), any(), anyInt(), any()); // These tiles were present in the original device String restoredTiles = "saver,work,internet,cast"; Intent restoreTilesIntent = makeRestoreIntent(Secure.QS_TILES, null, restoredTiles); mBroadcastReceiverArgumentCaptor.getValue().onReceive(mContext, restoreTilesIntent); // And these tiles have been auto-added in the original device // (no auto-added before restore) String restoredAutoAddTiles = "work"; Intent restoreAutoAddTilesIntent = makeRestoreIntent(Secure.QS_AUTO_ADDED_TILES, null, restoredAutoAddTiles); mBroadcastReceiverArgumentCaptor.getValue().onReceive(mContext, restoreAutoAddTilesIntent); // Then, don't remove any current tiles verify(mQSHost, never()).removeTiles(any()); assertEquals(restoredAutoAddTiles, mSecureSettings.getStringForUser(Secure.QS_AUTO_ADDED_TILES, USER)); } @Test public void testSettingRestoredWithTilesRemovedInSource_noAutoAddedInTarget() { verify(mBroadcastDispatcher) .registerReceiver(mBroadcastReceiverArgumentCaptor.capture(), any(), any(), any(), anyInt(), any()); // These tiles were present in the original device String restoredTiles = "saver,internet,cast"; Intent restoreTilesIntent = makeRestoreIntent(Secure.QS_TILES, null, restoredTiles); mBroadcastReceiverArgumentCaptor.getValue().onReceive(mContext, restoreTilesIntent); // And these tiles have been auto-added in the original device // (no auto-added before restore) String restoredAutoAddTiles = "work"; Intent restoreAutoAddTilesIntent = makeRestoreIntent(Secure.QS_AUTO_ADDED_TILES, null, restoredAutoAddTiles); mBroadcastReceiverArgumentCaptor.getValue().onReceive(mContext, restoreAutoAddTilesIntent); // Then, remove work tile verify(mQSHost).removeTiles(List.of("work")); assertEquals(restoredAutoAddTiles, mSecureSettings.getStringForUser(Secure.QS_AUTO_ADDED_TILES, USER)); } @Test public void testSettingRestoredWithTilesRemovedInSource_sameAutoAddedinTarget() { verify(mBroadcastDispatcher) .registerReceiver(mBroadcastReceiverArgumentCaptor.capture(), any(), any(), any(), anyInt(), any()); // These tiles were present in the original device String restoredTiles = "saver,internet,cast"; Intent restoreTilesIntent = makeRestoreIntent(Secure.QS_TILES, "saver, internet, cast, work", restoredTiles); mBroadcastReceiverArgumentCaptor.getValue().onReceive(mContext, restoreTilesIntent); // And these tiles have been auto-added in the original device // (no auto-added before restore) String restoredAutoAddTiles = "work"; Intent restoreAutoAddTilesIntent = makeRestoreIntent(Secure.QS_AUTO_ADDED_TILES, "work", restoredAutoAddTiles); mBroadcastReceiverArgumentCaptor.getValue().onReceive(mContext, restoreAutoAddTilesIntent); // Then, remove work tile verify(mQSHost).removeTiles(List.of("work")); assertEquals(restoredAutoAddTiles, mSecureSettings.getStringForUser(Secure.QS_AUTO_ADDED_TILES, USER)); } @Test public void testSettingRestoredWithTilesRemovedInSource_othersAutoAddedinTarget() { verify(mBroadcastDispatcher) .registerReceiver(mBroadcastReceiverArgumentCaptor.capture(), any(), any(), any(), anyInt(), any()); // These tiles were present in the original device String restoredTiles = "saver,internet,cast"; Intent restoreTilesIntent = makeRestoreIntent(Secure.QS_TILES, "saver, internet, cast, work", restoredTiles); mBroadcastReceiverArgumentCaptor.getValue().onReceive(mContext, restoreTilesIntent); // And these tiles have been auto-added in the original device // (no auto-added before restore) String restoredAutoAddTiles = "work"; Intent restoreAutoAddTilesIntent = makeRestoreIntent(Secure.QS_AUTO_ADDED_TILES, "inversion", restoredAutoAddTiles); mBroadcastReceiverArgumentCaptor.getValue().onReceive(mContext, restoreAutoAddTilesIntent); // Then, remove work tile verify(mQSHost).removeTiles(List.of("work")); String setting = mSecureSettings.getStringForUser(Secure.QS_AUTO_ADDED_TILES, USER); assertEquals(2, setting.split(",").length); assertTrue(setting.contains("work")); assertTrue(setting.contains("inversion")); } private Intent makeRestoreIntent( String settingName, String previousValue, String restoredValue) { Intent intent = new Intent(Intent.ACTION_SETTING_RESTORED); intent.putExtra(Intent.EXTRA_SETTING_NAME, settingName); intent.putExtra(Intent.EXTRA_SETTING_PREVIOUS_VALUE, previousValue); intent.putExtra(Intent.EXTRA_SETTING_NEW_VALUE, restoredValue); return intent; } private AutoAddTracker createAutoAddTracker(int user) { // Null handler wil dispatch sync. return new AutoAddTracker( mSecureSettings, mBroadcastDispatcher, mQSHost, mDumpManager, null, mBackgroundExecutor, user ); } }