• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 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.systemui.qs.pipeline.domain.interactor
18 
19 import android.content.pm.UserInfo
20 import android.os.UserManager
21 import androidx.test.ext.junit.runners.AndroidJUnit4
22 import androidx.test.filters.MediumTest
23 import com.android.systemui.SysuiTestCase
24 import com.android.systemui.coroutines.collectLastValue
25 import com.android.systemui.kosmos.testScope
26 import com.android.systemui.plugins.qs.QSTile
27 import com.android.systemui.qs.FakeQSFactory
28 import com.android.systemui.qs.FakeQSTile
29 import com.android.systemui.qs.pipeline.data.model.RestoreData
30 import com.android.systemui.qs.pipeline.data.repository.fakeRestoreRepository
31 import com.android.systemui.qs.pipeline.data.repository.fakeTileSpecRepository
32 import com.android.systemui.qs.pipeline.shared.TileSpec
33 import com.android.systemui.qs.qsTileFactory
34 import com.android.systemui.settings.fakeUserTracker
35 import com.android.systemui.settings.userTracker
36 import com.android.systemui.testKosmos
37 import com.google.common.truth.Truth.assertThat
38 import kotlinx.coroutines.test.TestScope
39 import kotlinx.coroutines.test.runCurrent
40 import kotlinx.coroutines.test.runTest
41 import org.junit.Before
42 import org.junit.Test
43 import org.junit.runner.RunWith
44 
45 /**
46  * This integration test is for testing the solution to b/314781280. In particular, there are two
47  * issues we want to verify after a restore of a device with a work profile and a work mode tile:
48  * * When the work profile is re-enabled in the target device, it is auto-added.
49  * * The tile is auto-added in the same position that it was in the restored device.
50  */
51 @MediumTest
52 @RunWith(AndroidJUnit4::class)
53 class WorkProfileAutoAddedAfterRestoreTest : SysuiTestCase() {
54 
<lambda>null55     private val kosmos by lazy {
56         testKosmos().apply { fakeUserTracker.set(listOf(USER_0_INFO), 0) }
57     }
58     // Getter here so it can change when there is a managed profile.
59     private val workTileAvailable: Boolean
60         get() = hasManagedProfile()
61 
62     private val currentUser: Int
63         get() = kosmos.userTracker.userId
64 
65     private val testScope: TestScope
66         get() = kosmos.testScope
67 
68     @Before
setUpnull69     fun setUp() {
70         kosmos.qsTileFactory = FakeQSFactory(::tileCreator)
71         kosmos.restoreReconciliationInteractor.start()
72         kosmos.autoAddInteractor.init(kosmos.currentTilesInteractor)
73     }
74 
75     @Test
workTileRestoredAndPreviouslyAutoAdded_notAvailable_willBeAutoaddedInCorrectPositionnull76     fun workTileRestoredAndPreviouslyAutoAdded_notAvailable_willBeAutoaddedInCorrectPosition() =
77         testScope.runTest {
78             val tiles by collectLastValue(kosmos.currentTilesInteractor.currentTiles)
79 
80             // Set up
81             val currentTiles = listOf("a".toTileSpec())
82             kosmos.fakeTileSpecRepository.setTiles(currentUser, currentTiles)
83 
84             val restoredTiles =
85                 listOf(WORK_TILE_SPEC) + listOf("b", "c", "d").map { it.toTileSpec() }
86             val restoredAutoAdded = setOf(WORK_TILE_SPEC)
87 
88             val restoreData = RestoreData(restoredTiles, restoredAutoAdded, currentUser)
89 
90             // WHEN we restore tiles that auto-added the WORK tile and it's not available (there
91             // are no managed profiles)
92             kosmos.fakeRestoreRepository.onDataRestored(restoreData)
93 
94             // THEN the work tile is not part of the current tiles
95             assertThat(tiles!!).hasSize(3)
96             assertThat(tiles!!.map { it.spec }).doesNotContain(WORK_TILE_SPEC)
97 
98             // WHEN we add a work profile
99             createManagedProfileAndAdd()
100 
101             // THEN the work profile is added in the correct place
102             assertThat(tiles!!.first().spec).isEqualTo(WORK_TILE_SPEC)
103         }
104 
105     @Test
workTileNotRestoredAndPreviouslyAutoAdded_wontBeAutoAddedWhenWorkProfileIsAddednull106     fun workTileNotRestoredAndPreviouslyAutoAdded_wontBeAutoAddedWhenWorkProfileIsAdded() =
107         testScope.runTest {
108             val tiles by collectLastValue(kosmos.currentTilesInteractor.currentTiles)
109 
110             // Set up
111             val currentTiles = listOf("a".toTileSpec())
112             kosmos.fakeTileSpecRepository.setTiles(currentUser, currentTiles)
113             runCurrent()
114 
115             val restoredTiles = listOf("b", "c", "d").map { it.toTileSpec() }
116             val restoredAutoAdded = setOf(WORK_TILE_SPEC)
117 
118             val restoreData = RestoreData(restoredTiles, restoredAutoAdded, currentUser)
119 
120             // WHEN we restore tiles that auto-added the WORK tile
121             kosmos.fakeRestoreRepository.onDataRestored(restoreData)
122 
123             // THEN the work tile is not part of the current tiles
124             assertThat(tiles!!).hasSize(3)
125             assertThat(tiles!!.map { it.spec }).doesNotContain(WORK_TILE_SPEC)
126 
127             // WHEN we add a work profile
128             createManagedProfileAndAdd()
129 
130             // THEN the work profile is not added because the user had manually removed it in the
131             // past
132             assertThat(tiles!!.map { it.spec }).doesNotContain(WORK_TILE_SPEC)
133         }
134 
tileCreatornull135     private fun tileCreator(spec: String): QSTile {
136         return if (spec == WORK_TILE_SPEC.spec) {
137             FakeQSTile(currentUser, workTileAvailable)
138         } else {
139             FakeQSTile(currentUser)
140         }
141     }
142 
hasManagedProfilenull143     private fun hasManagedProfile(): Boolean {
144         return kosmos.userTracker.userProfiles.any { it.isManagedProfile }
145     }
146 
TestScopenull147     private fun TestScope.createManagedProfileAndAdd() {
148         kosmos.fakeUserTracker.set(listOf(USER_0_INFO, MANAGED_USER_INFO), 0)
149         runCurrent()
150     }
151 
152     private companion object {
153         val WORK_TILE_SPEC = "work".toTileSpec()
154         val USER_0_INFO = UserInfo(0, "zero", "", UserInfo.FLAG_ADMIN or UserInfo.FLAG_FULL)
155         val MANAGED_USER_INFO =
156             UserInfo(10, "ten-managed", "", 0, UserManager.USER_TYPE_PROFILE_MANAGED)
157 
toTileSpecnull158         fun String.toTileSpec() = TileSpec.create(this)
159     }
160 }
161