Remove usage of qs_new_pipeline flag
This removes all the usages, as well as classes that are not needed
anymore in the new pipeline.
Bug: 357647489
Flag: EXEMPT flag cleanup
Test: atest com.android.systemui.qs
Test: atest PlatformScenarioTests
Test: atest CtsTileServiceTestCases
Change-Id: Ice6ab30836440e0bac0b12ce8e488120b3bc178d
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractorImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractorImplTest.kt
index 3146318..8995f46 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractorImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractorImplTest.kt
@@ -24,7 +24,6 @@
import android.service.quicksettings.Tile
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.systemui.Flags.FLAG_QS_NEW_PIPELINE
import com.android.systemui.Flags.FLAG_QS_NEW_TILES
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
@@ -107,7 +106,6 @@
fun setup() {
MockitoAnnotations.initMocks(this)
- mSetFlagsRule.enableFlags(FLAG_QS_NEW_PIPELINE)
mSetFlagsRule.enableFlags(FLAG_QS_NEW_TILES)
userRepository.setUserInfos(listOf(USER_INFO_0, USER_INFO_1))
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/NoLowNumberOfTilesTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/NoLowNumberOfTilesTest.kt
index e8ad038..00c7204 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/NoLowNumberOfTilesTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/NoLowNumberOfTilesTest.kt
@@ -20,7 +20,6 @@
import android.content.pm.UserInfo
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
-import com.android.systemui.Flags
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.kosmos.Kosmos
@@ -98,8 +97,6 @@
@Before
fun setUp() {
- mSetFlagsRule.enableFlags(Flags.FLAG_QS_NEW_PIPELINE)
-
with(kosmos) {
restoreReconciliationInteractor.start()
autoAddInteractor.init(kosmos.currentTilesInteractor)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/WorkProfileAutoAddedAfterRestoreTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/WorkProfileAutoAddedAfterRestoreTest.kt
index dffd0d7..6bcaea4 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/WorkProfileAutoAddedAfterRestoreTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/WorkProfileAutoAddedAfterRestoreTest.kt
@@ -20,7 +20,6 @@
import android.os.UserManager
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
-import com.android.systemui.Flags.FLAG_QS_NEW_PIPELINE
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.kosmos.Kosmos
@@ -59,6 +58,7 @@
// Getter here so it can change when there is a managed profile.
private val workTileAvailable: Boolean
get() = hasManagedProfile()
+
private val currentUser: Int
get() = kosmos.userTracker.userId
@@ -67,8 +67,6 @@
@Before
fun setUp() {
- mSetFlagsRule.enableFlags(FLAG_QS_NEW_PIPELINE)
-
kosmos.qsTileFactory = FakeQSFactory(::tileCreator)
kosmos.restoreReconciliationInteractor.start()
kosmos.autoAddInteractor.init(kosmos.currentTilesInteractor)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/AutoAddTracker.kt b/packages/SystemUI/src/com/android/systemui/qs/AutoAddTracker.kt
deleted file mode 100644
index e4bafcd..0000000
--- a/packages/SystemUI/src/com/android/systemui/qs/AutoAddTracker.kt
+++ /dev/null
@@ -1,298 +0,0 @@
-/*
- * Copyright (C) 2021 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 android.content.BroadcastReceiver
-import android.content.Context
-import android.content.Intent
-import android.content.IntentFilter
-import android.database.ContentObserver
-import android.net.Uri
-import android.os.Handler
-import android.os.UserHandle
-import android.provider.Settings
-import android.text.TextUtils
-import android.util.ArraySet
-import android.util.Log
-import androidx.annotation.GuardedBy
-import androidx.annotation.VisibleForTesting
-import com.android.systemui.Dumpable
-import com.android.systemui.broadcast.BroadcastDispatcher
-import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.dagger.qualifiers.Background
-import com.android.systemui.dagger.qualifiers.Main
-import com.android.systemui.dump.DumpManager
-import com.android.systemui.util.UserAwareController
-import com.android.systemui.util.settings.SecureSettings
-import java.io.PrintWriter
-import java.util.concurrent.Executor
-import javax.inject.Inject
-
-private const val TAG = "AutoAddTracker"
-private const val DELIMITER = ","
-
-/**
- * Class to track tiles that have been auto-added
- *
- * The list is backed by [Settings.Secure.QS_AUTO_ADDED_TILES].
- *
- * It also handles restore gracefully.
- */
-class AutoAddTracker
-@VisibleForTesting
-constructor(
- private val secureSettings: SecureSettings,
- private val broadcastDispatcher: BroadcastDispatcher,
- private val qsHost: QSHost,
- private val dumpManager: DumpManager,
- private val mainHandler: Handler?,
- private val backgroundExecutor: Executor,
- private var userId: Int
-) : UserAwareController, Dumpable {
-
- companion object {
- private val FILTER = IntentFilter(Intent.ACTION_SETTING_RESTORED)
- }
-
- @GuardedBy("autoAdded") private val autoAdded = ArraySet<String>()
- private var restoredTiles: Map<String, AutoTile>? = null
-
- override val currentUserId: Int
- get() = userId
-
- private val contentObserver =
- object : ContentObserver(mainHandler) {
- override fun onChange(
- selfChange: Boolean,
- uris: Collection<Uri>,
- flags: Int,
- _userId: Int
- ) {
- if (_userId != userId) {
- // Ignore changes outside of our user. We'll load the correct value on user
- // change
- return
- }
- loadTiles()
- }
- }
-
- private val restoreReceiver =
- object : BroadcastReceiver() {
- override fun onReceive(context: Context, intent: Intent) {
- if (intent.action != Intent.ACTION_SETTING_RESTORED) return
- processRestoreIntent(intent)
- }
- }
-
- private fun processRestoreIntent(intent: Intent) {
- when (intent.getStringExtra(Intent.EXTRA_SETTING_NAME)) {
- Settings.Secure.QS_TILES -> {
- restoredTiles =
- intent
- .getStringExtra(Intent.EXTRA_SETTING_NEW_VALUE)
- ?.split(DELIMITER)
- ?.mapIndexed(::AutoTile)
- ?.associateBy(AutoTile::tileType)
- ?: run {
- Log.w(TAG, "Null restored tiles for user $userId")
- emptyMap()
- }
- }
- Settings.Secure.QS_AUTO_ADDED_TILES -> {
- restoredTiles?.let { restoredTiles ->
- val restoredAutoAdded =
- intent.getStringExtra(Intent.EXTRA_SETTING_NEW_VALUE)?.split(DELIMITER)
- ?: emptyList()
- val autoAddedBeforeRestore =
- intent.getStringExtra(Intent.EXTRA_SETTING_PREVIOUS_VALUE)?.split(DELIMITER)
- ?: emptyList()
-
- val tilesToRemove = restoredAutoAdded.filter { it !in restoredTiles }
- if (tilesToRemove.isNotEmpty()) {
- Log.d(TAG, "Removing tiles: $tilesToRemove")
- qsHost.removeTiles(tilesToRemove)
- }
- val tiles =
- synchronized(autoAdded) {
- autoAdded.clear()
- autoAdded.addAll(restoredAutoAdded + autoAddedBeforeRestore)
- getTilesFromListLocked()
- }
- saveTiles(tiles)
- }
- ?: run {
- Log.w(
- TAG,
- "${Settings.Secure.QS_AUTO_ADDED_TILES} restored before " +
- "${Settings.Secure.QS_TILES} for user $userId"
- )
- }
- }
- else -> {} // Do nothing for other Settings
- }
- }
-
- /** Init method must be called after construction to start listening */
- fun initialize() {
- dumpManager.registerDumpable(TAG, this)
- loadTiles()
- secureSettings.registerContentObserverForUserSync(
- secureSettings.getUriFor(Settings.Secure.QS_AUTO_ADDED_TILES),
- contentObserver,
- UserHandle.USER_ALL
- )
- registerBroadcastReceiver()
- }
-
- /** Unregister listeners, receivers and observers */
- fun destroy() {
- dumpManager.unregisterDumpable(TAG)
- secureSettings.unregisterContentObserverSync(contentObserver)
- unregisterBroadcastReceiver()
- }
-
- private fun registerBroadcastReceiver() {
- broadcastDispatcher.registerReceiver(
- restoreReceiver,
- FILTER,
- backgroundExecutor,
- UserHandle.of(userId)
- )
- }
-
- private fun unregisterBroadcastReceiver() {
- broadcastDispatcher.unregisterReceiver(restoreReceiver)
- }
-
- override fun changeUser(newUser: UserHandle) {
- if (newUser.identifier == userId) return
- unregisterBroadcastReceiver()
- userId = newUser.identifier
- restoredTiles = null
- loadTiles()
- registerBroadcastReceiver()
- }
-
- fun getRestoredTilePosition(tile: String): Int =
- restoredTiles?.get(tile)?.index ?: QSHost.POSITION_AT_END
-
- /** Returns `true` if the tile has been auto-added before */
- fun isAdded(tile: String): Boolean {
- return synchronized(autoAdded) { tile in autoAdded }
- }
-
- /**
- * Sets a tile as auto-added.
- *
- * From here on, [isAdded] will return true for that tile.
- */
- fun setTileAdded(tile: String) {
- val tiles =
- synchronized(autoAdded) {
- if (autoAdded.add(tile)) {
- getTilesFromListLocked()
- } else {
- null
- }
- }
- tiles?.let { saveTiles(it) }
- }
-
- /**
- * Removes a tile from the list of auto-added.
- *
- * This allows for this tile to be auto-added again in the future.
- */
- fun setTileRemoved(tile: String) {
- val tiles =
- synchronized(autoAdded) {
- if (autoAdded.remove(tile)) {
- getTilesFromListLocked()
- } else {
- null
- }
- }
- tiles?.let { saveTiles(it) }
- }
-
- private fun getTilesFromListLocked(): String {
- return TextUtils.join(DELIMITER, autoAdded)
- }
-
- private fun saveTiles(tiles: String) {
- secureSettings.putStringForUser(
- Settings.Secure.QS_AUTO_ADDED_TILES,
- tiles,
- /* tag */ null,
- /* makeDefault */ false,
- userId,
- /* overrideableByRestore */ true
- )
- }
-
- private fun loadTiles() {
- synchronized(autoAdded) {
- autoAdded.clear()
- autoAdded.addAll(getAdded())
- }
- }
-
- private fun getAdded(): Collection<String> {
- val current = secureSettings.getStringForUser(Settings.Secure.QS_AUTO_ADDED_TILES, userId)
- return current?.split(DELIMITER) ?: emptySet()
- }
-
- override fun dump(pw: PrintWriter, args: Array<out String>) {
- pw.println("Current user: $userId")
- pw.println("Restored tiles: $restoredTiles")
- pw.println("Added tiles: $autoAdded")
- }
-
- @SysUISingleton
- class Builder
- @Inject
- constructor(
- private val secureSettings: SecureSettings,
- private val broadcastDispatcher: BroadcastDispatcher,
- private val qsHost: QSHost,
- private val dumpManager: DumpManager,
- @Main private val handler: Handler,
- @Background private val executor: Executor
- ) {
- private var userId: Int = 0
-
- fun setUserId(_userId: Int): Builder {
- userId = _userId
- return this
- }
-
- fun build(): AutoAddTracker {
- return AutoAddTracker(
- secureSettings,
- broadcastDispatcher,
- qsHost,
- dumpManager,
- handler,
- executor,
- userId
- )
- }
- }
-
- private data class AutoTile(val index: Int, val tileType: String)
-}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSHostAdapter.kt b/packages/SystemUI/src/com/android/systemui/qs/QSHostAdapter.kt
index c77233e..4323b31 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSHostAdapter.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSHostAdapter.kt
@@ -47,12 +47,10 @@
class QSHostAdapter
@Inject
constructor(
- private val qsTileHost: QSTileHost,
private val interactor: CurrentTilesInteractor,
private val context: Context,
private val tileServiceRequestControllerBuilder: TileServiceRequestController.Builder,
@Application private val scope: CoroutineScope,
- flags: QSPipelineFlagsRepository,
dumpManager: DumpManager,
) : QSHost {
@@ -60,123 +58,69 @@
private const val TAG = "QSTileHost"
}
- private val useNewHost = flags.pipelineEnabled
-
@GuardedBy("callbacksMap") private val callbacksMap = mutableMapOf<QSHost.Callback, Job>()
init {
scope.launch { tileServiceRequestControllerBuilder.create(this@QSHostAdapter).init() }
// Redirect dump to the correct host (needed for CTS tests)
- dumpManager.registerCriticalDumpable(TAG, if (useNewHost) interactor else qsTileHost)
+ dumpManager.registerCriticalDumpable(TAG, interactor)
}
override fun getTiles(): Collection<QSTile> {
- return if (useNewHost) {
- interactor.currentQSTiles
- } else {
- qsTileHost.getTiles()
- }
+ return interactor.currentQSTiles
}
override fun getSpecs(): List<String> {
- return if (useNewHost) {
- interactor.currentTilesSpecs.map { it.spec }
- } else {
- qsTileHost.getSpecs()
- }
+ return interactor.currentTilesSpecs.map { it.spec }
}
override fun removeTile(spec: String) {
- if (useNewHost) {
- interactor.removeTiles(listOf(TileSpec.create(spec)))
- } else {
- qsTileHost.removeTile(spec)
- }
+ interactor.removeTiles(listOf(TileSpec.create(spec)))
}
override fun addCallback(callback: QSHost.Callback) {
- if (useNewHost) {
- val job = scope.launch { interactor.currentTiles.collect { callback.onTilesChanged() } }
- synchronized(callbacksMap) { callbacksMap.put(callback, job) }
- } else {
- qsTileHost.addCallback(callback)
- }
+ val job = scope.launch { interactor.currentTiles.collect { callback.onTilesChanged() } }
+ synchronized(callbacksMap) { callbacksMap.put(callback, job) }
}
override fun removeCallback(callback: QSHost.Callback) {
- if (useNewHost) {
- synchronized(callbacksMap) { callbacksMap.remove(callback)?.cancel() }
- } else {
- qsTileHost.removeCallback(callback)
- }
+ synchronized(callbacksMap) { callbacksMap.remove(callback)?.cancel() }
}
override fun removeTiles(specs: Collection<String>) {
- if (useNewHost) {
- interactor.removeTiles(specs.map(TileSpec::create))
- } else {
- qsTileHost.removeTiles(specs)
- }
+ interactor.removeTiles(specs.map(TileSpec::create))
}
override fun removeTileByUser(component: ComponentName) {
- if (useNewHost) {
- interactor.removeTiles(listOf(TileSpec.create(component)))
- } else {
- qsTileHost.removeTileByUser(component)
- }
+ interactor.removeTiles(listOf(TileSpec.create(component)))
}
override fun addTile(spec: String, position: Int) {
- if (useNewHost) {
- interactor.addTile(TileSpec.create(spec), position)
- } else {
- qsTileHost.addTile(spec, position)
- }
+ interactor.addTile(TileSpec.create(spec), position)
}
override fun addTile(component: ComponentName, end: Boolean) {
- if (useNewHost) {
- interactor.addTile(TileSpec.create(component), if (end) POSITION_AT_END else 0)
- } else {
- qsTileHost.addTile(component, end)
- }
+ interactor.addTile(TileSpec.create(component), if (end) POSITION_AT_END else 0)
}
override fun changeTilesByUser(previousTiles: List<String>, newTiles: List<String>) {
- if (useNewHost) {
- interactor.setTiles(newTiles.map(TileSpec::create))
- } else {
- qsTileHost.changeTilesByUser(previousTiles, newTiles)
- }
+ interactor.setTiles(newTiles.map(TileSpec::create))
}
override fun getContext(): Context {
- return if (useNewHost) {
- context
- } else {
- qsTileHost.context
- }
+ return context
}
override fun getUserContext(): Context {
- return if (useNewHost) {
- interactor.userContext.value
- } else {
- qsTileHost.userContext
- }
+ return interactor.userContext.value
}
override fun getUserId(): Int {
- return if (useNewHost) {
- interactor.userId.value
- } else {
- qsTileHost.userId
- }
+ return interactor.userId.value
}
override fun createTile(tileSpec: String): QSTile? {
- return qsTileHost.createTile(tileSpec)
+ return interactor.createTileSync(TileSpec.create(tileSpec))
}
override fun addTile(spec: String) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java b/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
deleted file mode 100644
index 03c2aa6..0000000
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
+++ /dev/null
@@ -1,630 +0,0 @@
-/*
- * 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 android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.res.Resources;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.provider.Settings.Secure;
-import android.text.TextUtils;
-import android.util.ArraySet;
-import android.util.Log;
-
-import androidx.annotation.MainThread;
-import androidx.annotation.Nullable;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.systemui.Dumpable;
-import com.android.systemui.ProtoDumpable;
-import com.android.systemui.dagger.SysUISingleton;
-import com.android.systemui.dagger.qualifiers.Main;
-import com.android.systemui.dump.nano.SystemUIProtoDump;
-import com.android.systemui.plugins.PluginListener;
-import com.android.systemui.plugins.PluginManager;
-import com.android.systemui.plugins.qs.QSFactory;
-import com.android.systemui.plugins.qs.QSTile;
-import com.android.systemui.qs.external.CustomTile;
-import com.android.systemui.qs.external.CustomTileStatePersister;
-import com.android.systemui.qs.external.TileLifecycleManager;
-import com.android.systemui.qs.external.TileServiceKey;
-import com.android.systemui.qs.logging.QSLogger;
-import com.android.systemui.qs.nano.QsTileState;
-import com.android.systemui.qs.pipeline.data.repository.CustomTileAddedRepository;
-import com.android.systemui.qs.pipeline.domain.interactor.PanelInteractor;
-import com.android.systemui.qs.pipeline.shared.QSPipelineFlagsRepository;
-import com.android.systemui.qs.tiles.di.NewQSTileFactory;
-import com.android.systemui.res.R;
-import com.android.systemui.settings.UserFileManager;
-import com.android.systemui.settings.UserTracker;
-import com.android.systemui.shade.ShadeController;
-import com.android.systemui.statusbar.phone.AutoTileManager;
-import com.android.systemui.tuner.TunerService;
-import com.android.systemui.tuner.TunerService.Tunable;
-import com.android.systemui.util.settings.SecureSettings;
-
-import dagger.Lazy;
-
-import org.jetbrains.annotations.NotNull;
-
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Objects;
-import java.util.Set;
-import java.util.concurrent.Executor;
-import java.util.function.Predicate;
-import java.util.stream.Collectors;
-
-import javax.inject.Inject;
-import javax.inject.Provider;
-
-/** Platform implementation of the quick settings tile host
- *
- * This class keeps track of the set of current tiles and is the in memory source of truth
- * (ground truth is kept in {@link Secure#QS_TILES}). When the ground truth changes,
- * {@link #onTuningChanged} will be called and the tiles will be re-created as needed.
- *
- * This class also provides the interface for adding/removing/changing tiles.
- */
-@SysUISingleton
-public class QSTileHost implements QSHost, Tunable, PluginListener<QSFactory>, ProtoDumpable,
- PanelInteractor, CustomTileAddedRepository {
- private static final String TAG = "QSTileHost";
- private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
-
- // Shared prefs that hold tile lifecycle info.
- @VisibleForTesting
- static final String TILES = "tiles_prefs";
-
- private final Context mContext;
- private final LinkedHashMap<String, QSTile> mTiles = new LinkedHashMap<>();
- private final ArrayList<String> mTileSpecs = new ArrayList<>();
- private final TunerService mTunerService;
- private final PluginManager mPluginManager;
- private final QSLogger mQSLogger;
- private final CustomTileStatePersister mCustomTileStatePersister;
- private final Executor mMainExecutor;
- private final UserFileManager mUserFileManager;
-
- private final List<Callback> mCallbacks = new ArrayList<>();
- @Nullable
- private AutoTileManager mAutoTiles;
- private final ArrayList<QSFactory> mQsFactories = new ArrayList<>();
- private int mCurrentUser;
- private final Lazy<ShadeController> mShadeControllerProvider;
- private Context mUserContext;
- private UserTracker mUserTracker;
- private SecureSettings mSecureSettings;
- // Keep track of whether mTilesList contains the same information as the Settings value.
- // This is a performance optimization to reduce the number of blocking calls to Settings from
- // main thread.
- // This is enforced by only cleaning the flag at the end of a successful run of #onTuningChanged
- private boolean mTilesListDirty = true;
-
- private TileLifecycleManager.Factory mTileLifeCycleManagerFactory;
-
- private final QSPipelineFlagsRepository mFeatureFlags;
-
- @Inject
- public QSTileHost(Context context,
- Lazy<NewQSTileFactory> newQsTileFactoryProvider,
- QSFactory defaultFactory,
- @Main Executor mainExecutor,
- PluginManager pluginManager,
- TunerService tunerService,
- Provider<AutoTileManager> autoTiles,
- Lazy<ShadeController> shadeControllerProvider,
- QSLogger qsLogger,
- UserTracker userTracker,
- SecureSettings secureSettings,
- CustomTileStatePersister customTileStatePersister,
- TileLifecycleManager.Factory tileLifecycleManagerFactory,
- UserFileManager userFileManager,
- QSPipelineFlagsRepository featureFlags
- ) {
- mContext = context;
- mUserContext = context;
- mTunerService = tunerService;
- mPluginManager = pluginManager;
- mQSLogger = qsLogger;
- mMainExecutor = mainExecutor;
- mTileLifeCycleManagerFactory = tileLifecycleManagerFactory;
- mUserFileManager = userFileManager;
- mFeatureFlags = featureFlags;
-
- mShadeControllerProvider = shadeControllerProvider;
-
- if (featureFlags.getTilesEnabled()) {
- mQsFactories.add(newQsTileFactoryProvider.get());
- }
- mQsFactories.add(defaultFactory);
- pluginManager.addPluginListener(this, QSFactory.class, true);
- mUserTracker = userTracker;
- mCurrentUser = userTracker.getUserId();
- mSecureSettings = secureSettings;
- mCustomTileStatePersister = customTileStatePersister;
-
- mainExecutor.execute(() -> {
- // This is technically a hack to avoid circular dependency of
- // QSTileHost -> XXXTile -> QSTileHost. Posting ensures creation
- // finishes before creating any tiles.
- tunerService.addTunable(this, TILES_SETTING);
- // AutoTileManager can modify mTiles so make sure mTiles has already been initialized.
- if (!mFeatureFlags.getPipelineEnabled()) {
- mAutoTiles = autoTiles.get();
- }
- });
- }
-
- public void destroy() {
- mTiles.values().forEach(tile -> tile.destroy());
- mAutoTiles.destroy();
- mTunerService.removeTunable(this);
- mPluginManager.removePluginListener(this);
- }
-
- @Override
- public void onPluginConnected(QSFactory plugin, Context pluginContext) {
- // Give plugins priority over creation so they can override if they wish.
- mQsFactories.add(0, plugin);
- String value = mTunerService.getValue(TILES_SETTING);
- // Force remove and recreate of all tiles.
- onTuningChanged(TILES_SETTING, "");
- onTuningChanged(TILES_SETTING, value);
- }
-
- @Override
- public void onPluginDisconnected(QSFactory plugin) {
- mQsFactories.remove(plugin);
- // Force remove and recreate of all tiles.
- String value = mTunerService.getValue(TILES_SETTING);
- onTuningChanged(TILES_SETTING, "");
- onTuningChanged(TILES_SETTING, value);
- }
-
- @Override
- public void addCallback(Callback callback) {
- mCallbacks.add(callback);
- }
-
- @Override
- public void removeCallback(Callback callback) {
- mCallbacks.remove(callback);
- }
-
- @Override
- public Collection<QSTile> getTiles() {
- return mTiles.values();
- }
-
- @Override
- public void collapsePanels() {
- mShadeControllerProvider.get().postAnimateCollapseShade();
- }
-
- @Override
- public void forceCollapsePanels() {
- mShadeControllerProvider.get().postAnimateForceCollapseShade();
- }
-
- @Override
- public void openPanels() {
- mShadeControllerProvider.get().postAnimateExpandQs();
- }
-
- @Override
- public Context getContext() {
- return mContext;
- }
-
- @Override
- public Context getUserContext() {
- return mUserContext;
- }
-
- @Override
- public int getUserId() {
- return mCurrentUser;
- }
-
- public int indexOf(String spec) {
- return mTileSpecs.indexOf(spec);
- }
-
- /**
- * Whenever the Secure Setting keeping track of the current tiles changes (or upon start) this
- * will be called with the new value of the setting.
- *
- * This method will do the following:
- * <ol>
- * <li>Destroy any existing tile that's not one of the current tiles (in the setting)</li>
- * <li>Create new tiles for those that don't already exist. If this tiles end up being
- * not available, they'll also be destroyed.</li>
- * <li>Save the resolved list of tiles (current tiles that are available) into the setting.
- * This means that after this call ends, the tiles in the Setting, {@link #mTileSpecs},
- * and visible tiles ({@link #mTiles}) must match.
- * </li>
- * </ol>
- *
- * Additionally, if the user has changed, it'll do the following:
- * <ul>
- * <li>Change the user for SystemUI tiles: {@link QSTile#userSwitch}.</li>
- * <li>Destroy any {@link CustomTile} and recreate it for the new user.</li>
- * </ul>
- *
- * This happens in main thread as {@link com.android.systemui.tuner.TunerServiceImpl} dispatches
- * in main thread.
- *
- * @see QSTile#isAvailable
- */
- @MainThread
- @Override
- public void onTuningChanged(String key, String newValue) {
- if (!TILES_SETTING.equals(key)) {
- return;
- }
- int currentUser = mUserTracker.getUserId();
- if (currentUser != mCurrentUser) {
- mUserContext = mUserTracker.getUserContext();
- if (mAutoTiles != null) {
- mAutoTiles.changeUser(UserHandle.of(currentUser));
- }
- }
- // Do not process tiles if the flag is enabled.
- if (mFeatureFlags.getPipelineEnabled()) {
- return;
- }
- QSPipelineFlagsRepository.Utils.assertInLegacyMode();
- if (newValue == null && UserManager.isDeviceInDemoMode(mContext)) {
- newValue = mContext.getResources().getString(R.string.quick_settings_tiles_retail_mode);
- }
- final List<String> tileSpecs = loadTileSpecs(mContext, newValue);
- if (tileSpecs.equals(mTileSpecs) && currentUser == mCurrentUser) return;
- Log.d(TAG, "Recreating tiles: " + tileSpecs);
- mTiles.entrySet().stream().filter(tile -> !tileSpecs.contains(tile.getKey())).forEach(
- tile -> {
- Log.d(TAG, "Destroying tile: " + tile.getKey());
- mQSLogger.logTileDestroyed(tile.getKey(), "Tile removed");
- tile.getValue().destroy();
- });
- final LinkedHashMap<String, QSTile> newTiles = new LinkedHashMap<>();
- for (String tileSpec : tileSpecs) {
- QSTile tile = mTiles.get(tileSpec);
- if (tile != null && (!(tile instanceof CustomTile)
- || ((CustomTile) tile).getUser() == currentUser)) {
- if (tile.isAvailable()) {
- Log.d(TAG, "Adding " + tile);
- tile.removeCallbacks();
- if (!(tile instanceof CustomTile) && mCurrentUser != currentUser) {
- tile.userSwitch(currentUser);
- }
- newTiles.put(tileSpec, tile);
- mQSLogger.logTileAdded(tileSpec);
- } else {
- tile.destroy();
- Log.d(TAG, "Destroying not available tile: " + tileSpec);
- mQSLogger.logTileDestroyed(tileSpec, "Tile not available");
- }
- } else {
- // This means that the tile is a CustomTile AND the user is different, so let's
- // destroy it
- if (tile != null) {
- tile.destroy();
- Log.d(TAG, "Destroying tile for wrong user: " + tileSpec);
- mQSLogger.logTileDestroyed(tileSpec, "Tile for wrong user");
- }
- Log.d(TAG, "Creating tile: " + tileSpec);
- try {
- tile = createTile(tileSpec);
- if (tile != null) {
- if (tile.isAvailable()) {
- newTiles.put(tileSpec, tile);
- mQSLogger.logTileAdded(tileSpec);
- } else {
- tile.destroy();
- Log.d(TAG, "Destroying not available tile: " + tileSpec);
- mQSLogger.logTileDestroyed(tileSpec, "Tile not available");
- }
- } else {
- Log.d(TAG, "No factory for a spec: " + tileSpec);
- }
- } catch (Throwable t) {
- Log.w(TAG, "Error creating tile for spec: " + tileSpec, t);
- }
- }
- }
- mCurrentUser = currentUser;
- List<String> currentSpecs = new ArrayList<>(mTileSpecs);
- mTileSpecs.clear();
- mTileSpecs.addAll(newTiles.keySet()); // Only add the valid (available) tiles.
- mTiles.clear();
- mTiles.putAll(newTiles);
- if (newTiles.isEmpty() && !tileSpecs.isEmpty()) {
- // If we didn't manage to create any tiles, set it to empty (default)
- Log.d(TAG, "No valid tiles on tuning changed. Setting to default.");
- changeTilesByUser(currentSpecs, loadTileSpecs(mContext, ""));
- } else {
- String resolvedTiles = TextUtils.join(",", mTileSpecs);
- if (!resolvedTiles.equals(newValue)) {
- // If the resolved tiles (those we actually ended up with) are different than
- // the ones that are in the setting, update the Setting.
- saveTilesToSettings(mTileSpecs);
- }
- mTilesListDirty = false;
- for (int i = 0; i < mCallbacks.size(); i++) {
- mCallbacks.get(i).onTilesChanged();
- }
- }
- }
-
- /**
- * Only use with [CustomTile] if the tile doesn't exist anymore (and therefore doesn't need
- * its lifecycle terminated).
- */
- @Override
- public void removeTile(String spec) {
- if (spec.startsWith(CustomTile.PREFIX)) {
- // If the tile is removed (due to it not actually existing), mark it as removed. That
- // way it will be marked as newly added if it appears in the future.
- setTileAdded(CustomTile.getComponentFromSpec(spec), mCurrentUser, false);
- }
- mMainExecutor.execute(() -> changeTileSpecs(tileSpecs-> tileSpecs.remove(spec)));
- }
-
- /**
- * Remove many tiles at once.
- *
- * It will only save to settings once (as opposed to {@link QSTileHost#removeTileByUser} called
- * multiple times).
- */
- @Override
- public void removeTiles(Collection<String> specs) {
- mMainExecutor.execute(() -> changeTileSpecs(tileSpecs -> tileSpecs.removeAll(specs)));
- }
-
- /**
- * Add a tile to the end
- *
- * @param spec string matching a pre-defined tilespec
- */
- public void addTile(String spec) {
- addTile(spec, POSITION_AT_END);
- }
-
- @Override
- public void addTile(String spec, int requestPosition) {
- mMainExecutor.execute(() ->
- changeTileSpecs(tileSpecs -> {
- if (tileSpecs.contains(spec)) return false;
-
- int size = tileSpecs.size();
- if (requestPosition == POSITION_AT_END || requestPosition >= size) {
- tileSpecs.add(spec);
- } else {
- tileSpecs.add(requestPosition, spec);
- }
- return true;
- })
- );
- }
-
- // When calling this, you may want to modify mTilesListDirty accordingly.
- @MainThread
- private void saveTilesToSettings(List<String> tileSpecs) {
- Log.d(TAG, "Saving tiles: " + tileSpecs + " for user: " + mCurrentUser);
- mSecureSettings.putStringForUser(TILES_SETTING, TextUtils.join(",", tileSpecs),
- null /* tag */, false /* default */, mCurrentUser,
- true /* overrideable by restore */);
- }
-
- @MainThread
- private void changeTileSpecs(Predicate<List<String>> changeFunction) {
- final List<String> tileSpecs;
- if (!mTilesListDirty) {
- tileSpecs = new ArrayList<>(mTileSpecs);
- } else {
- tileSpecs = loadTileSpecs(mContext,
- mSecureSettings.getStringForUser(TILES_SETTING, mCurrentUser));
- }
- if (changeFunction.test(tileSpecs)) {
- mTilesListDirty = true;
- saveTilesToSettings(tileSpecs);
- }
- }
-
- @Override
- public void addTile(ComponentName tile) {
- addTile(tile, /* end */ false);
- }
-
- @Override
- public void addTile(ComponentName tile, boolean end) {
- String spec = CustomTile.toSpec(tile);
- addTile(spec, end ? POSITION_AT_END : 0);
- }
-
- /**
- * This will call through {@link #changeTilesByUser}. It should only be used when a tile is
- * removed by a <b>user action</b> like {@code adb}.
- */
- @Override
- public void removeTileByUser(ComponentName tile) {
- mMainExecutor.execute(() -> {
- List<String> newSpecs = new ArrayList<>(mTileSpecs);
- if (newSpecs.remove(CustomTile.toSpec(tile))) {
- changeTilesByUser(mTileSpecs, newSpecs);
- }
- });
- }
-
- /**
- * Change the tiles triggered by the user editing.
- * <p>
- * This is not called on device start, or on user change.
- *
- * {@link android.service.quicksettings.TileService#onTileRemoved} will be called for tiles
- * that are removed.
- */
- @MainThread
- @Override
- public void changeTilesByUser(List<String> previousTiles, List<String> newTiles) {
- final List<String> copy = new ArrayList<>(previousTiles);
- final int NP = copy.size();
- for (int i = 0; i < NP; i++) {
- String tileSpec = copy.get(i);
- if (!tileSpec.startsWith(CustomTile.PREFIX)) continue;
- if (!newTiles.contains(tileSpec)) {
- ComponentName component = CustomTile.getComponentFromSpec(tileSpec);
- Intent intent = new Intent().setComponent(component);
- TileLifecycleManager lifecycleManager = mTileLifeCycleManagerFactory.create(
- intent, new UserHandle(mCurrentUser));
- lifecycleManager.onStopListening();
- lifecycleManager.onTileRemoved();
- mCustomTileStatePersister.removeState(new TileServiceKey(component, mCurrentUser));
- setTileAdded(component, mCurrentUser, false);
- lifecycleManager.flushMessagesAndUnbind();
- }
- }
- Log.d(TAG, "saveCurrentTiles " + newTiles);
- mTilesListDirty = true;
- saveTilesToSettings(newTiles);
- }
-
- @Nullable
- @Override
- public QSTile createTile(String tileSpec) {
- for (int i = 0; i < mQsFactories.size(); i++) {
- QSTile t = mQsFactories.get(i).createTile(tileSpec);
- if (t != null) {
- return t;
- }
- }
- return null;
- }
-
- /**
- * Check if a particular {@link CustomTile} has been added for a user and has not been removed
- * since.
- * @param componentName the {@link ComponentName} of the
- * {@link android.service.quicksettings.TileService} associated with the
- * tile.
- * @param userId the user to check
- */
- @Override
- public boolean isTileAdded(ComponentName componentName, int userId) {
- return mUserFileManager
- .getSharedPreferences(TILES, 0, userId)
- .getBoolean(componentName.flattenToString(), false);
- }
-
- /**
- * Persists whether a particular {@link CustomTile} has been added and it's currently in the
- * set of selected tiles ({@link #mTiles}.
- * @param componentName the {@link ComponentName} of the
- * {@link android.service.quicksettings.TileService} associated
- * with the tile.
- * @param userId the user for this tile
- * @param added {@code true} if the tile is being added, {@code false} otherwise
- */
- @Override
- public void setTileAdded(ComponentName componentName, int userId, boolean added) {
- mUserFileManager.getSharedPreferences(TILES, 0, userId)
- .edit()
- .putBoolean(componentName.flattenToString(), added)
- .apply();
- }
-
- @Override
- public List<String> getSpecs() {
- return mTileSpecs;
- }
-
- protected static List<String> loadTileSpecs(Context context, String tileList) {
- final Resources res = context.getResources();
-
- if (TextUtils.isEmpty(tileList)) {
- tileList = res.getString(R.string.quick_settings_tiles);
- Log.d(TAG, "Loaded tile specs from default config: " + tileList);
- } else {
- Log.d(TAG, "Loaded tile specs from setting: " + tileList);
- }
- final ArrayList<String> tiles = new ArrayList<String>();
- boolean addedDefault = false;
- Set<String> addedSpecs = new ArraySet<>();
- for (String tile : tileList.split(",")) {
- tile = tile.trim();
- if (tile.isEmpty()) continue;
- if (tile.equals("default")) {
- if (!addedDefault) {
- List<String> defaultSpecs = QSHost.getDefaultSpecs(context.getResources());
- for (String spec : defaultSpecs) {
- if (!addedSpecs.contains(spec)) {
- tiles.add(spec);
- addedSpecs.add(spec);
- }
- }
- addedDefault = true;
- }
- } else {
- if (!addedSpecs.contains(tile)) {
- tiles.add(tile);
- addedSpecs.add(tile);
- }
- }
- }
-
- if (!tiles.contains("internet")) {
- if (tiles.contains("wifi")) {
- // Replace the WiFi with Internet, and remove the Cell
- tiles.set(tiles.indexOf("wifi"), "internet");
- tiles.remove("cell");
- } else if (tiles.contains("cell")) {
- // Replace the Cell with Internet
- tiles.set(tiles.indexOf("cell"), "internet");
- }
- } else {
- tiles.remove("wifi");
- tiles.remove("cell");
- }
- return tiles;
- }
-
- @Override
- public void dump(PrintWriter pw, String[] args) {
- pw.println("QSTileHost:");
- pw.println("tile specs: " + mTileSpecs);
- pw.println("current user: " + mCurrentUser);
- pw.println("is dirty: " + mTilesListDirty);
- pw.println("tiles:");
- mTiles.values().stream().filter(obj -> obj instanceof Dumpable)
- .forEach(o -> ((Dumpable) o).dump(pw, args));
- }
-
- @Override
- public void dumpProto(@NotNull SystemUIProtoDump systemUIProtoDump, @NotNull String[] args) {
- List<QsTileState> data = mTiles.values().stream()
- .map(QSTile::getState)
- .map(TileStateToProtoKt::toProto)
- .filter(Objects::nonNull)
- .collect(Collectors.toList());
-
- systemUIProtoDump.tiles = data.toArray(new QsTileState[0]);
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSHostModule.kt b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSHostModule.kt
index 496a6f8..a947d36 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSHostModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSHostModule.kt
@@ -18,17 +18,14 @@
import com.android.systemui.qs.QSHost
import com.android.systemui.qs.QSHostAdapter
-import com.android.systemui.qs.QSTileHost
import com.android.systemui.qs.QsEventLogger
import com.android.systemui.qs.QsEventLoggerImpl
import com.android.systemui.qs.pipeline.data.repository.CustomTileAddedRepository
import com.android.systemui.qs.pipeline.data.repository.CustomTileAddedSharedPrefsRepository
import com.android.systemui.qs.pipeline.domain.interactor.PanelInteractor
import com.android.systemui.qs.pipeline.domain.interactor.PanelInteractorImpl
-import com.android.systemui.qs.pipeline.shared.QSPipelineFlagsRepository
import dagger.Binds
import dagger.Module
-import dagger.Provides
@Module
interface QSHostModule {
@@ -37,36 +34,10 @@
@Binds fun provideEventLogger(impl: QsEventLoggerImpl): QsEventLogger
- @Module
- companion object {
- private const val MAX_QS_INSTANCE_ID = 1 shl 20
+ @Binds fun providePanelInteractor(impl: PanelInteractorImpl): PanelInteractor
- @Provides
- @JvmStatic
- fun providePanelInteractor(
- featureFlags: QSPipelineFlagsRepository,
- qsHost: QSTileHost,
- panelInteractorImpl: PanelInteractorImpl
- ): PanelInteractor {
- return if (featureFlags.pipelineEnabled) {
- panelInteractorImpl
- } else {
- qsHost
- }
- }
-
- @Provides
- @JvmStatic
- fun provideCustomTileAddedRepository(
- featureFlags: QSPipelineFlagsRepository,
- qsHost: QSTileHost,
- customTileAddedRepository: CustomTileAddedSharedPrefsRepository
- ): CustomTileAddedRepository {
- return if (featureFlags.pipelineEnabled) {
- customTileAddedRepository
- } else {
- qsHost
- }
- }
- }
+ @Binds
+ fun provideCustomTileAddedRepository(
+ impl: CustomTileAddedSharedPrefsRepository
+ ): CustomTileAddedRepository
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModule.java b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModule.java
index b705a03..29bcad4 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModule.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModule.java
@@ -16,17 +16,7 @@
package com.android.systemui.qs.dagger;
-import static com.android.systemui.qs.dagger.QSFlagsModule.RBC_AVAILABLE;
-
-import android.content.Context;
-import android.os.Handler;
-
-import com.android.systemui.dagger.NightDisplayListenerModule;
-import com.android.systemui.dagger.SysUISingleton;
-import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.media.dagger.MediaModule;
-import com.android.systemui.qs.AutoAddTracker;
-import com.android.systemui.qs.QSHost;
import com.android.systemui.qs.ReduceBrightColorsController;
import com.android.systemui.qs.ReduceBrightColorsControllerImpl;
import com.android.systemui.qs.external.QSExternalModule;
@@ -36,24 +26,12 @@
import com.android.systemui.qs.tiles.di.QSTilesModule;
import com.android.systemui.qs.ui.adapter.QSSceneAdapter;
import com.android.systemui.qs.ui.adapter.QSSceneAdapterImpl;
-import com.android.systemui.statusbar.phone.AutoTileManager;
-import com.android.systemui.statusbar.phone.ManagedProfileController;
-import com.android.systemui.statusbar.policy.CastController;
-import com.android.systemui.statusbar.policy.DataSaverController;
-import com.android.systemui.statusbar.policy.DeviceControlsController;
-import com.android.systemui.statusbar.policy.HotspotController;
-import com.android.systemui.statusbar.policy.SafetyController;
-import com.android.systemui.statusbar.policy.WalletController;
-import com.android.systemui.util.settings.SecureSettings;
-
-import dagger.Binds;
-import dagger.Module;
-import dagger.Provides;
-import dagger.multibindings.Multibinds;
import java.util.Map;
-import javax.inject.Named;
+import dagger.Binds;
+import dagger.Module;
+import dagger.multibindings.Multibinds;
/**
* Module for QS dependencies
@@ -78,45 +56,6 @@
@Multibinds
Map<String, QSTileImpl<?>> tileMap();
- @Provides
- @SysUISingleton
- static AutoTileManager provideAutoTileManager(
- Context context,
- AutoAddTracker.Builder autoAddTrackerBuilder,
- QSHost host,
- @Background Handler handler,
- SecureSettings secureSettings,
- HotspotController hotspotController,
- DataSaverController dataSaverController,
- ManagedProfileController managedProfileController,
- NightDisplayListenerModule.Builder nightDisplayListenerBuilder,
- CastController castController,
- ReduceBrightColorsController reduceBrightColorsController,
- DeviceControlsController deviceControlsController,
- WalletController walletController,
- SafetyController safetyController,
- @Named(RBC_AVAILABLE) boolean isReduceBrightColorsAvailable) {
- AutoTileManager manager = new AutoTileManager(
- context,
- autoAddTrackerBuilder,
- host,
- handler,
- secureSettings,
- hotspotController,
- dataSaverController,
- managedProfileController,
- nightDisplayListenerBuilder,
- castController,
- reduceBrightColorsController,
- deviceControlsController,
- walletController,
- safetyController,
- isReduceBrightColorsAvailable
- );
- manager.init();
- return manager;
- }
-
@Binds
QSSceneAdapter bindsQsSceneInteractor(QSSceneAdapterImpl impl);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractor.kt
index 02379e6..4a96710 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractor.kt
@@ -116,6 +116,8 @@
*/
fun setTiles(specs: List<TileSpec>)
+ fun createTileSync(spec: TileSpec): QSTile?
+
companion object {
val POSITION_AT_END: Int = TileSpecRepository.POSITION_AT_END
}
@@ -190,9 +192,7 @@
}
init {
- if (featureFlags.pipelineEnabled) {
- startTileCollection()
- }
+ startTileCollection()
}
private fun startTileCollection() {
@@ -342,15 +342,16 @@
lifecycleManager.flushMessagesAndUnbind()
}
+ override fun createTileSync(spec: TileSpec): QSTile? {
+ return if (featureFlags.tilesEnabled) {
+ newQSTileFactory.get().createTile(spec.spec)
+ } else {
+ null
+ } ?: tileFactory.createTile(spec.spec)
+ }
+
private suspend fun createTile(spec: TileSpec): QSTile? {
- val tile =
- withContext(mainDispatcher) {
- if (featureFlags.tilesEnabled) {
- newQSTileFactory.get().createTile(spec.spec)
- } else {
- null
- } ?: tileFactory.createTile(spec.spec)
- }
+ val tile = withContext(mainDispatcher) { createTileSync(spec) }
if (tile == null) {
logger.logTileNotFoundInFactory(spec)
return null
diff --git a/packages/SystemUI/src/com/android/systemui/qs/pipeline/domain/startable/QSPipelineCoreStartable.kt b/packages/SystemUI/src/com/android/systemui/qs/pipeline/domain/startable/QSPipelineCoreStartable.kt
index c8fbeb5..0bcb6b7 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/pipeline/domain/startable/QSPipelineCoreStartable.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/pipeline/domain/startable/QSPipelineCoreStartable.kt
@@ -40,14 +40,12 @@
) : CoreStartable {
override fun start() {
- if (featureFlags.pipelineEnabled) {
- accessibilityTilesInteractor.init(currentTilesInteractor)
- autoAddInteractor.init(currentTilesInteractor)
- restoreReconciliationInteractor.start()
+ accessibilityTilesInteractor.init(currentTilesInteractor)
+ autoAddInteractor.init(currentTilesInteractor)
+ restoreReconciliationInteractor.start()
- if (NewQsUI.isEnabled) {
- gridConsistencyInteractor.start()
- }
+ if (NewQsUI.isEnabled) {
+ gridConsistencyInteractor.start()
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/pipeline/shared/QSPipelineFlagsRepository.kt b/packages/SystemUI/src/com/android/systemui/qs/pipeline/shared/QSPipelineFlagsRepository.kt
index 42bee3c..5dc8d1b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/pipeline/shared/QSPipelineFlagsRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/pipeline/shared/QSPipelineFlagsRepository.kt
@@ -9,19 +9,10 @@
@SysUISingleton
class QSPipelineFlagsRepository @Inject constructor() {
- val pipelineEnabled: Boolean
- get() = AconfigFlags.qsNewPipeline()
-
val tilesEnabled: Boolean
get() = AconfigFlags.qsNewTiles()
companion object Utils {
- fun assertInLegacyMode() =
- RefactorFlagUtils.assertInLegacyMode(
- AconfigFlags.qsNewPipeline(),
- AconfigFlags.FLAG_QS_NEW_PIPELINE
- )
-
fun assertNewTiles() =
RefactorFlagUtils.assertInNewMode(
AconfigFlags.qsNewTiles(),
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java
deleted file mode 100644
index a538856..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java
+++ /dev/null
@@ -1,520 +0,0 @@
-/*
- * Copyright (C) 2016 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.statusbar.phone;
-
-import static com.android.systemui.qs.dagger.QSFlagsModule.RBC_AVAILABLE;
-
-import android.annotation.Nullable;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.res.Resources;
-import android.database.ContentObserver;
-import android.hardware.display.ColorDisplayManager;
-import android.hardware.display.NightDisplayListener;
-import android.os.Handler;
-import android.os.UserHandle;
-import android.util.Log;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.systemui.dagger.NightDisplayListenerModule;
-import com.android.systemui.dagger.qualifiers.Background;
-import com.android.systemui.plugins.qs.QSTile;
-import com.android.systemui.qs.AutoAddTracker;
-import com.android.systemui.qs.QSHost;
-import com.android.systemui.qs.ReduceBrightColorsController;
-import com.android.systemui.qs.UserSettingObserver;
-import com.android.systemui.qs.external.CustomTile;
-import com.android.systemui.qs.pipeline.shared.QSPipelineFlagsRepository;
-import com.android.systemui.res.R;
-import com.android.systemui.statusbar.policy.CastController;
-import com.android.systemui.statusbar.policy.CastDevice;
-import com.android.systemui.statusbar.policy.DataSaverController;
-import com.android.systemui.statusbar.policy.DataSaverController.Listener;
-import com.android.systemui.statusbar.policy.DeviceControlsController;
-import com.android.systemui.statusbar.policy.HotspotController;
-import com.android.systemui.statusbar.policy.HotspotController.Callback;
-import com.android.systemui.statusbar.policy.SafetyController;
-import com.android.systemui.statusbar.policy.WalletController;
-import com.android.systemui.util.UserAwareController;
-import com.android.systemui.util.settings.SecureSettings;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Objects;
-
-import javax.inject.Named;
-
-/**
- * Manages which tiles should be automatically added to QS.
- */
-public class AutoTileManager implements UserAwareController {
- private static final String TAG = "AutoTileManager";
-
- public static final String HOTSPOT = "hotspot";
- public static final String SAVER = "saver";
- public static final String INVERSION = "inversion";
- public static final String WORK = "work";
- public static final String NIGHT = "night";
- public static final String CAST = "cast";
- public static final String DEVICE_CONTROLS = "controls";
- public static final String WALLET = "wallet";
- public static final String BRIGHTNESS = "reduce_brightness";
- static final String SETTING_SEPARATOR = ":";
-
- private UserHandle mCurrentUser;
- private boolean mInitialized;
- private final String mSafetySpec;
-
- protected final Context mContext;
- protected final QSHost mHost;
- protected final Handler mHandler;
- protected final SecureSettings mSecureSettings;
- protected final AutoAddTracker mAutoTracker;
- private final HotspotController mHotspotController;
- private final DataSaverController mDataSaverController;
- private final ManagedProfileController mManagedProfileController;
- private final NightDisplayListenerModule.Builder mNightDisplayListenerBuilder;
- private NightDisplayListener mNightDisplayListener;
- private final CastController mCastController;
- private final DeviceControlsController mDeviceControlsController;
- private final WalletController mWalletController;
- private final ReduceBrightColorsController mReduceBrightColorsController;
- private final SafetyController mSafetyController;
- private final boolean mIsReduceBrightColorsAvailable;
- private final ArrayList<AutoAddSetting> mAutoAddSettingList = new ArrayList<>();
-
- public AutoTileManager(Context context, AutoAddTracker.Builder autoAddTrackerBuilder,
- QSHost host,
- @Background Handler handler,
- SecureSettings secureSettings,
- HotspotController hotspotController,
- DataSaverController dataSaverController,
- ManagedProfileController managedProfileController,
- NightDisplayListenerModule.Builder nightDisplayListenerBuilder,
- CastController castController,
- ReduceBrightColorsController reduceBrightColorsController,
- DeviceControlsController deviceControlsController,
- WalletController walletController,
- SafetyController safetyController,
- @Named(RBC_AVAILABLE) boolean isReduceBrightColorsAvailable) {
- mContext = context;
- mHost = host;
- mSecureSettings = secureSettings;
- mCurrentUser = mHost.getUserContext().getUser();
- mAutoTracker = autoAddTrackerBuilder.setUserId(mCurrentUser.getIdentifier()).build();
- mHandler = handler;
- mHotspotController = hotspotController;
- mDataSaverController = dataSaverController;
- mManagedProfileController = managedProfileController;
- mNightDisplayListenerBuilder = nightDisplayListenerBuilder;
- mCastController = castController;
- mReduceBrightColorsController = reduceBrightColorsController;
- mIsReduceBrightColorsAvailable = isReduceBrightColorsAvailable;
- mDeviceControlsController = deviceControlsController;
- mWalletController = walletController;
- mSafetyController = safetyController;
- String safetySpecClass;
- try {
- safetySpecClass =
- context.getResources().getString(R.string.safety_quick_settings_tile_class);
- if (safetySpecClass.length() == 0) {
- safetySpecClass = null;
- }
- } catch (Resources.NotFoundException | NullPointerException e) {
- safetySpecClass = null;
- }
- mSafetySpec = safetySpecClass != null ? CustomTile.toSpec(new ComponentName(mContext
- .getPackageManager().getPermissionControllerPackageName(), safetySpecClass)) : null;
- }
-
- /**
- * Init method must be called after construction to start listening
- */
- public void init() {
- QSPipelineFlagsRepository.Utils.assertInLegacyMode();
- if (mInitialized) {
- Log.w(TAG, "Trying to re-initialize");
- return;
- }
- mAutoTracker.initialize();
- populateSettingsList();
- startControllersAndSettingsListeners();
- mInitialized = true;
- }
-
- protected void startControllersAndSettingsListeners() {
- if (!mAutoTracker.isAdded(HOTSPOT)) {
- mHotspotController.addCallback(mHotspotCallback);
- }
- if (!mAutoTracker.isAdded(SAVER)) {
- mDataSaverController.addCallback(mDataSaverListener);
- }
- mManagedProfileController.addCallback(mProfileCallback);
-
- mNightDisplayListener = mNightDisplayListenerBuilder
- .setUser(mCurrentUser.getIdentifier())
- .build();
- if (!mAutoTracker.isAdded(NIGHT)
- && ColorDisplayManager.isNightDisplayAvailable(mContext)) {
- mNightDisplayListener.setCallback(mNightDisplayCallback);
- }
- if (!mAutoTracker.isAdded(CAST)) {
- mCastController.addCallback(mCastCallback);
- }
- if (!mAutoTracker.isAdded(BRIGHTNESS) && mIsReduceBrightColorsAvailable) {
- mReduceBrightColorsController.addCallback(mReduceBrightColorsCallback);
- }
- // We always want this callback, because if the feature stops being supported,
- // we want to remove the tile from AutoAddTracker. That way it will be re-added when the
- // feature is reenabled (similar to work tile).
- mDeviceControlsController.setCallback(mDeviceControlsCallback);
- if (!mAutoTracker.isAdded(WALLET)) {
- initWalletController();
- }
- if (mSafetySpec != null) {
- if (!mAutoTracker.isAdded(mSafetySpec)) {
- initSafetyTile();
- }
- mSafetyController.addCallback(mSafetyCallback);
- }
-
- int settingsN = mAutoAddSettingList.size();
- for (int i = 0; i < settingsN; i++) {
- if (!mAutoTracker.isAdded(mAutoAddSettingList.get(i).mSpec)) {
- mAutoAddSettingList.get(i).setListening(true);
- }
- }
- }
-
- protected void stopListening() {
- mHotspotController.removeCallback(mHotspotCallback);
- mDataSaverController.removeCallback(mDataSaverListener);
- mManagedProfileController.removeCallback(mProfileCallback);
- if (ColorDisplayManager.isNightDisplayAvailable(mContext)
- && mNightDisplayListener != null) {
- mNightDisplayListener.setCallback(null);
- }
- if (mIsReduceBrightColorsAvailable) {
- mReduceBrightColorsController.removeCallback(mReduceBrightColorsCallback);
- }
- mCastController.removeCallback(mCastCallback);
- mDeviceControlsController.removeCallback();
- if (mSafetySpec != null) {
- mSafetyController.removeCallback(mSafetyCallback);
- }
- int settingsN = mAutoAddSettingList.size();
- for (int i = 0; i < settingsN; i++) {
- mAutoAddSettingList.get(i).setListening(false);
- }
- }
-
- public void destroy() {
- stopListening();
- mAutoTracker.destroy();
- }
-
- /**
- * Populates a list with the pairs setting:spec in the config resource.
- * <p>
- * This will only create {@link AutoAddSetting} objects for those tiles that have not been
- * auto-added before, and set the corresponding {@link ContentObserver} to listening.
- */
- private void populateSettingsList() {
- String [] autoAddList;
- try {
- autoAddList = mContext.getResources().getStringArray(
- R.array.config_quickSettingsAutoAdd);
- } catch (Resources.NotFoundException e) {
- Log.w(TAG, "Missing config resource");
- return;
- }
- // getStringArray returns @NotNull, so if we got here, autoAddList is not null
- for (String tile : autoAddList) {
- String[] split = tile.split(SETTING_SEPARATOR);
- if (split.length == 2) {
- String setting = split[0];
- String spec = split[1];
- // Populate all the settings. As they may not have been added in other users
- AutoAddSetting s = new AutoAddSetting(
- mSecureSettings, mHandler, setting, mCurrentUser.getIdentifier(), spec);
- mAutoAddSettingList.add(s);
- } else {
- Log.w(TAG, "Malformed item in array: " + tile);
- }
- }
- }
-
- /*
- * This will be sent off the main thread if needed
- */
- @Override
- public void changeUser(UserHandle newUser) {
- if (!mInitialized) {
- throw new IllegalStateException("AutoTileManager not initialized");
- }
- if (!Thread.currentThread().equals(mHandler.getLooper().getThread())) {
- mHandler.post(() -> changeUser(newUser));
- return;
- }
- if (newUser.getIdentifier() == mCurrentUser.getIdentifier()) {
- return;
- }
- stopListening();
- mCurrentUser = newUser;
- int settingsN = mAutoAddSettingList.size();
- for (int i = 0; i < settingsN; i++) {
- mAutoAddSettingList.get(i).setUserId(newUser.getIdentifier());
- }
- mAutoTracker.changeUser(newUser);
- startControllersAndSettingsListeners();
- }
-
- @Override
- public int getCurrentUserId() {
- return mCurrentUser.getIdentifier();
- }
-
- private final ManagedProfileController.Callback mProfileCallback =
- new ManagedProfileController.Callback() {
- @Override
- public void onManagedProfileChanged() {
- if (mManagedProfileController.hasActiveProfile()) {
- if (mAutoTracker.isAdded(WORK)) return;
- final int position = mAutoTracker.getRestoredTilePosition(WORK);
- mHost.addTile(WORK, position);
- mAutoTracker.setTileAdded(WORK);
- } else {
- if (!mAutoTracker.isAdded(WORK)) return;
- mHost.removeTile(WORK);
- mAutoTracker.setTileRemoved(WORK);
- }
- }
-
- @Override
- public void onManagedProfileRemoved() {
- }
- };
-
- private final DataSaverController.Listener mDataSaverListener = new Listener() {
- @Override
- public void onDataSaverChanged(boolean isDataSaving) {
- if (mAutoTracker.isAdded(SAVER)) return;
- if (isDataSaving) {
- mHost.addTile(SAVER);
- mAutoTracker.setTileAdded(SAVER);
- mHandler.post(() -> mDataSaverController.removeCallback(mDataSaverListener));
- }
- }
- };
-
- private final HotspotController.Callback mHotspotCallback = new Callback() {
- @Override
- public void onHotspotChanged(boolean enabled, int numDevices) {
- if (mAutoTracker.isAdded(HOTSPOT)) return;
- if (enabled) {
- mHost.addTile(HOTSPOT);
- mAutoTracker.setTileAdded(HOTSPOT);
- mHandler.post(() -> mHotspotController.removeCallback(mHotspotCallback));
- }
- }
- };
-
- private final DeviceControlsController.Callback mDeviceControlsCallback =
- new DeviceControlsController.Callback() {
- @Override
- public void onControlsUpdate(@Nullable Integer position) {
- if (mAutoTracker.isAdded(DEVICE_CONTROLS)) return;
- if (position != null && !hasTile(DEVICE_CONTROLS)) {
- mHost.addTile(DEVICE_CONTROLS, position);
- mAutoTracker.setTileAdded(DEVICE_CONTROLS);
- }
- mHandler.post(() -> mDeviceControlsController.removeCallback());
- }
-
- @Override
- public void removeControlsAutoTracker() {
- mAutoTracker.setTileRemoved(DEVICE_CONTROLS);
- }
- };
-
- private boolean hasTile(String tileSpec) {
- if (tileSpec == null) return false;
- Collection<QSTile> tiles = mHost.getTiles();
- for (QSTile tile : tiles) {
- if (tileSpec.equals(tile.getTileSpec())) {
- return true;
- }
- }
- return false;
- }
-
- private void initWalletController() {
- if (mAutoTracker.isAdded(WALLET)) return;
- Integer position = mWalletController.getWalletPosition();
-
- if (position != null) {
- mHost.addTile(WALLET, position);
- mAutoTracker.setTileAdded(WALLET);
- }
- }
-
- private void initSafetyTile() {
- if (mSafetySpec == null || mAutoTracker.isAdded(mSafetySpec)) {
- return;
- }
- mHost.addTile(CustomTile.getComponentFromSpec(mSafetySpec), true);
- mAutoTracker.setTileAdded(mSafetySpec);
- }
-
- @VisibleForTesting
- final NightDisplayListener.Callback mNightDisplayCallback =
- new NightDisplayListener.Callback() {
- @Override
- public void onActivated(boolean activated) {
- if (activated) {
- addNightTile();
- }
- }
-
- @Override
- public void onAutoModeChanged(int autoMode) {
- if (autoMode == ColorDisplayManager.AUTO_MODE_CUSTOM_TIME
- || autoMode == ColorDisplayManager.AUTO_MODE_TWILIGHT) {
- addNightTile();
- }
- }
-
- private void addNightTile() {
- if (mAutoTracker.isAdded(NIGHT)) return;
- mHost.addTile(NIGHT);
- mAutoTracker.setTileAdded(NIGHT);
- mHandler.post(() -> mNightDisplayListener.setCallback(null));
- }
- };
-
- @VisibleForTesting
- final ReduceBrightColorsController.Listener mReduceBrightColorsCallback =
- new ReduceBrightColorsController.Listener() {
- @Override
- public void onActivated(boolean activated) {
- if (activated) {
- addReduceBrightColorsTile();
- }
- }
-
- @Override
- public void onFeatureEnabledChanged(boolean enabled) {
- if (!enabled) {
- mHost.removeTile(BRIGHTNESS);
- mHandler.post(() -> mReduceBrightColorsController.removeCallback(this));
- }
- }
-
- private void addReduceBrightColorsTile() {
- if (mAutoTracker.isAdded(BRIGHTNESS)) return;
- mHost.addTile(BRIGHTNESS);
- mAutoTracker.setTileAdded(BRIGHTNESS);
- mHandler.post(() -> mReduceBrightColorsController.removeCallback(this));
- }
- };
-
- @VisibleForTesting
- final CastController.Callback mCastCallback = new CastController.Callback() {
- @Override
- public void onCastDevicesChanged() {
- if (mAutoTracker.isAdded(CAST)) return;
-
- boolean isCasting = false;
- for (CastDevice device : mCastController.getCastDevices()) {
- if (device.isCasting()) {
- isCasting = true;
- break;
- }
- }
-
- if (isCasting) {
- mHost.addTile(CAST);
- mAutoTracker.setTileAdded(CAST);
- mHandler.post(() -> mCastController.removeCallback(mCastCallback));
- }
- }
- };
-
- @VisibleForTesting
- final SafetyController.Listener mSafetyCallback = new SafetyController.Listener() {
- @Override
- public void onSafetyCenterEnableChanged(boolean isSafetyCenterEnabled) {
- if (mSafetySpec == null) {
- return;
- }
-
- if (isSafetyCenterEnabled && !mAutoTracker.isAdded(mSafetySpec)) {
- initSafetyTile();
- } else if (!isSafetyCenterEnabled && mAutoTracker.isAdded(mSafetySpec)) {
- mHost.removeTile(mSafetySpec);
- mAutoTracker.setTileRemoved(mSafetySpec);
- }
- }
- };
-
- @VisibleForTesting
- protected UserSettingObserver getSecureSettingForKey(String key) {
- for (UserSettingObserver s : mAutoAddSettingList) {
- if (Objects.equals(key, s.getKey())) {
- return s;
- }
- }
- return null;
- }
-
- /**
- * Tracks tiles that should be auto added when a setting changes.
- * <p>
- * When the setting changes to a value different from 0, if the tile has not been auto added
- * before, it will be added and the listener will be stopped.
- */
- private class AutoAddSetting extends UserSettingObserver {
- private final String mSpec;
-
- AutoAddSetting(
- SecureSettings secureSettings,
- Handler handler,
- String setting,
- int userId,
- String tileSpec
- ) {
- super(secureSettings, handler, setting, userId);
- mSpec = tileSpec;
- }
-
- @Override
- protected void handleValueChanged(int value, boolean observedChange) {
- if (mAutoTracker.isAdded(mSpec)) {
- // This should not be listening anymore
- mHandler.post(() -> setListening(false));
- return;
- }
- if (value != 0) {
- if (mSpec.startsWith(CustomTile.PREFIX)) {
- mHost.addTile(CustomTile.getComponentFromSpec(mSpec), /* end */ true);
- } else {
- mHost.addTile(mSpec);
- }
- mAutoTracker.setTileAdded(mSpec);
- mHandler.post(() -> setListening(false));
- }
- }
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceControlsControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceControlsControllerImpl.kt
index 1224275..e29e069 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceControlsControllerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceControlsControllerImpl.kt
@@ -21,13 +21,12 @@
import android.content.SharedPreferences
import android.provider.Settings
import android.util.Log
-import com.android.systemui.res.R
import com.android.systemui.controls.ControlsServiceInfo
import com.android.systemui.controls.dagger.ControlsComponent
import com.android.systemui.controls.management.ControlsListingController
import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.res.R
import com.android.systemui.settings.UserContextProvider
-import com.android.systemui.statusbar.phone.AutoTileManager
import com.android.systemui.statusbar.policy.DeviceControlsController.Callback
import com.android.systemui.util.settings.SecureSettings
import javax.inject.Inject
@@ -35,14 +34,16 @@
/**
* Watches for Device Controls QS Tile activation, which can happen in two ways:
* <ol>
- * <li>Migration from Power Menu - For existing Android 11 users, create a tile in a high
- * priority position.
- * <li>Device controls service becomes available - For non-migrated users, create a tile and
- * place at the end of active tiles, and initiate seeding where possible.
+ * <li>Migration from Power Menu - For existing Android 11 users, create a tile in a high priority
+ * position.
+ * <li>Device controls service becomes available - For non-migrated users, create a tile and place
+ * at the end of active tiles, and initiate seeding where possible.
* </ol>
*/
@SysUISingleton
-public class DeviceControlsControllerImpl @Inject constructor(
+public class DeviceControlsControllerImpl
+@Inject
+constructor(
private val context: Context,
private val controlsComponent: ControlsComponent,
private val userContextProvider: UserContextProvider,
@@ -52,13 +53,14 @@
private var callback: Callback? = null
internal var position: Int? = null
- private val listingCallback = object : ControlsListingController.ControlsListingCallback {
- override fun onServicesUpdated(serviceInfos: List<ControlsServiceInfo>) {
- if (!serviceInfos.isEmpty()) {
- seedFavorites(serviceInfos)
+ private val listingCallback =
+ object : ControlsListingController.ControlsListingCallback {
+ override fun onServicesUpdated(serviceInfos: List<ControlsServiceInfo>) {
+ if (!serviceInfos.isEmpty()) {
+ seedFavorites(serviceInfos)
+ }
}
}
- }
companion object {
private const val TAG = "DeviceControlsControllerImpl"
@@ -80,7 +82,7 @@
}
/**
- * This migration logic assumes that something like [AutoTileManager] is tracking state
+ * This migration logic assumes that something like [AutoAddTracker] is tracking state
* externally, and won't call this method after receiving a response via
* [Callback#onControlsUpdate], once per user. Otherwise the calculated position may be
* incorrect.
@@ -118,16 +120,19 @@
}
/**
- * See if any available control service providers match one of the preferred components. If
- * they do, and there are no current favorites for that component, query the preferred
- * component for a limited number of suggested controls.
+ * See if any available control service providers match one of the preferred components. If they
+ * do, and there are no current favorites for that component, query the preferred component for
+ * a limited number of suggested controls.
*/
private fun seedFavorites(serviceInfos: List<ControlsServiceInfo>) {
- val preferredControlsPackages = context.getResources().getStringArray(
- R.array.config_controlsPreferredPackages)
+ val preferredControlsPackages =
+ context.getResources().getStringArray(R.array.config_controlsPreferredPackages)
- val prefs = userContextProvider.userContext.getSharedPreferences(
- PREFS_CONTROLS_FILE, Context.MODE_PRIVATE)
+ val prefs =
+ userContextProvider.userContext.getSharedPreferences(
+ PREFS_CONTROLS_FILE,
+ Context.MODE_PRIVATE
+ )
val seededPackages =
prefs.getStringSet(PREFS_CONTROLS_SEEDING_COMPLETED, emptySet()) ?: emptySet()
@@ -157,21 +162,22 @@
if (componentsToSeed.isEmpty()) return
controlsController.seedFavoritesForComponents(
- componentsToSeed,
- { response ->
- Log.d(TAG, "Controls seeded: $response")
- if (response.accepted) {
- addPackageToSeededSet(prefs, response.packageName)
- if (position == null) {
- position = QS_DEFAULT_POSITION
- }
- fireControlsUpdate()
-
- controlsComponent.getControlsListingController().ifPresent {
- it.removeCallback(listingCallback)
- }
+ componentsToSeed,
+ { response ->
+ Log.d(TAG, "Controls seeded: $response")
+ if (response.accepted) {
+ addPackageToSeededSet(prefs, response.packageName)
+ if (position == null) {
+ position = QS_DEFAULT_POSITION
}
- })
+ fireControlsUpdate()
+
+ controlsComponent.getControlsListingController().ifPresent {
+ it.removeCallback(listingCallback)
+ }
+ }
+ }
+ )
}
private fun addPackageToSeededSet(prefs: SharedPreferences, pkg: String) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/AutoAddTrackerTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/AutoAddTrackerTest.java
deleted file mode 100644
index 1eeaef7..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/AutoAddTrackerTest.java
+++ /dev/null
@@ -1,311 +0,0 @@
-/*
- * 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.TestableLooper.RunWithLooper;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-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(AndroidJUnit4.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<BroadcastReceiver> mBroadcastReceiverArgumentCaptor;
- @Captor
- private ArgumentCaptor<IntentFilter> 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
- );
- }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSTileHostTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSTileHostTest.java
deleted file mode 100644
index 6d1bc82..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSTileHostTest.java
+++ /dev/null
@@ -1,786 +0,0 @@
-/*
- * Copyright (C) 2018 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.Flags.FLAG_QS_NEW_PIPELINE;
-import static com.android.systemui.Flags.FLAG_QS_NEW_TILES;
-
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertTrue;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.ArgumentMatchers.isNull;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.database.ContentObserver;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.UserHandle;
-import android.util.SparseArray;
-
-import androidx.annotation.Nullable;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
-import com.android.internal.logging.MetricsLogger;
-import com.android.internal.util.CollectionUtils;
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.animation.Expandable;
-import com.android.systemui.classifier.FalsingManagerFake;
-import com.android.systemui.dump.nano.SystemUIProtoDump;
-import com.android.systemui.plugins.ActivityStarter;
-import com.android.systemui.plugins.PluginManager;
-import com.android.systemui.plugins.qs.QSFactory;
-import com.android.systemui.plugins.qs.QSTile;
-import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.qs.external.CustomTile;
-import com.android.systemui.qs.external.CustomTileStatePersister;
-import com.android.systemui.qs.external.TileLifecycleManager;
-import com.android.systemui.qs.external.TileServiceKey;
-import com.android.systemui.qs.logging.QSLogger;
-import com.android.systemui.qs.pipeline.shared.QSPipelineFlagsRepository;
-import com.android.systemui.qs.tileimpl.QSTileImpl;
-import com.android.systemui.qs.tiles.di.NewQSTileFactory;
-import com.android.systemui.res.R;
-import com.android.systemui.settings.UserFileManager;
-import com.android.systemui.settings.UserTracker;
-import com.android.systemui.shade.ShadeController;
-import com.android.systemui.statusbar.phone.AutoTileManager;
-import com.android.systemui.tuner.TunerService;
-import com.android.systemui.util.FakeSharedPreferences;
-import com.android.systemui.util.concurrency.FakeExecutor;
-import com.android.systemui.util.settings.FakeSettings;
-import com.android.systemui.util.settings.SecureSettings;
-import com.android.systemui.util.time.FakeSystemClock;
-
-import dagger.Lazy;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.mockito.stubbing.Answer;
-
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.util.List;
-import java.util.concurrent.Executor;
-
-import javax.inject.Provider;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class QSTileHostTest extends SysuiTestCase {
-
- private static String MOCK_STATE_STRING = "MockState";
- private static ComponentName CUSTOM_TILE =
- ComponentName.unflattenFromString("TEST_PKG/.TEST_CLS");
- private static final String CUSTOM_TILE_SPEC = CustomTile.toSpec(CUSTOM_TILE);
- private static final String SETTING = QSHost.TILES_SETTING;
- @Mock
- private PluginManager mPluginManager;
- @Mock
- private TunerService mTunerService;
- @Mock
- private AutoTileManager mAutoTiles;
- @Mock
- private ShadeController mShadeController;
- @Mock
- private QSLogger mQSLogger;
- @Mock
- private CustomTile mCustomTile;
- @Mock
- private UserTracker mUserTracker;
- @Mock
- private CustomTileStatePersister mCustomTileStatePersister;
- @Mock
- private TileLifecycleManager.Factory mTileLifecycleManagerFactory;
- @Mock
- private TileLifecycleManager mTileLifecycleManager;
- @Mock
- private UserFileManager mUserFileManager;
-
- private SecureSettings mSecureSettings;
-
- private QSFactory mDefaultFactory;
-
- private SparseArray<SharedPreferences> mSharedPreferencesByUser;
-
- private QSPipelineFlagsRepository mQSPipelineFlagsRepository;
-
- private FakeExecutor mMainExecutor;
-
- private QSTileHost mQSTileHost;
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
-
- mSetFlagsRule.disableFlags(FLAG_QS_NEW_PIPELINE);
- mSetFlagsRule.disableFlags(FLAG_QS_NEW_TILES);
- mQSPipelineFlagsRepository = new QSPipelineFlagsRepository();
-
- mMainExecutor = new FakeExecutor(new FakeSystemClock());
-
- mSharedPreferencesByUser = new SparseArray<>();
- when(mTileLifecycleManagerFactory
- .create(any(Intent.class), any(UserHandle.class)))
- .thenReturn(mTileLifecycleManager);
- when(mUserFileManager.getSharedPreferences(anyString(), anyInt(), anyInt()))
- .thenAnswer((Answer<SharedPreferences>) invocation -> {
- assertEquals(QSTileHost.TILES, invocation.getArgument(0));
- int userId = invocation.getArgument(2);
- if (!mSharedPreferencesByUser.contains(userId)) {
- mSharedPreferencesByUser.put(userId, new FakeSharedPreferences());
- }
- return mSharedPreferencesByUser.get(userId);
- });
-
- mSecureSettings = new FakeSettings();
- saveSetting("");
- setUpTileFactory();
- mQSTileHost = new TestQSTileHost(mContext, () -> null, mDefaultFactory, mMainExecutor,
- mPluginManager, mTunerService, () -> mAutoTiles, () -> mShadeController,
- mQSLogger, mUserTracker, mSecureSettings, mCustomTileStatePersister,
- mTileLifecycleManagerFactory, mUserFileManager, mQSPipelineFlagsRepository);
- mMainExecutor.runAllReady();
-
- mSecureSettings.registerContentObserverForUserSync(SETTING, new ContentObserver(null) {
- @Override
- public void onChange(boolean selfChange) {
- super.onChange(selfChange);
- mMainExecutor.execute(() -> mQSTileHost.onTuningChanged(SETTING, getSetting()));
- mMainExecutor.runAllReady();
- }
- }, mUserTracker.getUserId());
- }
-
- private void saveSetting(String value) {
- mSecureSettings.putStringForUser(
- SETTING, value, "", false, mUserTracker.getUserId(), false);
- }
-
- private String getSetting() {
- return mSecureSettings.getStringForUser(SETTING, mUserTracker.getUserId());
- }
-
- private void setUpTileFactory() {
- mDefaultFactory = new FakeQSFactory(spec -> {
- if ("spec1".equals(spec)) {
- return new TestTile1(mQSTileHost);
- } else if ("spec2".equals(spec)) {
- return new TestTile2(mQSTileHost);
- } else if ("spec3".equals(spec)) {
- return new TestTile3(mQSTileHost);
- } else if ("na".equals(spec)) {
- return new NotAvailableTile(mQSTileHost);
- } else if (CUSTOM_TILE_SPEC.equals(spec)) {
- QSTile tile = mCustomTile;
- QSTile.State s = mock(QSTile.State.class);
- s.spec = spec;
- when(mCustomTile.getState()).thenReturn(s);
- return tile;
- } else if ("internet".equals(spec)
- || "wifi".equals(spec)
- || "cell".equals(spec)) {
- return new TestTile1(mQSTileHost);
- } else {
- return null;
- }
- });
- when(mCustomTile.isAvailable()).thenReturn(true);
- }
-
- @Test
- public void testLoadTileSpecs_emptySetting() {
- List<String> tiles = QSTileHost.loadTileSpecs(mContext, "");
- assertFalse(tiles.isEmpty());
- }
-
- @Test
- public void testLoadTileSpecs_nullSetting() {
- List<String> tiles = QSTileHost.loadTileSpecs(mContext, null);
- assertFalse(tiles.isEmpty());
- }
-
- @Test
- public void testInvalidSpecUsesDefault() {
- mContext.getOrCreateTestableResources()
- .addOverride(R.string.quick_settings_tiles, "spec1,spec2");
- saveSetting("not-valid");
-
- assertEquals(2, mQSTileHost.getTiles().size());
- }
-
- @Test
- public void testRemoveWifiAndCellularWithoutInternet() {
- saveSetting("wifi, spec1, cell, spec2");
-
- assertEquals("internet", mQSTileHost.getSpecs().get(0));
- assertEquals("spec1", mQSTileHost.getSpecs().get(1));
- assertEquals("spec2", mQSTileHost.getSpecs().get(2));
- }
-
- @Test
- public void testRemoveWifiAndCellularWithInternet() {
- saveSetting("wifi, spec1, cell, spec2, internet");
-
- assertEquals("spec1", mQSTileHost.getSpecs().get(0));
- assertEquals("spec2", mQSTileHost.getSpecs().get(1));
- assertEquals("internet", mQSTileHost.getSpecs().get(2));
- }
-
- @Test
- public void testRemoveWifiWithoutInternet() {
- saveSetting("spec1, wifi, spec2");
-
- assertEquals("spec1", mQSTileHost.getSpecs().get(0));
- assertEquals("internet", mQSTileHost.getSpecs().get(1));
- assertEquals("spec2", mQSTileHost.getSpecs().get(2));
- }
-
- @Test
- public void testRemoveCellWithInternet() {
- saveSetting("spec1, spec2, cell, internet");
-
- assertEquals("spec1", mQSTileHost.getSpecs().get(0));
- assertEquals("spec2", mQSTileHost.getSpecs().get(1));
- assertEquals("internet", mQSTileHost.getSpecs().get(2));
- }
-
- @Test
- public void testNoWifiNoCellularNoInternet() {
- saveSetting("spec1,spec2");
-
- assertEquals("spec1", mQSTileHost.getSpecs().get(0));
- assertEquals("spec2", mQSTileHost.getSpecs().get(1));
- }
-
- @Test
- public void testSpecWithInvalidDoesNotUseDefault() {
- mContext.getOrCreateTestableResources()
- .addOverride(R.string.quick_settings_tiles, "spec1,spec2");
- saveSetting("spec2,not-valid");
-
- assertEquals(1, mQSTileHost.getTiles().size());
- QSTile element = CollectionUtils.firstOrNull(mQSTileHost.getTiles());
- assertTrue(element instanceof TestTile2);
- }
-
- @Test
- public void testDump() {
- saveSetting("spec1,spec2");
- StringWriter w = new StringWriter();
- PrintWriter pw = new PrintWriter(w);
- mQSTileHost.dump(pw, new String[]{});
-
- String output = "QSTileHost:" + "\n"
- + "tile specs: [spec1, spec2]" + "\n"
- + "current user: 0" + "\n"
- + "is dirty: false" + "\n"
- + "tiles:" + "\n"
- + "TestTile1:" + "\n"
- + " MockState" + "\n"
- + "TestTile2:" + "\n"
- + " MockState" + "\n";
-
- System.out.println(output);
- System.out.println(w.getBuffer().toString());
-
- assertEquals(output, w.getBuffer().toString());
- }
-
- @Test
- public void testDefault() {
- mContext.getOrCreateTestableResources()
- .addOverride(R.string.quick_settings_tiles_default, "spec1");
- saveSetting("default");
- assertEquals(1, mQSTileHost.getTiles().size());
- QSTile element = CollectionUtils.firstOrNull(mQSTileHost.getTiles());
- assertTrue(element instanceof TestTile1);
- verify(mQSLogger).logTileAdded("spec1");
- }
-
- @Test
- public void testNoRepeatedSpecs_addTile() {
- mContext.getOrCreateTestableResources()
- .addOverride(R.string.quick_settings_tiles, "spec1,spec2");
- saveSetting("spec1,spec2");
-
- mQSTileHost.addTile("spec1");
-
- assertEquals(2, mQSTileHost.getSpecs().size());
- assertEquals("spec1", mQSTileHost.getSpecs().get(0));
- assertEquals("spec2", mQSTileHost.getSpecs().get(1));
- }
-
- @Test
- public void testAddTileAtValidPosition() {
- mContext.getOrCreateTestableResources()
- .addOverride(R.string.quick_settings_tiles, "spec1,spec3");
- saveSetting("spec1,spec3");
-
- mQSTileHost.addTile("spec2", 1);
- mMainExecutor.runAllReady();
-
- assertEquals(3, mQSTileHost.getSpecs().size());
- assertEquals("spec1", mQSTileHost.getSpecs().get(0));
- assertEquals("spec2", mQSTileHost.getSpecs().get(1));
- assertEquals("spec3", mQSTileHost.getSpecs().get(2));
- }
-
- @Test
- public void testAddTileAtInvalidPositionAddsToEnd() {
- mContext.getOrCreateTestableResources()
- .addOverride(R.string.quick_settings_tiles, "spec1,spec3");
- saveSetting("spec1,spec3");
-
- mQSTileHost.addTile("spec2", 100);
- mMainExecutor.runAllReady();
-
- assertEquals(3, mQSTileHost.getSpecs().size());
- assertEquals("spec1", mQSTileHost.getSpecs().get(0));
- assertEquals("spec3", mQSTileHost.getSpecs().get(1));
- assertEquals("spec2", mQSTileHost.getSpecs().get(2));
- }
-
- @Test
- public void testAddTileAtEnd() {
- mContext.getOrCreateTestableResources()
- .addOverride(R.string.quick_settings_tiles, "spec1,spec3");
- saveSetting("spec1,spec3");
-
- mQSTileHost.addTile("spec2", QSTileHost.POSITION_AT_END);
- mMainExecutor.runAllReady();
-
- assertEquals(3, mQSTileHost.getSpecs().size());
- assertEquals("spec1", mQSTileHost.getSpecs().get(0));
- assertEquals("spec3", mQSTileHost.getSpecs().get(1));
- assertEquals("spec2", mQSTileHost.getSpecs().get(2));
- }
-
- @Test
- public void testNoRepeatedSpecs_customTile() {
- saveSetting(CUSTOM_TILE_SPEC);
-
- mQSTileHost.addTile(CUSTOM_TILE, /* end */ false);
- mMainExecutor.runAllReady();
-
- assertEquals(1, mQSTileHost.getSpecs().size());
- assertEquals(CUSTOM_TILE_SPEC, mQSTileHost.getSpecs().get(0));
- }
-
- @Test
- public void testAddedAtBeginningOnDefault_customTile() {
- saveSetting("spec1"); // seed
-
- mQSTileHost.addTile(CUSTOM_TILE);
- mMainExecutor.runAllReady();
-
- assertEquals(2, mQSTileHost.getSpecs().size());
- assertEquals(CUSTOM_TILE_SPEC, mQSTileHost.getSpecs().get(0));
- }
-
- @Test
- public void testAddedAtBeginning_customTile() {
- saveSetting("spec1"); // seed
-
- mQSTileHost.addTile(CUSTOM_TILE, /* end */ false);
- mMainExecutor.runAllReady();
-
- assertEquals(2, mQSTileHost.getSpecs().size());
- assertEquals(CUSTOM_TILE_SPEC, mQSTileHost.getSpecs().get(0));
- }
-
- @Test
- public void testAddedAtEnd_customTile() {
- saveSetting("spec1"); // seed
-
- mQSTileHost.addTile(CUSTOM_TILE, /* end */ true);
- mMainExecutor.runAllReady();
-
- assertEquals(2, mQSTileHost.getSpecs().size());
- assertEquals(CUSTOM_TILE_SPEC, mQSTileHost.getSpecs().get(1));
- }
-
- @Test
- public void testLoadTileSpec_repeated() {
- List<String> specs = QSTileHost.loadTileSpecs(mContext, "spec1,spec1,spec2");
-
- assertEquals(2, specs.size());
- assertEquals("spec1", specs.get(0));
- assertEquals("spec2", specs.get(1));
- }
-
- @Test
- public void testLoadTileSpec_repeatedInDefault() {
- mContext.getOrCreateTestableResources()
- .addOverride(R.string.quick_settings_tiles_default, "spec1,spec1");
- List<String> specs = QSTileHost.loadTileSpecs(mContext, "default");
- }
-
- @Test
- public void testLoadTileSpec_repeatedDefaultAndSetting() {
- mContext.getOrCreateTestableResources()
- .addOverride(R.string.quick_settings_tiles_default, "spec1");
- List<String> specs = QSTileHost.loadTileSpecs(mContext, "default,spec1");
- }
-
- @Test
- public void testNotAvailableTile_specNotNull() {
- saveSetting("na");
- verify(mQSLogger, never()).logTileDestroyed(isNull(), anyString());
- }
-
- @Test
- public void testCustomTileRemoved_stateDeleted() {
- mQSTileHost.changeTilesByUser(List.of(CUSTOM_TILE_SPEC), List.of());
-
- verify(mCustomTileStatePersister)
- .removeState(new TileServiceKey(CUSTOM_TILE, mQSTileHost.getUserId()));
- }
-
- @Test
- public void testRemoveTiles() {
- saveSetting("spec1,spec2,spec3");
-
- mQSTileHost.removeTiles(List.of("spec1", "spec2"));
-
- mMainExecutor.runAllReady();
- assertEquals(List.of("spec3"), mQSTileHost.getSpecs());
- }
-
- @Test
- public void testTilesRemovedInQuickSuccession() {
- saveSetting("spec1,spec2,spec3");
- mQSTileHost.removeTile("spec1");
- mQSTileHost.removeTile("spec3");
-
- mMainExecutor.runAllReady();
- assertEquals(List.of("spec2"), mQSTileHost.getSpecs());
- assertEquals("spec2", getSetting());
- }
-
- @Test
- public void testAddTileInMainThread() {
- saveSetting("spec1,spec2");
-
- mQSTileHost.addTile("spec3");
- assertEquals(List.of("spec1", "spec2"), mQSTileHost.getSpecs());
-
- mMainExecutor.runAllReady();
- assertEquals(List.of("spec1", "spec2", "spec3"), mQSTileHost.getSpecs());
- }
-
- @Test
- public void testRemoveTileInMainThread() {
- saveSetting("spec1,spec2");
-
- mQSTileHost.removeTile("spec1");
- assertEquals(List.of("spec1", "spec2"), mQSTileHost.getSpecs());
-
- mMainExecutor.runAllReady();
- assertEquals(List.of("spec2"), mQSTileHost.getSpecs());
- }
-
- @Test
- public void testRemoveTilesInMainThread() {
- saveSetting("spec1,spec2,spec3");
-
- mQSTileHost.removeTiles(List.of("spec3", "spec1"));
- assertEquals(List.of("spec1", "spec2", "spec3"), mQSTileHost.getSpecs());
-
- mMainExecutor.runAllReady();
- assertEquals(List.of("spec2"), mQSTileHost.getSpecs());
- }
-
- @Test
- public void testRemoveTileByUserInMainThread() {
- saveSetting("spec1," + CUSTOM_TILE_SPEC);
-
- mQSTileHost.removeTileByUser(CUSTOM_TILE);
- assertEquals(List.of("spec1", CUSTOM_TILE_SPEC), mQSTileHost.getSpecs());
-
- mMainExecutor.runAllReady();
- assertEquals(List.of("spec1"), mQSTileHost.getSpecs());
- }
-
- @Test
- public void testNonValidTileNotStoredInSettings() {
- saveSetting("spec1,not-valid");
-
- assertEquals(List.of("spec1"), mQSTileHost.getSpecs());
- assertEquals("spec1", getSetting());
- }
-
- @Test
- public void testNotAvailableTileNotStoredInSettings() {
- saveSetting("spec1,na");
-
- assertEquals(List.of("spec1"), mQSTileHost.getSpecs());
- assertEquals("spec1", getSetting());
- }
-
- @Test
- public void testIsTileAdded_true() {
- int user = mUserTracker.getUserId();
- getSharedPreferencesForUser(user)
- .edit()
- .putBoolean(CUSTOM_TILE.flattenToString(), true)
- .apply();
-
- assertTrue(mQSTileHost.isTileAdded(CUSTOM_TILE, user));
- }
-
- @Test
- public void testIsTileAdded_false() {
- int user = mUserTracker.getUserId();
- getSharedPreferencesForUser(user)
- .edit()
- .putBoolean(CUSTOM_TILE.flattenToString(), false)
- .apply();
-
- assertFalse(mQSTileHost.isTileAdded(CUSTOM_TILE, user));
- }
-
- @Test
- public void testIsTileAdded_notSet() {
- int user = mUserTracker.getUserId();
-
- assertFalse(mQSTileHost.isTileAdded(CUSTOM_TILE, user));
- }
-
- @Test
- public void testIsTileAdded_differentUser() {
- int user = mUserTracker.getUserId();
- mUserFileManager.getSharedPreferences(QSTileHost.TILES, 0, user)
- .edit()
- .putBoolean(CUSTOM_TILE.flattenToString(), true)
- .apply();
-
- assertFalse(mQSTileHost.isTileAdded(CUSTOM_TILE, user + 1));
- }
-
- @Test
- public void testSetTileAdded_true() {
- int user = mUserTracker.getUserId();
- mQSTileHost.setTileAdded(CUSTOM_TILE, user, true);
-
- assertTrue(getSharedPreferencesForUser(user)
- .getBoolean(CUSTOM_TILE.flattenToString(), false));
- }
-
- @Test
- public void testSetTileAdded_false() {
- int user = mUserTracker.getUserId();
- mQSTileHost.setTileAdded(CUSTOM_TILE, user, false);
-
- assertFalse(getSharedPreferencesForUser(user)
- .getBoolean(CUSTOM_TILE.flattenToString(), false));
- }
-
- @Test
- public void testSetTileAdded_differentUser() {
- int user = mUserTracker.getUserId();
- mQSTileHost.setTileAdded(CUSTOM_TILE, user, true);
-
- assertFalse(getSharedPreferencesForUser(user + 1)
- .getBoolean(CUSTOM_TILE.flattenToString(), false));
- }
-
- @Test
- public void testSetTileRemoved_afterCustomTileChangedByUser() {
- int user = mUserTracker.getUserId();
- saveSetting(CUSTOM_TILE_SPEC);
-
- // This will be done by TileServiceManager
- mQSTileHost.setTileAdded(CUSTOM_TILE, user, true);
-
- mQSTileHost.changeTilesByUser(mQSTileHost.getSpecs(), List.of("spec1"));
- assertFalse(getSharedPreferencesForUser(user)
- .getBoolean(CUSTOM_TILE.flattenToString(), false));
- }
-
- @Test
- public void testSetTileRemoved_removedByUser() {
- int user = mUserTracker.getUserId();
- saveSetting(CUSTOM_TILE_SPEC);
-
- // This will be done by TileServiceManager
- mQSTileHost.setTileAdded(CUSTOM_TILE, user, true);
-
- mQSTileHost.removeTileByUser(CUSTOM_TILE);
- mMainExecutor.runAllReady();
- assertFalse(getSharedPreferencesForUser(user)
- .getBoolean(CUSTOM_TILE.flattenToString(), false));
- }
-
- @Test
- public void testSetTileRemoved_removedBySystem() {
- int user = mUserTracker.getUserId();
- saveSetting("spec1," + CUSTOM_TILE_SPEC);
-
- // This will be done by TileServiceManager
- mQSTileHost.setTileAdded(CUSTOM_TILE, user, true);
-
- mQSTileHost.removeTile(CUSTOM_TILE_SPEC);
- mMainExecutor.runAllReady();
- assertFalse(getSharedPreferencesForUser(user)
- .getBoolean(CUSTOM_TILE.flattenToString(), false));
- }
-
- @Test
- public void testProtoDump_noTiles() {
- SystemUIProtoDump proto = new SystemUIProtoDump();
- mQSTileHost.dumpProto(proto, new String[0]);
-
- assertEquals(0, proto.tiles.length);
- }
-
- @Test
- public void testTilesInOrder() {
- saveSetting("spec1," + CUSTOM_TILE_SPEC);
-
- SystemUIProtoDump proto = new SystemUIProtoDump();
- mQSTileHost.dumpProto(proto, new String[0]);
-
- assertEquals(2, proto.tiles.length);
- assertEquals("spec1", proto.tiles[0].getSpec());
- assertEquals(CUSTOM_TILE.getPackageName(), proto.tiles[1].getComponentName().packageName);
- assertEquals(CUSTOM_TILE.getClassName(), proto.tiles[1].getComponentName().className);
- }
-
- private SharedPreferences getSharedPreferencesForUser(int user) {
- return mUserFileManager.getSharedPreferences(QSTileHost.TILES, 0, user);
- }
-
- private class TestQSTileHost extends QSTileHost {
- TestQSTileHost(Context context, Lazy<NewQSTileFactory> newQSTileFactoryProvider,
- QSFactory defaultFactory, Executor mainExecutor,
- PluginManager pluginManager, TunerService tunerService,
- Provider<AutoTileManager> autoTiles,
- Lazy<ShadeController> shadeController, QSLogger qsLogger,
- UserTracker userTracker, SecureSettings secureSettings,
- CustomTileStatePersister customTileStatePersister,
- TileLifecycleManager.Factory tileLifecycleManagerFactory,
- UserFileManager userFileManager, QSPipelineFlagsRepository featureFlags) {
- super(context, newQSTileFactoryProvider, defaultFactory, mainExecutor, pluginManager,
- tunerService, autoTiles, shadeController, qsLogger,
- userTracker, secureSettings, customTileStatePersister,
- tileLifecycleManagerFactory, userFileManager, featureFlags);
- }
-
- @Override
- public void onPluginConnected(QSFactory plugin, Context pluginContext) {
- }
-
- @Override
- public void onPluginDisconnected(QSFactory plugin) {
- }
- }
-
-
- private class TestTile extends QSTileImpl<QSTile.State> {
-
- protected TestTile(QSHost host) {
- super(
- host,
- mock(QsEventLogger.class),
- mock(Looper.class),
- mock(Handler.class),
- new FalsingManagerFake(),
- mock(MetricsLogger.class),
- mock(StatusBarStateController.class),
- mock(ActivityStarter.class),
- QSTileHostTest.this.mQSLogger
- );
- }
-
- @Override
- public State newTileState() {
- State s = mock(QSTile.State.class);
- when(s.toString()).thenReturn(MOCK_STATE_STRING);
- return s;
- }
-
- @Override
- protected void handleClick(@Nullable Expandable expandable) {}
-
- @Override
- protected void handleUpdateState(State state, Object arg) {}
-
- @Override
- public int getMetricsCategory() {
- return 0;
- }
-
- @Override
- public Intent getLongClickIntent() {
- return null;
- }
-
- @Override
- public CharSequence getTileLabel() {
- return null;
- }
- }
-
- private class TestTile1 extends TestTile {
-
- protected TestTile1(QSHost host) {
- super(host);
- }
- }
-
- private class TestTile2 extends TestTile {
-
- protected TestTile2(QSHost host) {
- super(host);
- }
- }
-
- private class TestTile3 extends TestTile {
-
- protected TestTile3(QSHost host) {
- super(host);
- }
- }
-
- private class NotAvailableTile extends TestTile {
-
- protected NotAvailableTile(QSHost host) {
- super(host);
- }
-
- @Override
- public boolean isAvailable() {
- return false;
- }
- }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/shared/QSPipelineFlagsRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/shared/QSPipelineFlagsRepositoryTest.kt
index 970cd17..090a85b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/shared/QSPipelineFlagsRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/shared/QSPipelineFlagsRepositoryTest.kt
@@ -15,20 +15,6 @@
private val underTest = QSPipelineFlagsRepository()
@Test
- fun pipelineFlagDisabled() {
- mSetFlagsRule.disableFlags(Flags.FLAG_QS_NEW_PIPELINE)
-
- assertThat(underTest.pipelineEnabled).isFalse()
- }
-
- @Test
- fun pipelineFlagEnabled() {
- mSetFlagsRule.enableFlags(Flags.FLAG_QS_NEW_PIPELINE)
-
- assertThat(underTest.pipelineEnabled).isTrue()
- }
-
- @Test
fun tilesFlagDisabled() {
mSetFlagsRule.disableFlags(Flags.FLAG_QS_NEW_TILES)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java
deleted file mode 100644
index 665544d..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java
+++ /dev/null
@@ -1,648 +0,0 @@
-/*
- * 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.statusbar.phone;
-
-import static com.android.systemui.Flags.FLAG_QS_NEW_PIPELINE;
-import static com.android.systemui.qs.dagger.QSFlagsModule.RBC_AVAILABLE;
-import static com.android.systemui.statusbar.phone.AutoTileManager.DEVICE_CONTROLS;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-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;
-import static org.mockito.Mockito.inOrder;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
-
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.hardware.display.ColorDisplayManager;
-import android.hardware.display.NightDisplayListener;
-import android.os.Handler;
-import android.os.UserHandle;
-import android.testing.TestableLooper;
-import android.testing.TestableLooper.RunWithLooper;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.dagger.NightDisplayListenerModule;
-import com.android.systemui.plugins.qs.QSTile;
-import com.android.systemui.qs.AutoAddTracker;
-import com.android.systemui.qs.QSHost;
-import com.android.systemui.qs.ReduceBrightColorsController;
-import com.android.systemui.qs.UserSettingObserver;
-import com.android.systemui.qs.external.CustomTile;
-import com.android.systemui.res.R;
-import com.android.systemui.statusbar.policy.CastController;
-import com.android.systemui.statusbar.policy.CastDevice;
-import com.android.systemui.statusbar.policy.DataSaverController;
-import com.android.systemui.statusbar.policy.DeviceControlsController;
-import com.android.systemui.statusbar.policy.HotspotController;
-import com.android.systemui.statusbar.policy.SafetyController;
-import com.android.systemui.statusbar.policy.WalletController;
-import com.android.systemui.util.settings.FakeSettings;
-import com.android.systemui.util.settings.SecureSettings;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Answers;
-import org.mockito.ArgumentCaptor;
-import org.mockito.InOrder;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
-import org.mockito.Spy;
-import org.mockito.stubbing.Answer;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-import javax.inject.Named;
-
-@RunWith(AndroidJUnit4.class)
-@RunWithLooper
-@SmallTest
-public class AutoTileManagerTest extends SysuiTestCase {
-
- private static final String TEST_SETTING = "setting";
- private static final String TEST_SPEC = "spec";
- private static final String TEST_SETTING_COMPONENT = "setting_component";
- private static final String TEST_COMPONENT = "test_pkg/test_cls";
- private static final String TEST_CUSTOM_SPEC = "custom(" + TEST_COMPONENT + ")";
- private static final String TEST_CUSTOM_SAFETY_CLASS = "safety_cls";
- private static final String TEST_CUSTOM_SAFETY_PKG = "safety_pkg";
- private static final String TEST_CUSTOM_SAFETY_SPEC = CustomTile.toSpec(new ComponentName(
- TEST_CUSTOM_SAFETY_PKG, TEST_CUSTOM_SAFETY_CLASS));
- private static final String SEPARATOR = AutoTileManager.SETTING_SEPARATOR;
-
- private static final int USER = 0;
-
- @Mock private QSHost mQsHost;
- @Mock private AutoAddTracker mAutoAddTracker;
- @Mock private CastController mCastController;
- @Mock private HotspotController mHotspotController;
- @Mock private DataSaverController mDataSaverController;
- @Mock private ManagedProfileController mManagedProfileController;
- @Mock private NightDisplayListener mNightDisplayListener;
- @Mock(answer = Answers.RETURNS_SELF)
- private NightDisplayListenerModule.Builder mNightDisplayListenerBuilder;
- @Mock private ReduceBrightColorsController mReduceBrightColorsController;
- @Mock private DeviceControlsController mDeviceControlsController;
- @Mock private WalletController mWalletController;
- @Mock private SafetyController mSafetyController;
- @Mock(answer = Answers.RETURNS_SELF)
- private AutoAddTracker.Builder mAutoAddTrackerBuilder;
- @Mock private Context mUserContext;
- @Spy private PackageManager mPackageManager;
- private final boolean mIsReduceBrightColorsAvailable = true;
-
- private AutoTileManager mAutoTileManager; // under test
-
- private SecureSettings mSecureSettings;
- private ManagedProfileController.Callback mManagedProfileCallback;
-
- @Before
- public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
- mSecureSettings = new FakeSettings();
-
- mSetFlagsRule.disableFlags(FLAG_QS_NEW_PIPELINE);
-
- mContext.getOrCreateTestableResources().addOverride(
- R.array.config_quickSettingsAutoAdd,
- new String[] {
- TEST_SETTING + SEPARATOR + TEST_SPEC,
- TEST_SETTING_COMPONENT + SEPARATOR + TEST_CUSTOM_SPEC
- }
- );
- mContext.getOrCreateTestableResources().addOverride(
- com.android.internal.R.bool.config_nightDisplayAvailable, true);
- mContext.getOrCreateTestableResources().addOverride(
- R.string.safety_quick_settings_tile_class, TEST_CUSTOM_SAFETY_CLASS);
-
- when(mAutoAddTrackerBuilder.build()).thenReturn(mAutoAddTracker);
- when(mQsHost.getUserContext()).thenReturn(mUserContext);
- when(mUserContext.getUser()).thenReturn(UserHandle.of(USER));
- mPackageManager = Mockito.spy(mContext.getPackageManager());
- when(mPackageManager.getPermissionControllerPackageName())
- .thenReturn(TEST_CUSTOM_SAFETY_PKG);
- Context context = Mockito.spy(mContext);
- when(context.getPackageManager()).thenReturn(mPackageManager);
- when(mNightDisplayListenerBuilder.build()).thenReturn(mNightDisplayListener);
-
- mAutoTileManager = createAutoTileManager(context);
- mAutoTileManager.init();
- }
-
- @After
- public void tearDown() {
- mAutoTileManager.destroy();
- }
-
- private AutoTileManager createAutoTileManager(
- Context context,
- AutoAddTracker.Builder autoAddTrackerBuilder,
- HotspotController hotspotController,
- DataSaverController dataSaverController,
- ManagedProfileController managedProfileController,
- NightDisplayListenerModule.Builder nightDisplayListenerBuilder,
- CastController castController,
- ReduceBrightColorsController reduceBrightColorsController,
- DeviceControlsController deviceControlsController,
- WalletController walletController,
- SafetyController safetyController,
- @Named(RBC_AVAILABLE) boolean isReduceBrightColorsAvailable) {
- return new AutoTileManager(context, autoAddTrackerBuilder, mQsHost,
- Handler.createAsync(TestableLooper.get(this).getLooper()),
- mSecureSettings,
- hotspotController,
- dataSaverController,
- managedProfileController,
- mNightDisplayListenerBuilder,
- castController,
- reduceBrightColorsController,
- deviceControlsController,
- walletController,
- safetyController,
- isReduceBrightColorsAvailable);
- }
-
- private AutoTileManager createAutoTileManager(Context context) {
- return createAutoTileManager(context, mAutoAddTrackerBuilder, mHotspotController,
- mDataSaverController, mManagedProfileController, mNightDisplayListenerBuilder,
- mCastController, mReduceBrightColorsController, mDeviceControlsController,
- mWalletController, mSafetyController, mIsReduceBrightColorsAvailable);
- }
-
- @Test
- public void testCreatedAutoTileManagerIsNotInitialized() {
- AutoAddTracker.Builder builder = mock(AutoAddTracker.Builder.class, Answers.RETURNS_SELF);
- AutoAddTracker tracker = mock(AutoAddTracker.class);
- when(builder.build()).thenReturn(tracker);
- HotspotController hC = mock(HotspotController.class);
- DataSaverController dSC = mock(DataSaverController.class);
- ManagedProfileController mPC = mock(ManagedProfileController.class);
- NightDisplayListenerModule.Builder nDSB = mock(NightDisplayListenerModule.Builder.class);
- CastController cC = mock(CastController.class);
- ReduceBrightColorsController rBC = mock(ReduceBrightColorsController.class);
- DeviceControlsController dCC = mock(DeviceControlsController.class);
- WalletController wC = mock(WalletController.class);
- SafetyController sC = mock(SafetyController.class);
-
- AutoTileManager manager =
- createAutoTileManager(mock(Context.class), builder, hC, dSC, mPC, nDSB, cC, rBC,
- dCC, wC, sC, true);
-
- verify(tracker, never()).initialize();
- verify(hC, never()).addCallback(any());
- verify(dSC, never()).addCallback(any());
- verify(mPC, never()).addCallback(any());
- verifyNoMoreInteractions(nDSB);
- verify(cC, never()).addCallback(any());
- verify(rBC, never()).addCallback(any());
- verify(dCC, never()).setCallback(any());
- verify(wC, never()).getWalletPosition();
- verify(sC, never()).addCallback(any());
- assertNull(manager.getSecureSettingForKey(TEST_SETTING));
- assertNull(manager.getSecureSettingForKey(TEST_SETTING_COMPONENT));
- }
-
- @Test
- public void testChangeUserWhenNotInitializedThrows() {
- AutoTileManager manager = createAutoTileManager(mock(Context.class));
-
- try {
- manager.changeUser(UserHandle.of(USER + 1));
- fail();
- } catch (Exception e) {
- // This should throw and take this path
- }
- }
-
- @Test
- public void testChangeUserCallbacksStoppedAndStarted() throws Exception {
- TestableLooper.get(this).runWithLooper(() ->
- mAutoTileManager.changeUser(UserHandle.of(USER + 1))
- );
-
- InOrder inOrderHotspot = inOrder(mHotspotController);
- inOrderHotspot.verify(mHotspotController).removeCallback(any());
- inOrderHotspot.verify(mHotspotController).addCallback(any());
-
- InOrder inOrderDataSaver = inOrder(mDataSaverController);
- inOrderDataSaver.verify(mDataSaverController).removeCallback(any());
- inOrderDataSaver.verify(mDataSaverController).addCallback(any());
-
- InOrder inOrderManagedProfile = inOrder(mManagedProfileController);
- inOrderManagedProfile.verify(mManagedProfileController).removeCallback(any());
- inOrderManagedProfile.verify(mManagedProfileController).addCallback(any());
-
- if (ColorDisplayManager.isNightDisplayAvailable(mContext)) {
- InOrder inOrderNightDisplay = inOrder(mNightDisplayListener);
- inOrderNightDisplay.verify(mNightDisplayListener).setCallback(isNull());
- inOrderNightDisplay.verify(mNightDisplayListener).setCallback(isNotNull());
- }
-
- InOrder inOrderReduceBrightColors = inOrder(mReduceBrightColorsController);
- inOrderReduceBrightColors.verify(mReduceBrightColorsController).removeCallback(any());
- inOrderReduceBrightColors.verify(mReduceBrightColorsController).addCallback(any());
-
- InOrder inOrderCast = inOrder(mCastController);
- inOrderCast.verify(mCastController).removeCallback(any());
- inOrderCast.verify(mCastController).addCallback(any());
-
- InOrder inOrderDevices = inOrder(mDeviceControlsController);
- inOrderDevices.verify(mDeviceControlsController).removeCallback();
- inOrderDevices.verify(mDeviceControlsController).setCallback(any());
-
- verify(mWalletController, times(2)).getWalletPosition();
-
- InOrder inOrderSafety = inOrder(mSafetyController);
- inOrderSafety.verify(mSafetyController).removeCallback(any());
- inOrderSafety.verify(mSafetyController).addCallback(any());
-
- UserSettingObserver setting = mAutoTileManager.getSecureSettingForKey(TEST_SETTING);
- assertEquals(USER + 1, setting.getCurrentUser());
- assertTrue(setting.isListening());
- }
-
- @Test
- public void testChangeUserSomeCallbacksNotAdded() throws Exception {
- when(mAutoAddTracker.isAdded("hotspot")).thenReturn(true);
- when(mAutoAddTracker.isAdded("work")).thenReturn(true);
- when(mAutoAddTracker.isAdded("cast")).thenReturn(true);
- when(mAutoAddTracker.isAdded(TEST_SPEC)).thenReturn(true);
-
- TestableLooper.get(this).runWithLooper(() ->
- mAutoTileManager.changeUser(UserHandle.of(USER + 1))
- );
-
- verify(mAutoAddTracker).changeUser(UserHandle.of(USER + 1));
-
- InOrder inOrderHotspot = inOrder(mHotspotController);
- inOrderHotspot.verify(mHotspotController).removeCallback(any());
- inOrderHotspot.verify(mHotspotController, never()).addCallback(any());
-
- InOrder inOrderDataSaver = inOrder(mDataSaverController);
- inOrderDataSaver.verify(mDataSaverController).removeCallback(any());
- inOrderDataSaver.verify(mDataSaverController).addCallback(any());
-
- InOrder inOrderManagedProfile = inOrder(mManagedProfileController);
- inOrderManagedProfile.verify(mManagedProfileController).removeCallback(any());
- inOrderManagedProfile.verify(mManagedProfileController).addCallback(any());
-
- if (ColorDisplayManager.isNightDisplayAvailable(mContext)) {
- InOrder inOrderNightDisplay = inOrder(mNightDisplayListener);
- inOrderNightDisplay.verify(mNightDisplayListener).setCallback(isNull());
- inOrderNightDisplay.verify(mNightDisplayListener).setCallback(isNotNull());
- }
-
- InOrder inOrderReduceBrightColors = inOrder(mReduceBrightColorsController);
- inOrderReduceBrightColors.verify(mReduceBrightColorsController).removeCallback(any());
- inOrderReduceBrightColors.verify(mReduceBrightColorsController).addCallback(any());
-
- InOrder inOrderCast = inOrder(mCastController);
- inOrderCast.verify(mCastController).removeCallback(any());
- inOrderCast.verify(mCastController, never()).addCallback(any());
-
- InOrder inOrderDevices = inOrder(mDeviceControlsController);
- inOrderDevices.verify(mDeviceControlsController).removeCallback();
- inOrderDevices.verify(mDeviceControlsController).setCallback(any());
-
- verify(mWalletController, times(2)).getWalletPosition();
-
- InOrder inOrderSafety = inOrder(mSafetyController);
- inOrderSafety.verify(mSafetyController).removeCallback(any());
- inOrderSafety.verify(mSafetyController).addCallback(any());
-
- UserSettingObserver setting = mAutoTileManager.getSecureSettingForKey(TEST_SETTING);
- assertEquals(USER + 1, setting.getCurrentUser());
- assertFalse(setting.isListening());
- }
-
- @Test
- public void testGetCurrentUserId() throws Exception {
- assertEquals(USER, mAutoTileManager.getCurrentUserId());
-
- TestableLooper.get(this).runWithLooper(() ->
- mAutoTileManager.changeUser(UserHandle.of(USER + 100))
- );
-
- assertEquals(USER + 100, mAutoTileManager.getCurrentUserId());
- }
-
- @Test
- public void nightTileAdded_whenActivated() {
- if (!ColorDisplayManager.isNightDisplayAvailable(mContext)) {
- return;
- }
- mAutoTileManager.mNightDisplayCallback.onActivated(true);
- verify(mQsHost).addTile("night");
- }
-
- @Test
- public void nightTileNotAdded_whenDeactivated() {
- if (!ColorDisplayManager.isNightDisplayAvailable(mContext)) {
- return;
- }
- mAutoTileManager.mNightDisplayCallback.onActivated(false);
- verify(mQsHost, never()).addTile("night");
- }
-
- @Test
- public void nightTileAdded_whenNightModeTwilight() {
- if (!ColorDisplayManager.isNightDisplayAvailable(mContext)) {
- return;
- }
- mAutoTileManager.mNightDisplayCallback.onAutoModeChanged(
- ColorDisplayManager.AUTO_MODE_TWILIGHT);
- verify(mQsHost).addTile("night");
- }
-
- @Test
- public void nightTileAdded_whenNightModeCustom() {
- if (!ColorDisplayManager.isNightDisplayAvailable(mContext)) {
- return;
- }
- mAutoTileManager.mNightDisplayCallback.onAutoModeChanged(
- ColorDisplayManager.AUTO_MODE_CUSTOM_TIME);
- verify(mQsHost).addTile("night");
- }
-
- @Test
- public void nightTileNotAdded_whenNightModeDisabled() {
- if (!ColorDisplayManager.isNightDisplayAvailable(mContext)) {
- return;
- }
- mAutoTileManager.mNightDisplayCallback.onAutoModeChanged(
- ColorDisplayManager.AUTO_MODE_DISABLED);
- verify(mQsHost, never()).addTile("night");
- }
-
- @Test
- public void reduceBrightColorsTileAdded_whenActivated() {
- mAutoTileManager.mReduceBrightColorsCallback.onActivated(true);
- verify(mQsHost).addTile("reduce_brightness");
- }
-
- @Test
- public void reduceBrightColorsTileNotAdded_whenDeactivated() {
- mAutoTileManager.mReduceBrightColorsCallback.onActivated(false);
- verify(mQsHost, never()).addTile("reduce_brightness");
- }
-
- private static List<CastDevice> buildFakeCastDevice(boolean isCasting) {
- CastDevice.CastState state = isCasting
- ? CastDevice.CastState.Connected
- : CastDevice.CastState.Disconnected;
- return Collections.singletonList(
- new CastDevice(
- "id",
- /* name= */ null,
- /* description= */ null,
- /* state= */ state,
- /* origin= */ CastDevice.CastOrigin.MediaProjection,
- /* tag= */ null));
- }
-
- @Test
- public void castTileAdded_whenDeviceIsCasting() {
- doReturn(buildFakeCastDevice(true)).when(mCastController).getCastDevices();
- mAutoTileManager.mCastCallback.onCastDevicesChanged();
- verify(mQsHost).addTile("cast");
- }
-
- @Test
- public void castTileNotAdded_whenDeviceIsNotCasting() {
- doReturn(buildFakeCastDevice(false)).when(mCastController).getCastDevices();
- mAutoTileManager.mCastCallback.onCastDevicesChanged();
- verify(mQsHost, never()).addTile("cast");
- }
-
- @Test
- public void testSettingTileAdded_onChanged() {
- changeValue(TEST_SETTING, 1);
- verify(mAutoAddTracker).setTileAdded(TEST_SPEC);
- verify(mQsHost).addTile(TEST_SPEC);
- }
-
- @Test
- public void testSettingTileAddedComponentAtEnd_onChanged() {
- changeValue(TEST_SETTING_COMPONENT, 1);
- verify(mAutoAddTracker).setTileAdded(TEST_CUSTOM_SPEC);
- verify(mQsHost).addTile(ComponentName.unflattenFromString(TEST_COMPONENT)
- , /* end */ true);
- }
-
- @Test
- public void testSettingTileAdded_onlyOnce() {
- changeValue(TEST_SETTING, 1);
- changeValue(TEST_SETTING, 2);
- verify(mAutoAddTracker).setTileAdded(TEST_SPEC);
- verify(mQsHost).addTile(TEST_SPEC);
- }
-
- @Test
- public void testSettingTileNotAdded_onChangedTo0() {
- changeValue(TEST_SETTING, 0);
- verify(mAutoAddTracker, never()).setTileAdded(TEST_SPEC);
- verify(mQsHost, never()).addTile(TEST_SPEC);
- }
-
- @Test
- public void testSettingTileNotAdded_ifPreviouslyAdded() {
- when(mAutoAddTracker.isAdded(TEST_SPEC)).thenReturn(true);
-
- changeValue(TEST_SETTING, 1);
- verify(mAutoAddTracker, never()).setTileAdded(TEST_SPEC);
- verify(mQsHost, never()).addTile(TEST_SPEC);
- }
-
- @Test
- public void testSafetyTileNotAdded_ifPreviouslyAdded() {
- ComponentName safetyComponent = CustomTile.getComponentFromSpec(TEST_CUSTOM_SAFETY_SPEC);
- mAutoTileManager.init();
- verify(mQsHost, times(1)).addTile(safetyComponent, true);
- when(mAutoAddTracker.isAdded(TEST_CUSTOM_SAFETY_SPEC)).thenReturn(true);
- mAutoTileManager.init();
- verify(mQsHost, times(1)).addTile(safetyComponent, true);
- }
-
- @Test
- public void testSafetyTileAdded_onUserChange() {
- ComponentName safetyComponent = CustomTile.getComponentFromSpec(TEST_CUSTOM_SAFETY_SPEC);
- mAutoTileManager.init();
- verify(mQsHost, times(1)).addTile(safetyComponent, true);
- when(mAutoAddTracker.isAdded(TEST_CUSTOM_SAFETY_SPEC)).thenReturn(false);
- mAutoTileManager.changeUser(UserHandle.of(USER + 1));
- verify(mQsHost, times(2)).addTile(safetyComponent, true);
- }
-
- @Test
- public void testSafetyTileRemoved_onSafetyCenterDisable() {
- ComponentName safetyComponent = CustomTile.getComponentFromSpec(TEST_CUSTOM_SAFETY_SPEC);
- mAutoTileManager.init();
- when(mAutoAddTracker.isAdded(TEST_CUSTOM_SAFETY_SPEC)).thenReturn(true);
- mAutoTileManager.mSafetyCallback.onSafetyCenterEnableChanged(false);
- verify(mQsHost, times(1)).removeTile(TEST_CUSTOM_SAFETY_SPEC);
- }
-
- @Test
- public void testSafetyTileAdded_onSafetyCenterEnable() {
- ComponentName safetyComponent = CustomTile.getComponentFromSpec(TEST_CUSTOM_SAFETY_SPEC);
- mAutoTileManager.init();
- verify(mQsHost, times(1)).addTile(safetyComponent, true);
- mAutoTileManager.mSafetyCallback.onSafetyCenterEnableChanged(false);
- mAutoTileManager.mSafetyCallback.onSafetyCenterEnableChanged(true);
- verify(mQsHost, times(2)).addTile(safetyComponent, true);
- }
-
- @Test
- public void managedProfileAdded_tileAdded() {
- when(mAutoAddTracker.isAdded(eq("work"))).thenReturn(false);
- when(mAutoAddTracker.getRestoredTilePosition(eq("work"))).thenReturn(2);
- 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(mQsHost, times(1)).addTile(eq("work"), eq(2));
- 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(mQsHost, times(1)).removeTile(eq("work"));
- verify(mAutoAddTracker, times(1)).setTileRemoved(eq("work"));
- }
-
- @Test
- public void testAddControlsTileIfNotPresent() {
- String spec = DEVICE_CONTROLS;
- when(mAutoAddTracker.isAdded(eq(spec))).thenReturn(false);
- when(mQsHost.getTiles()).thenReturn(new ArrayList<>());
-
- mAutoTileManager.init();
- ArgumentCaptor<DeviceControlsController.Callback> captor =
- ArgumentCaptor.forClass(DeviceControlsController.Callback.class);
-
- verify(mDeviceControlsController).setCallback(captor.capture());
-
- captor.getValue().onControlsUpdate(3);
- verify(mQsHost).addTile(spec, 3);
- verify(mAutoAddTracker).setTileAdded(spec);
- }
-
- @Test
- public void testDontAddControlsTileIfPresent() {
- String spec = DEVICE_CONTROLS;
- when(mAutoAddTracker.isAdded(eq(spec))).thenReturn(false);
- when(mQsHost.getTiles()).thenReturn(new ArrayList<>());
-
- mAutoTileManager.init();
- ArgumentCaptor<DeviceControlsController.Callback> captor =
- ArgumentCaptor.forClass(DeviceControlsController.Callback.class);
-
- verify(mDeviceControlsController).setCallback(captor.capture());
-
- captor.getValue().removeControlsAutoTracker();
- verify(mQsHost, never()).addTile(spec, 3);
- verify(mAutoAddTracker, never()).setTileAdded(spec);
- verify(mAutoAddTracker).setTileRemoved(spec);
- }
-
- @Test
- public void testRemoveControlsTileFromTrackerWhenRequested() {
- String spec = "controls";
- when(mAutoAddTracker.isAdded(eq(spec))).thenReturn(true);
- QSTile mockTile = mock(QSTile.class);
- when(mockTile.getTileSpec()).thenReturn(spec);
- when(mQsHost.getTiles()).thenReturn(List.of(mockTile));
-
- mAutoTileManager.init();
- ArgumentCaptor<DeviceControlsController.Callback> captor =
- ArgumentCaptor.forClass(DeviceControlsController.Callback.class);
-
- verify(mDeviceControlsController).setCallback(captor.capture());
-
- captor.getValue().onControlsUpdate(3);
- verify(mQsHost, never()).addTile(spec, 3);
- verify(mAutoAddTracker, never()).setTileAdded(spec);
- }
-
-
- @Test
- public void testEmptyArray_doesNotCrash() {
- mContext.getOrCreateTestableResources().addOverride(
- R.array.config_quickSettingsAutoAdd, new String[0]);
- createAutoTileManager(mContext).destroy();
- }
-
- @Test
- public void testMissingConfig_doesNotCrash() {
- mContext.getOrCreateTestableResources().addOverride(
- R.array.config_quickSettingsAutoAdd, null);
- createAutoTileManager(mContext).destroy();
- }
-
- @Test
- public void testUserChange_newNightDisplayListenerCreated() {
- UserHandle newUser = UserHandle.of(1000);
- mAutoTileManager.changeUser(newUser);
- InOrder inOrder = inOrder(mNightDisplayListenerBuilder);
- inOrder.verify(mNightDisplayListenerBuilder).setUser(newUser.getIdentifier());
- inOrder.verify(mNightDisplayListenerBuilder).build();
- }
-
- // Will only notify if it's listening
- private void changeValue(String key, int value) {
- mSecureSettings.putIntForUser(key, value, USER);
- TestableLooper.get(this).processAllMessages();
- }
-}