Merge "Fix work tile setup when adding work profile" into tm-qpr-dev

This commit is contained in:
Anton Potapov
2023-01-11 21:32:43 +00:00
committed by Android (Google) Code Review
8 changed files with 159 additions and 50 deletions

View File

@@ -36,7 +36,6 @@ public interface QSHost {
void removeCallback(Callback callback); void removeCallback(Callback callback);
void removeTile(String tileSpec); void removeTile(String tileSpec);
void removeTiles(Collection<String> specs); void removeTiles(Collection<String> specs);
void unmarkTileAsAutoAdded(String tileSpec);
int indexOf(String tileSpec); int indexOf(String tileSpec);

View File

@@ -427,11 +427,6 @@ public class QSTileHost implements QSHost, Tunable, PluginListener<QSFactory>, P
mMainExecutor.execute(() -> changeTileSpecs(tileSpecs -> tileSpecs.removeAll(specs))); mMainExecutor.execute(() -> changeTileSpecs(tileSpecs -> tileSpecs.removeAll(specs)));
} }
@Override
public void unmarkTileAsAutoAdded(String spec) {
if (mAutoTiles != null) mAutoTiles.unmarkTileAsAutoAdded(spec);
}
/** /**
* Add a tile to the end * Add a tile to the end
* *

View File

@@ -101,7 +101,6 @@ public class WorkModeTile extends QSTileImpl<BooleanState> implements
@MainThread @MainThread
public void onManagedProfileRemoved() { public void onManagedProfileRemoved() {
mHost.removeTile(getTileSpec()); mHost.removeTile(getTileSpec());
mHost.unmarkTileAsAutoAdded(getTileSpec());
} }
@Override @Override

View File

@@ -112,7 +112,7 @@ class UserTrackerImpl internal constructor(
// These get called when a managed profile goes in or out of quiet mode. // These get called when a managed profile goes in or out of quiet mode.
addAction(Intent.ACTION_MANAGED_PROFILE_AVAILABLE) addAction(Intent.ACTION_MANAGED_PROFILE_AVAILABLE)
addAction(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE) addAction(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE)
addAction(Intent.ACTION_MANAGED_PROFILE_ADDED)
addAction(Intent.ACTION_MANAGED_PROFILE_REMOVED) addAction(Intent.ACTION_MANAGED_PROFILE_REMOVED)
addAction(Intent.ACTION_MANAGED_PROFILE_UNLOCKED) addAction(Intent.ACTION_MANAGED_PROFILE_UNLOCKED)
} }
@@ -129,6 +129,7 @@ class UserTrackerImpl internal constructor(
Intent.ACTION_USER_INFO_CHANGED, Intent.ACTION_USER_INFO_CHANGED,
Intent.ACTION_MANAGED_PROFILE_AVAILABLE, Intent.ACTION_MANAGED_PROFILE_AVAILABLE,
Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE, Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE,
Intent.ACTION_MANAGED_PROFILE_ADDED,
Intent.ACTION_MANAGED_PROFILE_REMOVED, Intent.ACTION_MANAGED_PROFILE_REMOVED,
Intent.ACTION_MANAGED_PROFILE_UNLOCKED -> { Intent.ACTION_MANAGED_PROFILE_UNLOCKED -> {
handleProfilesChanged() handleProfilesChanged()

View File

@@ -154,9 +154,7 @@ public class AutoTileManager implements UserAwareController {
if (!mAutoTracker.isAdded(SAVER)) { if (!mAutoTracker.isAdded(SAVER)) {
mDataSaverController.addCallback(mDataSaverListener); mDataSaverController.addCallback(mDataSaverListener);
} }
if (!mAutoTracker.isAdded(WORK)) { mManagedProfileController.addCallback(mProfileCallback);
mManagedProfileController.addCallback(mProfileCallback);
}
if (!mAutoTracker.isAdded(NIGHT) if (!mAutoTracker.isAdded(NIGHT)
&& ColorDisplayManager.isNightDisplayAvailable(mContext)) { && ColorDisplayManager.isNightDisplayAvailable(mContext)) {
mNightDisplayListener.setCallback(mNightDisplayCallback); mNightDisplayListener.setCallback(mNightDisplayCallback);
@@ -275,18 +273,18 @@ public class AutoTileManager implements UserAwareController {
return mCurrentUser.getIdentifier(); return mCurrentUser.getIdentifier();
} }
public void unmarkTileAsAutoAdded(String tabSpec) {
mAutoTracker.setTileRemoved(tabSpec);
}
private final ManagedProfileController.Callback mProfileCallback = private final ManagedProfileController.Callback mProfileCallback =
new ManagedProfileController.Callback() { new ManagedProfileController.Callback() {
@Override @Override
public void onManagedProfileChanged() { public void onManagedProfileChanged() {
if (mAutoTracker.isAdded(WORK)) return;
if (mManagedProfileController.hasActiveProfile()) { if (mManagedProfileController.hasActiveProfile()) {
if (mAutoTracker.isAdded(WORK)) return;
mHost.addTile(WORK); mHost.addTile(WORK);
mAutoTracker.setTileAdded(WORK); mAutoTracker.setTileAdded(WORK);
} else {
if (!mAutoTracker.isAdded(WORK)) return;
mHost.removeTile(WORK);
mAutoTracker.setTileRemoved(WORK);
} }
} }
@@ -429,7 +427,7 @@ public class AutoTileManager implements UserAwareController {
initSafetyTile(); initSafetyTile();
} else if (!isSafetyCenterEnabled && mAutoTracker.isAdded(mSafetySpec)) { } else if (!isSafetyCenterEnabled && mAutoTracker.isAdded(mSafetySpec)) {
mHost.removeTile(mSafetySpec); mHost.removeTile(mSafetySpec);
mHost.unmarkTileAsAutoAdded(mSafetySpec); mAutoTracker.setTileRemoved(mSafetySpec);
} }
} }
}; };

View File

@@ -0,0 +1,100 @@
package com.android.systemui.settings
import android.content.Context
import android.content.Intent
import android.content.pm.UserInfo
import android.os.Handler
import android.os.UserHandle
import android.os.UserManager
import androidx.concurrent.futures.DirectExecutor
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.dump.DumpManager
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.capture
import com.google.common.truth.Truth.assertThat
import java.util.concurrent.Executor
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
import org.mockito.ArgumentCaptor
import org.mockito.ArgumentMatchers
import org.mockito.ArgumentMatchers.anyInt
import org.mockito.Captor
import org.mockito.Mock
import org.mockito.Mockito.times
import org.mockito.Mockito.verify
import org.mockito.Mockito.`when`
import org.mockito.MockitoAnnotations
@SmallTest
@RunWith(Parameterized::class)
class UserTrackerImplReceiveTest : SysuiTestCase() {
companion object {
@JvmStatic
@Parameterized.Parameters
fun data(): Iterable<String> =
listOf(
Intent.ACTION_USER_INFO_CHANGED,
Intent.ACTION_MANAGED_PROFILE_AVAILABLE,
Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE,
Intent.ACTION_MANAGED_PROFILE_ADDED,
Intent.ACTION_MANAGED_PROFILE_REMOVED,
Intent.ACTION_MANAGED_PROFILE_UNLOCKED
)
}
private val executor: Executor = DirectExecutor.INSTANCE
@Mock private lateinit var context: Context
@Mock private lateinit var userManager: UserManager
@Mock(stubOnly = true) private lateinit var dumpManager: DumpManager
@Mock(stubOnly = true) private lateinit var handler: Handler
@Parameterized.Parameter lateinit var intentAction: String
@Mock private lateinit var callback: UserTracker.Callback
@Captor private lateinit var captor: ArgumentCaptor<List<UserInfo>>
private lateinit var tracker: UserTrackerImpl
@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
`when`(context.user).thenReturn(UserHandle.SYSTEM)
`when`(context.createContextAsUser(ArgumentMatchers.any(), anyInt())).thenReturn(context)
tracker = UserTrackerImpl(context, userManager, dumpManager, handler)
}
@Test
fun `calls callback and updates profiles when an intent received`() {
tracker.initialize(0)
tracker.addCallback(callback, executor)
val profileID = tracker.userId + 10
`when`(userManager.getProfiles(anyInt())).thenAnswer { invocation ->
val id = invocation.getArgument<Int>(0)
val info = UserInfo(id, "", UserInfo.FLAG_FULL)
val infoProfile =
UserInfo(
id + 10,
"",
"",
UserInfo.FLAG_MANAGED_PROFILE,
UserManager.USER_TYPE_PROFILE_MANAGED
)
infoProfile.profileGroupId = id
listOf(info, infoProfile)
}
tracker.onReceive(context, Intent(intentAction))
verify(callback, times(0)).onUserChanged(anyInt(), any())
verify(callback, times(1)).onProfilesChanged(capture(captor))
assertThat(captor.value.map { it.id }).containsExactly(0, profileID)
}
}

View File

@@ -124,6 +124,16 @@ class UserTrackerImplTest : SysuiTestCase() {
verify(context).registerReceiverForAllUsers( verify(context).registerReceiverForAllUsers(
eq(tracker), capture(captor), isNull(), eq(handler)) eq(tracker), capture(captor), isNull(), eq(handler))
with(captor.value) {
assertThat(countActions()).isEqualTo(7)
assertThat(hasAction(Intent.ACTION_USER_SWITCHED)).isTrue()
assertThat(hasAction(Intent.ACTION_USER_INFO_CHANGED)).isTrue()
assertThat(hasAction(Intent.ACTION_MANAGED_PROFILE_AVAILABLE)).isTrue()
assertThat(hasAction(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE)).isTrue()
assertThat(hasAction(Intent.ACTION_MANAGED_PROFILE_ADDED)).isTrue()
assertThat(hasAction(Intent.ACTION_MANAGED_PROFILE_REMOVED)).isTrue()
assertThat(hasAction(Intent.ACTION_MANAGED_PROFILE_UNLOCKED)).isTrue()
}
} }
@Test @Test
@@ -279,37 +289,6 @@ class UserTrackerImplTest : SysuiTestCase() {
assertThat(callback.lastUserProfiles.map { it.id }).containsExactly(newID) assertThat(callback.lastUserProfiles.map { it.id }).containsExactly(newID)
} }
@Test
fun testCallbackCalledOnProfileChanged() {
tracker.initialize(0)
val callback = TestCallback()
tracker.addCallback(callback, executor)
val profileID = tracker.userId + 10
`when`(userManager.getProfiles(anyInt())).thenAnswer { invocation ->
val id = invocation.getArgument<Int>(0)
val info = UserInfo(id, "", UserInfo.FLAG_FULL)
val infoProfile = UserInfo(
id + 10,
"",
"",
UserInfo.FLAG_MANAGED_PROFILE,
UserManager.USER_TYPE_PROFILE_MANAGED
)
infoProfile.profileGroupId = id
listOf(info, infoProfile)
}
val intent = Intent(Intent.ACTION_MANAGED_PROFILE_AVAILABLE)
.putExtra(Intent.EXTRA_USER, UserHandle.of(profileID))
tracker.onReceive(context, intent)
assertThat(callback.calledOnUserChanged).isEqualTo(0)
assertThat(callback.calledOnProfilesChanged).isEqualTo(1)
assertThat(callback.lastUserProfiles.map { it.id }).containsExactly(0, profileID)
}
@Test @Test
fun testCallbackCalledOnUserInfoChanged() { fun testCallbackCalledOnUserInfoChanged() {
tracker.initialize(0) tracker.initialize(0)

View File

@@ -24,6 +24,7 @@ import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail; import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isNotNull; import static org.mockito.ArgumentMatchers.isNotNull;
import static org.mockito.ArgumentMatchers.isNull; import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doReturn;
@@ -74,6 +75,7 @@ import org.mockito.Mock;
import org.mockito.Mockito; import org.mockito.Mockito;
import org.mockito.MockitoAnnotations; import org.mockito.MockitoAnnotations;
import org.mockito.Spy; import org.mockito.Spy;
import org.mockito.stubbing.Answer;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
@@ -115,8 +117,10 @@ public class AutoTileManagerTest extends SysuiTestCase {
@Spy private PackageManager mPackageManager; @Spy private PackageManager mPackageManager;
private final boolean mIsReduceBrightColorsAvailable = true; private final boolean mIsReduceBrightColorsAvailable = true;
private AutoTileManager mAutoTileManager; private AutoTileManager mAutoTileManager; // under test
private SecureSettings mSecureSettings; private SecureSettings mSecureSettings;
private ManagedProfileController.Callback mManagedProfileCallback;
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
@@ -303,7 +307,7 @@ public class AutoTileManagerTest extends SysuiTestCase {
InOrder inOrderManagedProfile = inOrder(mManagedProfileController); InOrder inOrderManagedProfile = inOrder(mManagedProfileController);
inOrderManagedProfile.verify(mManagedProfileController).removeCallback(any()); inOrderManagedProfile.verify(mManagedProfileController).removeCallback(any());
inOrderManagedProfile.verify(mManagedProfileController, never()).addCallback(any()); inOrderManagedProfile.verify(mManagedProfileController).addCallback(any());
if (ColorDisplayManager.isNightDisplayAvailable(mContext)) { if (ColorDisplayManager.isNightDisplayAvailable(mContext)) {
InOrder inOrderNightDisplay = inOrder(mNightDisplayListener); InOrder inOrderNightDisplay = inOrder(mNightDisplayListener);
@@ -503,6 +507,40 @@ public class AutoTileManagerTest extends SysuiTestCase {
verify(mQsTileHost, times(2)).addTile(safetyComponent, true); verify(mQsTileHost, times(2)).addTile(safetyComponent, true);
} }
@Test
public void managedProfileAdded_tileAdded() {
when(mAutoAddTracker.isAdded(eq("work"))).thenReturn(false);
mAutoTileManager = createAutoTileManager(mContext);
Mockito.doAnswer((Answer<Object>) invocation -> {
mManagedProfileCallback = invocation.getArgument(0);
return null;
}).when(mManagedProfileController).addCallback(any());
mAutoTileManager.init();
when(mManagedProfileController.hasActiveProfile()).thenReturn(true);
mManagedProfileCallback.onManagedProfileChanged();
verify(mQsTileHost, times(1)).addTile(eq("work"));
verify(mAutoAddTracker, times(1)).setTileAdded(eq("work"));
}
@Test
public void managedProfileRemoved_tileRemoved() {
when(mAutoAddTracker.isAdded(eq("work"))).thenReturn(true);
mAutoTileManager = createAutoTileManager(mContext);
Mockito.doAnswer((Answer<Object>) invocation -> {
mManagedProfileCallback = invocation.getArgument(0);
return null;
}).when(mManagedProfileController).addCallback(any());
mAutoTileManager.init();
when(mManagedProfileController.hasActiveProfile()).thenReturn(false);
mManagedProfileCallback.onManagedProfileChanged();
verify(mQsTileHost, times(1)).removeTile(eq("work"));
verify(mAutoAddTracker, times(1)).setTileRemoved(eq("work"));
}
@Test @Test
public void testEmptyArray_doesNotCrash() { public void testEmptyArray_doesNotCrash() {
mContext.getOrCreateTestableResources().addOverride( mContext.getOrCreateTestableResources().addOverride(