Merge cherrypicks of ['ag/20690268', 'ag/20877927', 'ag/20965081'] into tm-qpr2-release.

Change-Id: I9e4cdb6a9a8b795c6edae0ac52b693020f5f8eee
This commit is contained in:
Android Build Coastguard Worker
2023-01-24 01:31:33 +00:00
12 changed files with 179 additions and 93 deletions

View File

@@ -148,9 +148,4 @@
<include layout="@layout/ongoing_privacy_chip"/>
</FrameLayout>
<Space
android:layout_width="0dp"
android:layout_height="0dp"
android:id="@+id/space"
/>
</com.android.systemui.util.NoRemeasureMotionLayout>

View File

@@ -56,13 +56,9 @@
<Layout
android:layout_width="wrap_content"
android:layout_height="@dimen/new_qs_header_non_clickable_element_height"
app:layout_constrainedWidth="true"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/space"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@id/carrier_group"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintHorizontal_chainStyle="spread_inside"
/>
</Constraint>
@@ -87,39 +83,27 @@
<Constraint
android:id="@+id/statusIcons">
<Layout
android:layout_width="wrap_content"
android:layout_width="0dp"
android:layout_height="@dimen/new_qs_header_non_clickable_element_height"
app:layout_constraintStart_toEndOf="@id/space"
app:layout_constraintWidth_default="wrap"
app:layout_constraintStart_toEndOf="@id/date"
app:layout_constraintEnd_toStartOf="@id/batteryRemainingIcon"
app:layout_constraintTop_toTopOf="@id/date"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_bias="1"
app:layout_constraintBottom_toBottomOf="@id/date"
/>
</Constraint>
<Constraint
android:id="@+id/batteryRemainingIcon">
<Layout
android:layout_width="wrap_content"
android:layout_width="0dp"
android:layout_height="@dimen/new_qs_header_non_clickable_element_height"
app:layout_constraintWidth_default="wrap"
app:layout_constraintHeight_min="@dimen/new_qs_header_non_clickable_element_height"
app:layout_constraintStart_toEndOf="@id/statusIcons"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/date"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_bias="1"
app:layout_constraintHorizontal_chainStyle="spread_inside"
app:layout_constraintBottom_toBottomOf="@id/date"
/>
</Constraint>
<Constraint
android:id="@id/space">
<Layout
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintStart_toEndOf="@id/date"
app:layout_constraintEnd_toStartOf="@id/statusIcons"
/>
</Constraint>
</ConstraintSet>

View File

@@ -36,7 +36,6 @@ public interface QSHost {
void removeCallback(Callback callback);
void removeTile(String tileSpec);
void removeTiles(Collection<String> specs);
void unmarkTileAsAutoAdded(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)));
}
@Override
public void unmarkTileAsAutoAdded(String spec) {
if (mAutoTiles != null) mAutoTiles.unmarkTileAsAutoAdded(spec);
}
/**
* Add a tile to the end
*

View File

@@ -101,7 +101,6 @@ public class WorkModeTile extends QSTileImpl<BooleanState> implements
@MainThread
public void onManagedProfileRemoved() {
mHost.removeTile(getTileSpec());
mHost.unmarkTileAsAutoAdded(getTileSpec());
}
@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.
addAction(Intent.ACTION_MANAGED_PROFILE_AVAILABLE)
addAction(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE)
addAction(Intent.ACTION_MANAGED_PROFILE_ADDED)
addAction(Intent.ACTION_MANAGED_PROFILE_REMOVED)
addAction(Intent.ACTION_MANAGED_PROFILE_UNLOCKED)
}
@@ -129,6 +129,7 @@ class UserTrackerImpl internal constructor(
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 -> {
handleProfilesChanged()

View File

@@ -154,9 +154,7 @@ public class AutoTileManager implements UserAwareController {
if (!mAutoTracker.isAdded(SAVER)) {
mDataSaverController.addCallback(mDataSaverListener);
}
if (!mAutoTracker.isAdded(WORK)) {
mManagedProfileController.addCallback(mProfileCallback);
}
mManagedProfileController.addCallback(mProfileCallback);
if (!mAutoTracker.isAdded(NIGHT)
&& ColorDisplayManager.isNightDisplayAvailable(mContext)) {
mNightDisplayListener.setCallback(mNightDisplayCallback);
@@ -275,18 +273,18 @@ public class AutoTileManager implements UserAwareController {
return mCurrentUser.getIdentifier();
}
public void unmarkTileAsAutoAdded(String tabSpec) {
mAutoTracker.setTileRemoved(tabSpec);
}
private final ManagedProfileController.Callback mProfileCallback =
new ManagedProfileController.Callback() {
@Override
public void onManagedProfileChanged() {
if (mAutoTracker.isAdded(WORK)) return;
if (mManagedProfileController.hasActiveProfile()) {
if (mAutoTracker.isAdded(WORK)) return;
mHost.addTile(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();
} else if (!isSafetyCenterEnabled && mAutoTracker.isAdded(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(
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
@@ -279,37 +289,6 @@ class UserTrackerImplTest : SysuiTestCase() {
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
fun testCallbackCalledOnUserInfoChanged() {
tracker.initialize(0)

View File

@@ -17,6 +17,7 @@
package com.android.systemui.shade
import android.testing.AndroidTestingRunner
import android.view.ViewGroup
import androidx.constraintlayout.widget.ConstraintSet
import androidx.constraintlayout.widget.ConstraintSet.PARENT_ID
import androidx.constraintlayout.widget.ConstraintSet.START
@@ -92,12 +93,12 @@ class CombinedShadeHeaderConstraintsTest : SysuiTestCase() {
assertThat(getConstraint(R.id.clock).layout.horizontalBias).isEqualTo(0f)
assertThat(getConstraint(R.id.date).layout.startToStart).isEqualTo(PARENT_ID)
assertThat(getConstraint(R.id.date).layout.horizontalBias).isEqualTo(0f)
assertThat(getConstraint(R.id.date).layout.horizontalBias).isEqualTo(0.5f)
assertThat(getConstraint(R.id.batteryRemainingIcon).layout.endToEnd)
.isEqualTo(PARENT_ID)
assertThat(getConstraint(R.id.batteryRemainingIcon).layout.horizontalBias)
.isEqualTo(1f)
.isEqualTo(0.5f)
assertThat(getConstraint(R.id.privacy_container).layout.endToEnd)
.isEqualTo(R.id.end_guide)
@@ -331,10 +332,8 @@ class CombinedShadeHeaderConstraintsTest : SysuiTestCase() {
val views = mapOf(
R.id.clock to "clock",
R.id.date to "date",
R.id.statusIcons to "icons",
R.id.privacy_container to "privacy",
R.id.carrier_group to "carriers",
R.id.batteryRemainingIcon to "battery",
)
views.forEach { (id, name) ->
assertWithMessage("$name has 0 height in qqs")
@@ -352,11 +351,8 @@ class CombinedShadeHeaderConstraintsTest : SysuiTestCase() {
fun testCheckViewsDontChangeSizeBetweenAnimationConstraints() {
val views = mapOf(
R.id.clock to "clock",
R.id.date to "date",
R.id.statusIcons to "icons",
R.id.privacy_container to "privacy",
R.id.carrier_group to "carriers",
R.id.batteryRemainingIcon to "battery",
)
views.forEach { (id, name) ->
expect.withMessage("$name changes height")
@@ -369,8 +365,8 @@ class CombinedShadeHeaderConstraintsTest : SysuiTestCase() {
}
private fun Int.fromConstraint() = when (this) {
-1 -> "MATCH_PARENT"
-2 -> "WRAP_CONTENT"
ViewGroup.LayoutParams.MATCH_PARENT -> "MATCH_PARENT"
ViewGroup.LayoutParams.WRAP_CONTENT -> "WRAP_CONTENT"
else -> toString()
}

View File

@@ -24,6 +24,7 @@ import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isNotNull;
import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.Mockito.doReturn;
@@ -74,6 +75,7 @@ import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
import org.mockito.stubbing.Answer;
import java.util.Collections;
import java.util.List;
@@ -115,8 +117,10 @@ public class AutoTileManagerTest extends SysuiTestCase {
@Spy private PackageManager mPackageManager;
private final boolean mIsReduceBrightColorsAvailable = true;
private AutoTileManager mAutoTileManager;
private AutoTileManager mAutoTileManager; // under test
private SecureSettings mSecureSettings;
private ManagedProfileController.Callback mManagedProfileCallback;
@Before
public void setUp() throws Exception {
@@ -303,7 +307,7 @@ public class AutoTileManagerTest extends SysuiTestCase {
InOrder inOrderManagedProfile = inOrder(mManagedProfileController);
inOrderManagedProfile.verify(mManagedProfileController).removeCallback(any());
inOrderManagedProfile.verify(mManagedProfileController, never()).addCallback(any());
inOrderManagedProfile.verify(mManagedProfileController).addCallback(any());
if (ColorDisplayManager.isNightDisplayAvailable(mContext)) {
InOrder inOrderNightDisplay = inOrder(mNightDisplayListener);
@@ -503,6 +507,40 @@ public class AutoTileManagerTest extends SysuiTestCase {
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
public void testEmptyArray_doesNotCrash() {
mContext.getOrCreateTestableResources().addOverride(

View File

@@ -8196,15 +8196,13 @@ public class ActivityManagerService extends IActivityManager.Stub
t.traceEnd();
}
boolean isBootingSystemUser = currentUserId == UserHandle.USER_SYSTEM;
// Some systems - like automotive - will explicitly unlock system user then switch
// to a secondary user. Hence, we don't want to send duplicate broadcasts for
// the system user here.
// to a secondary user.
// TODO(b/242195409): this workaround shouldn't be necessary once we move
// the headless-user start logic to UserManager-land.
final boolean isBootingSystemUser = (currentUserId == UserHandle.USER_SYSTEM)
&& !UserManager.isHeadlessSystemUserMode();
if (isBootingSystemUser) {
if (isBootingSystemUser && !UserManager.isHeadlessSystemUserMode()) {
t.traceBegin("startHomeOnAllDisplays");
mAtmInternal.startHomeOnAllDisplays(currentUserId, "systemReady");
t.traceEnd();
@@ -8216,6 +8214,10 @@ public class ActivityManagerService extends IActivityManager.Stub
if (isBootingSystemUser) {
// Need to send the broadcasts for the system user here because
// UserController#startUserInternal will not send them for the system user starting,
// It checks if the user state already exists, which is always the case for the
// system user.
t.traceBegin("sendUserStartBroadcast");
final int callingUid = Binder.getCallingUid();
final int callingPid = Binder.getCallingPid();