diff options
| author | 2021-05-27 22:33:27 +0000 | |
|---|---|---|
| committer | 2021-05-27 22:33:27 +0000 | |
| commit | 84d8829d7296b6b9948d8ce12e1b899cd0a3bf4d (patch) | |
| tree | 2c0c1ef20f4dee71b581157a40d560740abce194 | |
| parent | a3c01dcf169f40274ee10985eb2797ff1c0b8318 (diff) | |
| parent | 8cf0a2a2922ae696bc2127b4d4dd467cafbdc809 (diff) | |
Merge changes I77c61f74,I569123ca,Idf70d205,I308ea00b
* changes:
setCurrentState(DESTROYED) called from main thread
Enforce setCurrentState calls are on main thread
Refactor QSTileImpl and remove Dependency.get
QSTileImpl is set to DESTROYED when handleDestroy
33 files changed, 794 insertions, 200 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemServicesModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemServicesModule.java index 8472b1b54c48..4a5d142c35e8 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/SystemServicesModule.java +++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemServicesModule.java @@ -39,6 +39,7 @@ import android.content.pm.ShortcutManager; import android.content.res.Resources; import android.hardware.SensorManager; import android.hardware.SensorPrivacyManager; +import android.hardware.display.ColorDisplayManager; import android.hardware.display.DisplayManager; import android.media.AudioManager; import android.media.MediaRouter2Manager; @@ -107,6 +108,12 @@ public class SystemServicesModule { @Provides @Singleton + static ColorDisplayManager provideColorDisplayManager(Context context) { + return context.getSystemService(ColorDisplayManager.class); + } + + @Provides + @Singleton static ConnectivityManager provideConnectivityManagager(Context context) { return context.getSystemService(ConnectivityManager.class); } diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSHost.java b/packages/SystemUI/src/com/android/systemui/qs/QSHost.java index 1e8c4d86da36..290ab8594fc0 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSHost.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSHost.java @@ -20,7 +20,6 @@ import com.android.internal.logging.InstanceId; import com.android.internal.logging.UiEventLogger; import com.android.systemui.plugins.qs.QSTile; import com.android.systemui.qs.external.TileServices; -import com.android.systemui.qs.logging.QSLogger; import java.util.Collection; @@ -31,7 +30,6 @@ public interface QSHost { void openPanels(); Context getContext(); Context getUserContext(); - QSLogger getQSLogger(); UiEventLogger getUiEventLogger(); Collection<QSTile> getTiles(); void addCallback(Callback callback); diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java b/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java index 1f3967c03a41..3b16a4ec1c38 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java @@ -179,10 +179,6 @@ public class QSTileHost implements QSHost, Tunable, PluginListener<QSFactory>, D onTuningChanged(TILES_SETTING, value); } - public QSLogger getQSLogger() { - return mQSLogger; - } - @Override public UiEventLogger getUiEventLogger() { return mUiEventLogger; diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java b/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java index 30e0a766de37..19c7b6cefc5d 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java @@ -29,7 +29,9 @@ import android.graphics.drawable.Drawable; import android.metrics.LogMaker; import android.net.Uri; import android.os.Binder; +import android.os.Handler; import android.os.IBinder; +import android.os.Looper; import android.os.RemoteException; import android.provider.Settings; import android.service.quicksettings.IQSTileService; @@ -42,16 +44,27 @@ import android.view.IWindowManager; import android.view.WindowManagerGlobal; import android.widget.Switch; +import androidx.annotation.NonNull; + +import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.systemui.Dependency; +import com.android.systemui.dagger.qualifiers.Background; +import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.qs.QSTile.State; +import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.qs.QSHost; import com.android.systemui.qs.external.TileLifecycleManager.TileChangeListener; +import com.android.systemui.qs.logging.QSLogger; import com.android.systemui.qs.tileimpl.QSTileImpl; import java.util.Objects; +import javax.inject.Inject; + +import dagger.Lazy; + public class CustomTile extends QSTileImpl<State> implements TileChangeListener { public static final String PREFIX = "custom("; @@ -79,8 +92,19 @@ public class CustomTile extends QSTileImpl<State> implements TileChangeListener private boolean mIsTokenGranted; private boolean mIsShowingDialog; - private CustomTile(QSHost host, String action, Context userContext) { - super(host); + private CustomTile( + QSHost host, + Looper backgroundLooper, + Handler mainHandler, + MetricsLogger metricsLogger, + StatusBarStateController statusBarStateController, + ActivityStarter activityStarter, + QSLogger qsLogger, + String action, + Context userContext + ) { + super(host, backgroundLooper, mainHandler, metricsLogger, statusBarStateController, + activityStarter, qsLogger); mWindowManager = WindowManagerGlobal.getWindowManagerService(); mComponent = ComponentName.unflattenFromString(action); mTile = new Tile(); @@ -397,7 +421,7 @@ public class CustomTile extends QSTileImpl<State> implements TileChangeListener return ComponentName.unflattenFromString(action); } - public static CustomTile create(QSHost host, String spec, Context userContext) { + private static String getAction(String spec) { if (spec == null || !spec.startsWith(PREFIX) || !spec.endsWith(")")) { throw new IllegalArgumentException("Bad custom tile spec: " + spec); } @@ -405,6 +429,81 @@ public class CustomTile extends QSTileImpl<State> implements TileChangeListener if (action.isEmpty()) { throw new IllegalArgumentException("Empty custom tile spec action"); } - return new CustomTile(host, action, userContext); + return action; + } + + /** + * Create a {@link CustomTile} for a given spec and user. + * + * @param builder including injected common dependencies. + * @param spec as provided by {@link CustomTile#toSpec} + * @param userContext context for the user that is creating this tile. + * @return a new {@link CustomTile} + */ + public static CustomTile create(Builder builder, String spec, Context userContext) { + return builder + .setSpec(spec) + .setUserContext(userContext) + .build(); + } + + public static class Builder { + final Lazy<QSHost> mQSHostLazy; + final Looper mBackgroundLooper; + final Handler mMainHandler; + final MetricsLogger mMetricsLogger; + final StatusBarStateController mStatusBarStateController; + final ActivityStarter mActivityStarter; + final QSLogger mQSLogger; + + Context mUserContext; + String mSpec = ""; + + @Inject + public Builder( + Lazy<QSHost> hostLazy, + @Background Looper backgroundLooper, + @Main Handler mainHandler, + MetricsLogger metricsLogger, + StatusBarStateController statusBarStateController, + ActivityStarter activityStarter, + QSLogger qsLogger + ) { + mQSHostLazy = hostLazy; + mBackgroundLooper = backgroundLooper; + mMainHandler = mainHandler; + mMetricsLogger = metricsLogger; + mStatusBarStateController = statusBarStateController; + mActivityStarter = activityStarter; + mQSLogger = qsLogger; + } + + Builder setSpec(@NonNull String spec) { + mSpec = spec; + return this; + } + + Builder setUserContext(@NonNull Context userContext) { + mUserContext = userContext; + return this; + } + + CustomTile build() { + if (mUserContext == null) { + throw new NullPointerException("UserContext cannot be null"); + } + String action = getAction(mSpec); + return new CustomTile( + mQSHostLazy.get(), + mBackgroundLooper, + mMainHandler, + mMetricsLogger, + mStatusBarStateController, + mActivityStarter, + mQSLogger, + action, + mUserContext + ); + } } } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java index c182a58a28c4..69a6fe1075c2 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java @@ -80,9 +80,12 @@ public class QSFactoryImpl implements QSFactory { private final Provider<ScreenRecordTile> mScreenRecordTileProvider; private final Lazy<QSHost> mQsHostLazy; + private final Provider<CustomTile.Builder> mCustomTileBuilderProvider; @Inject - public QSFactoryImpl(Lazy<QSHost> qsHostLazy, + public QSFactoryImpl( + Lazy<QSHost> qsHostLazy, + Provider<CustomTile.Builder> customTileBuilderProvider, Provider<WifiTile> wifiTileProvider, Provider<BluetoothTile> bluetoothTileProvider, Provider<CellularTile> cellularTileProvider, @@ -104,6 +107,8 @@ public class QSFactoryImpl implements QSFactory { Provider<UiModeNightTile> uiModeNightTileProvider, Provider<ScreenRecordTile> screenRecordTileProvider) { mQsHostLazy = qsHostLazy; + mCustomTileBuilderProvider = customTileBuilderProvider; + mWifiTileProvider = wifiTileProvider; mBluetoothTileProvider = bluetoothTileProvider; mCellularTileProvider = cellularTileProvider; @@ -179,8 +184,8 @@ public class QSFactoryImpl implements QSFactory { // Custom tiles if (tileSpec.startsWith(CustomTile.PREFIX)) { - return CustomTile.create(mQsHostLazy.get(), tileSpec, - mQsHostLazy.get().getUserContext()); + return CustomTile.create( + mCustomTileBuilderProvider.get(), tileSpec, mQsHostLazy.get().getUserContext()); } // Debug tiles. diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java index 795d0627c447..255513a31c75 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java @@ -14,6 +14,8 @@ package com.android.systemui.qs.tileimpl; +import static androidx.lifecycle.Lifecycle.State.CREATED; +import static androidx.lifecycle.Lifecycle.State.DESTROYED; import static androidx.lifecycle.Lifecycle.State.RESUMED; import static androidx.lifecycle.Lifecycle.State.STARTED; @@ -54,7 +56,6 @@ import com.android.internal.logging.UiEventLogger; import com.android.settingslib.RestrictedLockUtils; import com.android.settingslib.RestrictedLockUtilsInternal; import com.android.settingslib.Utils; -import com.android.systemui.Dependency; import com.android.systemui.Dumpable; import com.android.systemui.Prefs; import com.android.systemui.plugins.ActivityStarter; @@ -92,12 +93,12 @@ public abstract class QSTileImpl<TState extends State> implements QSTile, Lifecy protected final QSHost mHost; protected final Context mContext; // @NonFinalForTesting - protected H mHandler = new H(Dependency.get(Dependency.BG_LOOPER)); - protected final Handler mUiHandler = new Handler(Looper.getMainLooper()); + protected final H mHandler; + protected final Handler mUiHandler; private final ArraySet<Object> mListeners = new ArraySet<>(); - private final MetricsLogger mMetricsLogger = Dependency.get(MetricsLogger.class); - private final StatusBarStateController - mStatusBarStateController = Dependency.get(StatusBarStateController.class); + private final MetricsLogger mMetricsLogger; + private final StatusBarStateController mStatusBarStateController; + protected final ActivityStarter mActivityStarter; private final UiEventLogger mUiEventLogger; private final QSLogger mQSLogger; @@ -150,14 +151,30 @@ public abstract class QSTileImpl<TState extends State> implements QSTile, Lifecy */ abstract public int getMetricsCategory(); - protected QSTileImpl(QSHost host) { + protected QSTileImpl( + QSHost host, + Looper backgroundLooper, + Handler mainHandler, + MetricsLogger metricsLogger, + StatusBarStateController statusBarStateController, + ActivityStarter activityStarter, + QSLogger qsLogger + ) { mHost = host; mContext = host.getContext(); mInstanceId = host.getNewInstanceId(); + mUiEventLogger = host.getUiEventLogger(); + + mUiHandler = mainHandler; + mHandler = new H(backgroundLooper); + mQSLogger = qsLogger; + mMetricsLogger = metricsLogger; + mStatusBarStateController = statusBarStateController; + mActivityStarter = activityStarter; + mState = newTileState(); mTmpState = newTileState(); - mQSLogger = host.getQSLogger(); - mUiEventLogger = host.getUiEventLogger(); + mUiHandler.post(() -> mLifecycle.setCurrentState(CREATED)); } protected final void resetStates() { @@ -357,8 +374,7 @@ public abstract class QSTileImpl<TState extends State> implements QSTile, Lifecy * {@link QSTileImpl#getLongClickIntent} */ protected void handleLongClick() { - Dependency.get(ActivityStarter.class).postStartActivityDismissingKeyguard( - getLongClickIntent(), 0); + mActivityStarter.postStartActivityDismissingKeyguard(getLongClickIntent(), 0); } /** @@ -437,15 +453,24 @@ public abstract class QSTileImpl<TState extends State> implements QSTile, Lifecy if (listening) { if (mListeners.add(listener) && mListeners.size() == 1) { if (DEBUG) Log.d(TAG, "handleSetListening true"); - mLifecycle.setCurrentState(RESUMED); handleSetListening(listening); - refreshState(); // Ensure we get at least one refresh after listening. + mUiHandler.post(() -> { + // This tile has been destroyed, the state should not change anymore and we + // should not refresh it anymore. + if (mLifecycle.getCurrentState().equals(DESTROYED)) return; + mLifecycle.setCurrentState(RESUMED); + refreshState(); // Ensure we get at least one refresh after listening. + }); } } else { if (mListeners.remove(listener) && mListeners.size() == 0) { if (DEBUG) Log.d(TAG, "handleSetListening false"); - mLifecycle.setCurrentState(STARTED); handleSetListening(listening); + mUiHandler.post(() -> { + // This tile has been destroyed, the state should not change anymore. + if (mLifecycle.getCurrentState().equals(DESTROYED)) return; + mLifecycle.setCurrentState(STARTED); + }); } } updateIsFullQs(); @@ -472,9 +497,14 @@ public abstract class QSTileImpl<TState extends State> implements QSTile, Lifecy mQSLogger.logTileDestroyed(mTileSpec, "Handle destroy"); if (mListeners.size() != 0) { handleSetListening(false); + mListeners.clear(); } mCallbacks.clear(); mHandler.removeCallbacksAndMessages(null); + // This will force it to be removed from all controllers that may have it registered. + mUiHandler.post(() -> { + mLifecycle.setCurrentState(DESTROYED); + }); } protected void checkIfRestrictionEnforcedByAdminOnly(State state, String userRestriction) { @@ -530,7 +560,8 @@ public abstract class QSTileImpl<TState extends State> implements QSTile, Lifecy private static final int REMOVE_CALLBACKS = 11; private static final int REMOVE_CALLBACK = 12; private static final int SET_LISTENING = 13; - private static final int STALE = 14; + @VisibleForTesting + protected static final int STALE = 14; @VisibleForTesting protected H(Looper looper) { @@ -555,8 +586,7 @@ public abstract class QSTileImpl<TState extends State> implements QSTile, Lifecy if (mState.disabledByPolicy) { Intent intent = RestrictedLockUtils.getShowAdminSupportDetailsIntent( mContext, mEnforcedAdmin); - Dependency.get(ActivityStarter.class).postStartActivityDismissingKeyguard( - intent, 0); + mActivityStarter.postStartActivityDismissingKeyguard(intent, 0); } else { handleClick(); } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java index b24fdbfc562f..b8485907c519 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java @@ -21,6 +21,8 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.net.ConnectivityManager; +import android.os.Handler; +import android.os.Looper; import android.os.UserManager; import android.provider.Settings; import android.provider.Settings.Global; @@ -33,33 +35,50 @@ import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.systemui.R; import com.android.systemui.broadcast.BroadcastDispatcher; +import com.android.systemui.dagger.qualifiers.Background; +import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.qs.QSTile.BooleanState; +import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.qs.GlobalSetting; import com.android.systemui.qs.QSHost; +import com.android.systemui.qs.logging.QSLogger; import com.android.systemui.qs.tileimpl.QSTileImpl; import javax.inject.Inject; +import dagger.Lazy; + /** Quick settings tile: Airplane mode **/ public class AirplaneModeTile extends QSTileImpl<BooleanState> { private final Icon mIcon = ResourceIcon.get(com.android.internal.R.drawable.ic_qs_airplane); private final GlobalSetting mSetting; - private final ActivityStarter mActivityStarter; private final BroadcastDispatcher mBroadcastDispatcher; + private final Lazy<ConnectivityManager> mLazyConnectivityManager; private boolean mListening; @Inject - public AirplaneModeTile(QSHost host, ActivityStarter activityStarter, - BroadcastDispatcher broadcastDispatcher) { - super(host); - mActivityStarter = activityStarter; + public AirplaneModeTile( + QSHost host, + @Background Looper backgroundLooper, + @Main Handler mainHandler, + MetricsLogger metricsLogger, + StatusBarStateController statusBarStateController, + ActivityStarter activityStarter, + QSLogger qsLogger, + BroadcastDispatcher broadcastDispatcher, + Lazy<ConnectivityManager> lazyConnectivityManager + ) { + super(host, backgroundLooper, mainHandler, metricsLogger, statusBarStateController, + activityStarter, qsLogger); mBroadcastDispatcher = broadcastDispatcher; + mLazyConnectivityManager = lazyConnectivityManager; mSetting = new GlobalSetting(mContext, mHandler, Global.AIRPLANE_MODE_ON) { @Override protected void handleValueChanged(int value) { + // mHandler is the background handler so calling this is OK handleRefreshState(value); } }; @@ -83,9 +102,7 @@ public class AirplaneModeTile extends QSTileImpl<BooleanState> { } private void setEnabled(boolean enabled) { - final ConnectivityManager mgr = - (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE); - mgr.setAirplaneMode(enabled); + mLazyConnectivityManager.get().setAirplaneMode(enabled); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java index 7150e4350304..c64fc50b8237 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java @@ -16,16 +16,24 @@ package com.android.systemui.qs.tiles; import android.content.Intent; +import android.os.Handler; +import android.os.Looper; import android.provider.Settings.Secure; import android.service.quicksettings.Tile; import android.widget.Switch; import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.systemui.R; +import com.android.systemui.dagger.qualifiers.Background; +import com.android.systemui.dagger.qualifiers.Main; +import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.qs.QSTile.BooleanState; +import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.qs.QSHost; import com.android.systemui.qs.SecureSetting; +import com.android.systemui.qs.logging.QSLogger; import com.android.systemui.qs.tileimpl.QSTileImpl; import com.android.systemui.statusbar.policy.BatteryController; @@ -46,8 +54,18 @@ public class BatterySaverTile extends QSTileImpl<BooleanState> implements private Icon mIcon = ResourceIcon.get(com.android.internal.R.drawable.ic_qs_battery_saver); @Inject - public BatterySaverTile(QSHost host, BatteryController batteryController) { - super(host); + public BatterySaverTile( + QSHost host, + @Background Looper backgroundLooper, + @Main Handler mainHandler, + MetricsLogger metricsLogger, + StatusBarStateController statusBarStateController, + ActivityStarter activityStarter, + QSLogger qsLogger, + BatteryController batteryController + ) { + super(host, backgroundLooper, mainHandler, metricsLogger, statusBarStateController, + activityStarter, qsLogger); mBatteryController = batteryController; mBatteryController.observe(getLifecycle(), this); int currentUser = host.getUserContext().getUserId(); @@ -55,6 +73,7 @@ public class BatterySaverTile extends QSTileImpl<BooleanState> implements currentUser) { @Override protected void handleValueChanged(int value, boolean observedChange) { + // mHandler is the background handler so calling this is OK handleRefreshState(null); } }; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java index 888c7ab2c312..56083c43e1b6 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java @@ -24,6 +24,8 @@ import android.bluetooth.BluetoothProfile; import android.content.Context; import android.content.Intent; import android.graphics.drawable.Drawable; +import android.os.Handler; +import android.os.Looper; import android.provider.Settings; import android.service.quicksettings.Tile; import android.text.TextUtils; @@ -37,12 +39,16 @@ import com.android.settingslib.Utils; import com.android.settingslib.bluetooth.CachedBluetoothDevice; import com.android.settingslib.graph.BluetoothDeviceLayerDrawable; import com.android.systemui.R; +import com.android.systemui.dagger.qualifiers.Background; +import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.qs.DetailAdapter; import com.android.systemui.plugins.qs.QSTile.BooleanState; +import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.qs.QSDetailItems; import com.android.systemui.qs.QSDetailItems.Item; import com.android.systemui.qs.QSHost; +import com.android.systemui.qs.logging.QSLogger; import com.android.systemui.qs.tileimpl.QSTileImpl; import com.android.systemui.statusbar.policy.BluetoothController; @@ -58,15 +64,21 @@ public class BluetoothTile extends QSTileImpl<BooleanState> { private final BluetoothController mController; private final BluetoothDetailAdapter mDetailAdapter; - private final ActivityStarter mActivityStarter; @Inject - public BluetoothTile(QSHost host, - BluetoothController bluetoothController, - ActivityStarter activityStarter) { - super(host); + public BluetoothTile( + QSHost host, + @Background Looper backgroundLooper, + @Main Handler mainHandler, + MetricsLogger metricsLogger, + StatusBarStateController statusBarStateController, + ActivityStarter activityStarter, + QSLogger qsLogger, + BluetoothController bluetoothController + ) { + super(host, backgroundLooper, mainHandler, metricsLogger, statusBarStateController, + activityStarter, qsLogger); mController = bluetoothController; - mActivityStarter = activityStarter; mDetailAdapter = (BluetoothDetailAdapter) createDetailAdapter(); mController.observe(getLifecycle(), mCallback); } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java index 4b53ae2c6379..56b939df383f 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java @@ -22,6 +22,8 @@ import android.app.Dialog; import android.content.Context; import android.content.Intent; import android.media.MediaRouter.RouteInfo; +import android.os.Handler; +import android.os.Looper; import android.provider.Settings; import android.service.quicksettings.Tile; import android.util.Log; @@ -35,12 +37,16 @@ import com.android.internal.app.MediaRouteDialogPresenter; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.systemui.R; +import com.android.systemui.dagger.qualifiers.Background; +import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.qs.DetailAdapter; import com.android.systemui.plugins.qs.QSTile.BooleanState; +import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.qs.QSDetailItems; import com.android.systemui.qs.QSDetailItems.Item; import com.android.systemui.qs.QSHost; +import com.android.systemui.qs.logging.QSLogger; import com.android.systemui.qs.tileimpl.QSTileImpl; import com.android.systemui.statusbar.phone.SystemUIDialog; import com.android.systemui.statusbar.policy.CastController; @@ -64,20 +70,28 @@ public class CastTile extends QSTileImpl<BooleanState> { private final KeyguardStateController mKeyguard; private final NetworkController mNetworkController; private final Callback mCallback = new Callback(); - private final ActivityStarter mActivityStarter; private Dialog mDialog; private boolean mWifiConnected; @Inject - public CastTile(QSHost host, CastController castController, - KeyguardStateController keyguardStateController, NetworkController networkController, - ActivityStarter activityStarter) { - super(host); + public CastTile( + QSHost host, + @Background Looper backgroundLooper, + @Main Handler mainHandler, + MetricsLogger metricsLogger, + StatusBarStateController statusBarStateController, + ActivityStarter activityStarter, + QSLogger qsLogger, + CastController castController, + KeyguardStateController keyguardStateController, + NetworkController networkController + ) { + super(host, backgroundLooper, mainHandler, metricsLogger, statusBarStateController, + activityStarter, qsLogger); mController = castController; mDetailAdapter = new CastDetailAdapter(); mKeyguard = keyguardStateController; mNetworkController = networkController; - mActivityStarter = activityStarter; mController.observe(this, mCallback); mKeyguard.observe(this, mCallback); mNetworkController.observe(this, mSignalCallback); diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java index 33e98d836d94..f742752d80be 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java @@ -23,6 +23,8 @@ import android.app.AlertDialog.Builder; import android.content.Context; import android.content.Intent; import android.content.res.Resources; +import android.os.Handler; +import android.os.Looper; import android.os.UserHandle; import android.provider.Settings; import android.service.quicksettings.Tile; @@ -40,12 +42,16 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settingslib.net.DataUsageController; import com.android.systemui.Prefs; import com.android.systemui.R; +import com.android.systemui.dagger.qualifiers.Background; +import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.qs.DetailAdapter; import com.android.systemui.plugins.qs.QSIconView; import com.android.systemui.plugins.qs.QSTile.SignalState; +import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.qs.QSHost; import com.android.systemui.qs.SignalTileView; +import com.android.systemui.qs.logging.QSLogger; import com.android.systemui.qs.tileimpl.QSTileImpl; import com.android.systemui.statusbar.phone.SystemUIDialog; import com.android.systemui.statusbar.policy.NetworkController; @@ -63,14 +69,21 @@ public class CellularTile extends QSTileImpl<SignalState> { private final CellularDetailAdapter mDetailAdapter; private final CellSignalCallback mSignalCallback = new CellSignalCallback(); - private final ActivityStarter mActivityStarter; @Inject - public CellularTile(QSHost host, NetworkController networkController, - ActivityStarter activityStarter) { - super(host); + public CellularTile( + QSHost host, + @Background Looper backgroundLooper, + @Main Handler mainHandler, + MetricsLogger metricsLogger, + StatusBarStateController statusBarStateController, + ActivityStarter activityStarter, + QSLogger qsLogger, + NetworkController networkController + ) { + super(host, backgroundLooper, mainHandler, metricsLogger, statusBarStateController, + activityStarter, qsLogger); mController = networkController; - mActivityStarter = activityStarter; mDataController = mController.getMobileDataController(); mDetailAdapter = new CellularDetailAdapter(); mController.observe(getLifecycle(), mSignalCallback); diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java index 9c0030d528e7..131e28535911 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java @@ -17,17 +17,25 @@ package com.android.systemui.qs.tiles; import android.content.Intent; +import android.os.Handler; +import android.os.Looper; import android.provider.Settings; import android.provider.Settings.Secure; import android.service.quicksettings.Tile; import android.widget.Switch; +import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.systemui.R; import com.android.systemui.R.drawable; +import com.android.systemui.dagger.qualifiers.Background; +import com.android.systemui.dagger.qualifiers.Main; +import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.qs.QSTile.BooleanState; +import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.qs.QSHost; import com.android.systemui.qs.SecureSetting; +import com.android.systemui.qs.logging.QSLogger; import com.android.systemui.qs.tileimpl.QSTileImpl; import javax.inject.Inject; @@ -41,13 +49,23 @@ public class ColorInversionTile extends QSTileImpl<BooleanState> { private boolean mListening; @Inject - public ColorInversionTile(QSHost host) { - super(host); - - mSetting = new SecureSetting(mContext, mHandler, + public ColorInversionTile( + QSHost host, + @Background Looper backgroundLooper, + @Main Handler mainHandler, + MetricsLogger metricsLogger, + StatusBarStateController statusBarStateController, + ActivityStarter activityStarter, + QSLogger qsLogger + ) { + super(host, backgroundLooper, mainHandler, metricsLogger, statusBarStateController, + activityStarter, qsLogger); + + mSetting = new SecureSetting(mContext, mainHandler, Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED) { @Override protected void handleValueChanged(int value, boolean observedChange) { + // mHandler is the background handler so calling this is OK handleRefreshState(value); } }; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java index 7ae8fbc928a6..85f12458c33a 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java @@ -16,19 +16,26 @@ package com.android.systemui.qs.tiles; import android.content.DialogInterface.OnClickListener; import android.content.Intent; +import android.os.Handler; +import android.os.Looper; import android.provider.Settings; import android.service.quicksettings.Tile; import android.widget.Switch; +import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.systemui.Prefs; import com.android.systemui.R; +import com.android.systemui.dagger.qualifiers.Background; +import com.android.systemui.dagger.qualifiers.Main; +import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.qs.QSTile.BooleanState; +import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.qs.QSHost; +import com.android.systemui.qs.logging.QSLogger; import com.android.systemui.qs.tileimpl.QSTileImpl; import com.android.systemui.statusbar.phone.SystemUIDialog; import com.android.systemui.statusbar.policy.DataSaverController; -import com.android.systemui.statusbar.policy.NetworkController; import javax.inject.Inject; @@ -38,9 +45,19 @@ public class DataSaverTile extends QSTileImpl<BooleanState> implements private final DataSaverController mDataSaverController; @Inject - public DataSaverTile(QSHost host, NetworkController networkController) { - super(host); - mDataSaverController = networkController.getDataSaverController(); + public DataSaverTile( + QSHost host, + @Background Looper backgroundLooper, + @Main Handler mainHandler, + MetricsLogger metricsLogger, + StatusBarStateController statusBarStateController, + ActivityStarter activityStarter, + QSLogger qsLogger, + DataSaverController dataSaverController + ) { + super(host, backgroundLooper, mainHandler, metricsLogger, statusBarStateController, + activityStarter, qsLogger); + mDataSaverController = dataSaverController; mDataSaverController.observe(getLifecycle(), this); } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java index 9f7b84aa62c1..ec8b1435e201 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java @@ -30,6 +30,8 @@ import android.content.SharedPreferences.OnSharedPreferenceChangeListener; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.net.Uri; +import android.os.Handler; +import android.os.Looper; import android.os.UserManager; import android.provider.Settings; import android.provider.Settings.Global; @@ -53,11 +55,14 @@ import com.android.systemui.Prefs; import com.android.systemui.R; import com.android.systemui.SysUIToast; import com.android.systemui.broadcast.BroadcastDispatcher; +import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.qs.DetailAdapter; import com.android.systemui.plugins.qs.QSTile.BooleanState; +import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.qs.QSHost; +import com.android.systemui.qs.logging.QSLogger; import com.android.systemui.qs.tileimpl.QSTileImpl; import com.android.systemui.statusbar.phone.SystemUIDialog; import com.android.systemui.statusbar.policy.ZenModeController; @@ -79,7 +84,6 @@ public class DndTile extends QSTileImpl<BooleanState> { private final ZenModeController mController; private final DndDetailAdapter mDetailAdapter; - private final ActivityStarter mActivityStarter; private final SharedPreferences mSharedPreferences; private final BroadcastDispatcher mBroadcastDispatcher; @@ -88,12 +92,21 @@ public class DndTile extends QSTileImpl<BooleanState> { private boolean mReceiverRegistered; @Inject - public DndTile(QSHost host, ZenModeController zenModeController, - ActivityStarter activityStarter, BroadcastDispatcher broadcastDispatcher, - @Main SharedPreferences sharedPreferences) { - super(host); + public DndTile( + QSHost host, + @Background Looper backgroundLooper, + @Main Handler mainHandler, + MetricsLogger metricsLogger, + StatusBarStateController statusBarStateController, + ActivityStarter activityStarter, + QSLogger qsLogger, + ZenModeController zenModeController, + BroadcastDispatcher broadcastDispatcher, + @Main SharedPreferences sharedPreferences + ) { + super(host, backgroundLooper, mainHandler, metricsLogger, statusBarStateController, + activityStarter, qsLogger); mController = zenModeController; - mActivityStarter = activityStarter; mSharedPreferences = sharedPreferences; mDetailAdapter = new DndDetailAdapter(); mBroadcastDispatcher = broadcastDispatcher; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java index 27ccd7cab226..cd45082458f2 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java @@ -18,14 +18,22 @@ package com.android.systemui.qs.tiles; import android.app.ActivityManager; import android.content.Intent; +import android.os.Handler; +import android.os.Looper; import android.provider.MediaStore; import android.service.quicksettings.Tile; import android.widget.Switch; +import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.systemui.R; +import com.android.systemui.dagger.qualifiers.Background; +import com.android.systemui.dagger.qualifiers.Main; +import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.qs.QSTile.BooleanState; +import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.qs.QSHost; +import com.android.systemui.qs.logging.QSLogger; import com.android.systemui.qs.tileimpl.QSTileImpl; import com.android.systemui.statusbar.policy.FlashlightController; @@ -39,8 +47,18 @@ public class FlashlightTile extends QSTileImpl<BooleanState> implements private final FlashlightController mFlashlightController; @Inject - public FlashlightTile(QSHost host, FlashlightController flashlightController) { - super(host); + public FlashlightTile( + QSHost host, + @Background Looper backgroundLooper, + @Main Handler mainHandler, + MetricsLogger metricsLogger, + StatusBarStateController statusBarStateController, + ActivityStarter activityStarter, + QSLogger qsLogger, + FlashlightController flashlightController + ) { + super(host, backgroundLooper, mainHandler, metricsLogger, statusBarStateController, + activityStarter, qsLogger); mFlashlightController = flashlightController; mFlashlightController.observe(getLifecycle(), this); } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java index 1ab77f3f7524..a45d94ace425 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java @@ -18,16 +18,24 @@ package com.android.systemui.qs.tiles; import android.annotation.Nullable; import android.content.Intent; +import android.os.Handler; +import android.os.Looper; import android.os.UserManager; import android.provider.Settings; import android.service.quicksettings.Tile; import android.util.Log; import android.widget.Switch; +import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.systemui.R; +import com.android.systemui.dagger.qualifiers.Background; +import com.android.systemui.dagger.qualifiers.Main; +import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.qs.QSTile.BooleanState; +import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.qs.QSHost; +import com.android.systemui.qs.logging.QSLogger; import com.android.systemui.qs.tileimpl.QSTileImpl; import com.android.systemui.statusbar.policy.DataSaverController; import com.android.systemui.statusbar.policy.HotspotController; @@ -45,9 +53,19 @@ public class HotspotTile extends QSTileImpl<BooleanState> { private boolean mListening; @Inject - public HotspotTile(QSHost host, HotspotController hotspotController, - DataSaverController dataSaverController) { - super(host); + public HotspotTile( + QSHost host, + @Background Looper backgroundLooper, + @Main Handler mainHandler, + MetricsLogger metricsLogger, + StatusBarStateController statusBarStateController, + ActivityStarter activityStarter, + QSLogger qsLogger, + HotspotController hotspotController, + DataSaverController dataSaverController + ) { + super(host, backgroundLooper, mainHandler, metricsLogger, statusBarStateController, + activityStarter, qsLogger); mHotspotController = hotspotController; mDataSaverController = dataSaverController; mHotspotController.observe(this, mCallbacks); diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java index 02f364bd3a7e..d502d06efceb 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java @@ -17,16 +17,23 @@ package com.android.systemui.qs.tiles; import android.content.Intent; +import android.os.Handler; +import android.os.Looper; import android.os.UserManager; import android.provider.Settings; import android.service.quicksettings.Tile; import android.widget.Switch; +import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.systemui.R; +import com.android.systemui.dagger.qualifiers.Background; +import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.qs.QSTile.BooleanState; +import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.qs.QSHost; +import com.android.systemui.qs.logging.QSLogger; import com.android.systemui.qs.tileimpl.QSTileImpl; import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.statusbar.policy.LocationController; @@ -41,16 +48,24 @@ public class LocationTile extends QSTileImpl<BooleanState> { private final LocationController mController; private final KeyguardStateController mKeyguard; - private final ActivityStarter mActivityStarter; private final Callback mCallback = new Callback(); @Inject - public LocationTile(QSHost host, LocationController locationController, - KeyguardStateController keyguardStateController, ActivityStarter activityStarter) { - super(host); + public LocationTile( + QSHost host, + @Background Looper backgroundLooper, + @Main Handler mainHandler, + MetricsLogger metricsLogger, + StatusBarStateController statusBarStateController, + ActivityStarter activityStarter, + QSLogger qsLogger, + LocationController locationController, + KeyguardStateController keyguardStateController + ) { + super(host, backgroundLooper, mainHandler, metricsLogger, statusBarStateController, + activityStarter, qsLogger); mController = locationController; mKeyguard = keyguardStateController; - mActivityStarter = activityStarter; mController.observe(this, mCallback); mKeyguard.observe(this, mCallback); } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/NfcTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/NfcTile.java index 7da913592286..fb281169b2f1 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/NfcTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/NfcTile.java @@ -23,15 +23,23 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManager; import android.nfc.NfcAdapter; +import android.os.Handler; +import android.os.Looper; import android.provider.Settings; import android.service.quicksettings.Tile; import android.widget.Switch; +import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.systemui.R; import com.android.systemui.broadcast.BroadcastDispatcher; +import com.android.systemui.dagger.qualifiers.Background; +import com.android.systemui.dagger.qualifiers.Main; +import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.qs.QSTile.BooleanState; +import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.qs.QSHost; +import com.android.systemui.qs.logging.QSLogger; import com.android.systemui.qs.tileimpl.QSTileImpl; import javax.inject.Inject; @@ -47,8 +55,18 @@ public class NfcTile extends QSTileImpl<BooleanState> { private boolean mListening; @Inject - public NfcTile(QSHost host, BroadcastDispatcher broadcastDispatcher) { - super(host); + public NfcTile( + QSHost host, + @Background Looper backgroundLooper, + @Main Handler mainHandler, + MetricsLogger metricsLogger, + StatusBarStateController statusBarStateController, + ActivityStarter activityStarter, + QSLogger qsLogger, + BroadcastDispatcher broadcastDispatcher + ) { + super(host, backgroundLooper, mainHandler, metricsLogger, statusBarStateController, + activityStarter, qsLogger); mBroadcastDispatcher = broadcastDispatcher; } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java index acd2846fef3c..f628f7b30bd0 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java @@ -33,10 +33,16 @@ import android.widget.Switch; import androidx.annotation.StringRes; +import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.systemui.R; +import com.android.systemui.dagger.qualifiers.Background; +import com.android.systemui.dagger.qualifiers.Main; +import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.qs.QSTile.BooleanState; +import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.qs.QSHost; +import com.android.systemui.qs.logging.QSLogger; import com.android.systemui.qs.tileimpl.QSTileImpl; import com.android.systemui.statusbar.policy.LocationController; @@ -66,11 +72,22 @@ public class NightDisplayTile extends QSTileImpl<BooleanState> implements private boolean mIsListening; @Inject - public NightDisplayTile(QSHost host, LocationController locationController) { - super(host); + public NightDisplayTile( + QSHost host, + @Background Looper backgroundLooper, + @Main Handler mainHandler, + MetricsLogger metricsLogger, + StatusBarStateController statusBarStateController, + ActivityStarter activityStarter, + QSLogger qsLogger, + LocationController locationController, + ColorDisplayManager colorDisplayManager + ) { + super(host, backgroundLooper, mainHandler, metricsLogger, statusBarStateController, + activityStarter, qsLogger); mLocationController = locationController; - mManager = mContext.getSystemService(ColorDisplayManager.class); - mListener = new NightDisplayListener(mContext, new Handler(Looper.myLooper())); + mManager = colorDisplayManager; + mListener = new NightDisplayListener(mContext, mainHandler); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java index 5dcb4e3b1fb9..4bf27e2aa4b8 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java @@ -19,14 +19,22 @@ package com.android.systemui.qs.tiles; import android.content.Intent; import android.content.res.Configuration; import android.content.res.Resources; +import android.os.Handler; +import android.os.Looper; import android.provider.Settings; import android.service.quicksettings.Tile; import android.widget.Switch; +import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.systemui.R; +import com.android.systemui.dagger.qualifiers.Background; +import com.android.systemui.dagger.qualifiers.Main; +import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.qs.QSTile.BooleanState; +import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.qs.QSHost; +import com.android.systemui.qs.logging.QSLogger; import com.android.systemui.qs.tileimpl.QSTileImpl; import com.android.systemui.statusbar.policy.RotationLockController; import com.android.systemui.statusbar.policy.RotationLockController.RotationLockControllerCallback; @@ -40,8 +48,18 @@ public class RotationLockTile extends QSTileImpl<BooleanState> { private final RotationLockController mController; @Inject - public RotationLockTile(QSHost host, RotationLockController rotationLockController) { - super(host); + public RotationLockTile( + QSHost host, + @Background Looper backgroundLooper, + @Main Handler mainHandler, + MetricsLogger metricsLogger, + StatusBarStateController statusBarStateController, + ActivityStarter activityStarter, + QSLogger qsLogger, + RotationLockController rotationLockController + ) { + super(host, backgroundLooper, mainHandler, metricsLogger, statusBarStateController, + activityStarter, qsLogger); mController = rotationLockController; mController.observe(this, mCallback); } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java index 0c34b27d348e..d7a2975a4b04 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java @@ -17,15 +17,22 @@ package com.android.systemui.qs.tiles; import android.content.Intent; +import android.os.Handler; +import android.os.Looper; import android.service.quicksettings.Tile; import android.text.TextUtils; import android.util.Log; import android.widget.Switch; +import com.android.internal.logging.MetricsLogger; import com.android.systemui.R; +import com.android.systemui.dagger.qualifiers.Background; +import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.qs.QSTile; +import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.qs.QSHost; +import com.android.systemui.qs.logging.QSLogger; import com.android.systemui.qs.tileimpl.QSTileImpl; import com.android.systemui.screenrecord.RecordingController; import com.android.systemui.statusbar.phone.KeyguardDismissUtil; @@ -44,9 +51,19 @@ public class ScreenRecordTile extends QSTileImpl<QSTile.BooleanState> private Callback mCallback = new Callback(); @Inject - public ScreenRecordTile(QSHost host, RecordingController controller, - KeyguardDismissUtil keyguardDismissUtil) { - super(host); + public ScreenRecordTile( + QSHost host, + @Background Looper backgroundLooper, + @Main Handler mainHandler, + MetricsLogger metricsLogger, + StatusBarStateController statusBarStateController, + ActivityStarter activityStarter, + QSLogger qsLogger, + RecordingController controller, + KeyguardDismissUtil keyguardDismissUtil + ) { + super(host, backgroundLooper, mainHandler, metricsLogger, statusBarStateController, + activityStarter, qsLogger); mController = controller; mController.observe(this, mCallback); mKeyguardDismissUtil = keyguardDismissUtil; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/UiModeNightTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/UiModeNightTile.java index f777553bb5fe..78975a4798ce 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/UiModeNightTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/UiModeNightTile.java @@ -19,15 +19,23 @@ package com.android.systemui.qs.tiles; import android.app.UiModeManager; import android.content.Intent; import android.content.res.Configuration; +import android.os.Handler; +import android.os.Looper; import android.provider.Settings; import android.service.quicksettings.Tile; import android.text.TextUtils; import android.widget.Switch; +import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto; import com.android.systemui.R; +import com.android.systemui.dagger.qualifiers.Background; +import com.android.systemui.dagger.qualifiers.Main; +import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.qs.QSTile; +import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.qs.QSHost; +import com.android.systemui.qs.logging.QSLogger; import com.android.systemui.qs.tileimpl.QSTileImpl; import com.android.systemui.statusbar.policy.BatteryController; import com.android.systemui.statusbar.policy.ConfigurationController; @@ -54,9 +62,20 @@ public class UiModeNightTile extends QSTileImpl<QSTile.BooleanState> implements private final BatteryController mBatteryController; private final LocationController mLocationController; @Inject - public UiModeNightTile(QSHost host, ConfigurationController configurationController, - BatteryController batteryController, LocationController locationController) { - super(host); + public UiModeNightTile( + QSHost host, + @Background Looper backgroundLooper, + @Main Handler mainHandler, + MetricsLogger metricsLogger, + StatusBarStateController statusBarStateController, + ActivityStarter activityStarter, + QSLogger qsLogger, + ConfigurationController configurationController, + BatteryController batteryController, + LocationController locationController + ) { + super(host, backgroundLooper, mainHandler, metricsLogger, statusBarStateController, + activityStarter, qsLogger); mBatteryController = batteryController; mUiModeManager = host.getUserContext().getSystemService(UiModeManager.class); mLocationController = locationController; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserTile.java index aab30d499e08..26adfdcd8539 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserTile.java @@ -18,14 +18,22 @@ package com.android.systemui.qs.tiles; import android.content.Context; import android.content.Intent; import android.graphics.drawable.Drawable; +import android.os.Handler; +import android.os.Looper; import android.provider.Settings; import android.util.Pair; +import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; +import com.android.systemui.dagger.qualifiers.Background; +import com.android.systemui.dagger.qualifiers.Main; +import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.qs.DetailAdapter; import com.android.systemui.plugins.qs.QSTile; import com.android.systemui.plugins.qs.QSTile.State; +import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.qs.QSHost; +import com.android.systemui.qs.logging.QSLogger; import com.android.systemui.qs.tileimpl.QSTileImpl; import com.android.systemui.statusbar.policy.UserInfoController; import com.android.systemui.statusbar.policy.UserSwitcherController; @@ -39,9 +47,19 @@ public class UserTile extends QSTileImpl<State> implements UserInfoController.On private Pair<String, Drawable> mLastUpdate; @Inject - public UserTile(QSHost host, UserSwitcherController userSwitcherController, - UserInfoController userInfoController) { - super(host); + public UserTile( + QSHost host, + @Background Looper backgroundLooper, + @Main Handler mainHandler, + MetricsLogger metricsLogger, + StatusBarStateController statusBarStateController, + ActivityStarter activityStarter, + QSLogger qsLogger, + UserSwitcherController userSwitcherController, + UserInfoController userInfoController + ) { + super(host, backgroundLooper, mainHandler, metricsLogger, statusBarStateController, + activityStarter, qsLogger); mUserSwitcherController = userSwitcherController; mUserInfoController = userInfoController; mUserInfoController.observe(getLifecycle(), this); diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java index 1279d42eb64d..4d89dea7cb70 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java @@ -20,6 +20,8 @@ import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.content.res.Resources; +import android.os.Handler; +import android.os.Looper; import android.provider.Settings; import android.service.quicksettings.Tile; import android.text.TextUtils; @@ -32,15 +34,19 @@ import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settingslib.wifi.AccessPoint; import com.android.systemui.R; +import com.android.systemui.dagger.qualifiers.Background; +import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.qs.DetailAdapter; import com.android.systemui.plugins.qs.QSIconView; import com.android.systemui.plugins.qs.QSTile; import com.android.systemui.plugins.qs.QSTile.SignalState; +import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.qs.AlphaControlledSignalTileView; import com.android.systemui.qs.QSDetailItems; import com.android.systemui.qs.QSDetailItems.Item; import com.android.systemui.qs.QSHost; +import com.android.systemui.qs.logging.QSLogger; import com.android.systemui.qs.tileimpl.QSIconViewImpl; import com.android.systemui.qs.tileimpl.QSTileImpl; import com.android.systemui.statusbar.policy.NetworkController; @@ -63,17 +69,24 @@ public class WifiTile extends QSTileImpl<SignalState> { private final QSTile.SignalState mStateBeforeClick = newTileState(); protected final WifiSignalCallback mSignalCallback = new WifiSignalCallback(); - private final ActivityStarter mActivityStarter; private boolean mExpectDisabled; @Inject - public WifiTile(QSHost host, NetworkController networkController, - ActivityStarter activityStarter) { - super(host); + public WifiTile( + QSHost host, + @Background Looper backgroundLooper, + @Main Handler mainHandler, + MetricsLogger metricsLogger, + StatusBarStateController statusBarStateController, + ActivityStarter activityStarter, + QSLogger qsLogger, + NetworkController networkController + ) { + super(host, backgroundLooper, mainHandler, metricsLogger, statusBarStateController, + activityStarter, qsLogger); mController = networkController; mWifiController = mController.getAccessPointController(); mDetailAdapter = (WifiDetailAdapter) createDetailAdapter(); - mActivityStarter = activityStarter; mController.observe(getLifecycle(), mSignalCallback); } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java index 318c0c4660cb..5235b6d5a0bb 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java @@ -17,14 +17,22 @@ package com.android.systemui.qs.tiles; import android.content.Intent; +import android.os.Handler; +import android.os.Looper; import android.provider.Settings; import android.service.quicksettings.Tile; import android.widget.Switch; +import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.systemui.R; +import com.android.systemui.dagger.qualifiers.Background; +import com.android.systemui.dagger.qualifiers.Main; +import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.qs.QSTile.BooleanState; +import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.qs.QSHost; +import com.android.systemui.qs.logging.QSLogger; import com.android.systemui.qs.tileimpl.QSTileImpl; import com.android.systemui.statusbar.phone.ManagedProfileController; @@ -38,8 +46,18 @@ public class WorkModeTile extends QSTileImpl<BooleanState> implements private final ManagedProfileController mProfileController; @Inject - public WorkModeTile(QSHost host, ManagedProfileController managedProfileController) { - super(host); + public WorkModeTile( + QSHost host, + @Background Looper backgroundLooper, + @Main Handler mainHandler, + MetricsLogger metricsLogger, + StatusBarStateController statusBarStateController, + ActivityStarter activityStarter, + QSLogger qsLogger, + ManagedProfileController managedProfileController + ) { + super(host, backgroundLooper, mainHandler, metricsLogger, statusBarStateController, + activityStarter, qsLogger); mProfileController = managedProfileController; mProfileController.observe(getLifecycle(), this); } diff --git a/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java b/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java index b12224bf583d..d1805af06434 100644 --- a/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java +++ b/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java @@ -44,13 +44,17 @@ import android.text.format.DateUtils; import android.util.Log; import android.util.LongSparseArray; +import com.android.internal.logging.MetricsLogger; import com.android.systemui.Dumpable; import com.android.systemui.R; import com.android.systemui.SystemUI; import com.android.systemui.dagger.qualifiers.Background; +import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.qs.QSTile; +import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.qs.QSHost; +import com.android.systemui.qs.logging.QSLogger; import com.android.systemui.qs.tileimpl.QSTileImpl; import java.io.FileDescriptor; @@ -396,15 +400,23 @@ public class GarbageMonitor implements Dumpable { public static final String TILE_SPEC = "dbg:mem"; private final GarbageMonitor gm; - private final ActivityStarter mActivityStarter; private ProcessMemInfo pmi; private boolean dumpInProgress; @Inject - public MemoryTile(QSHost host, GarbageMonitor monitor, ActivityStarter starter) { - super(host); + public MemoryTile( + QSHost host, + @Background Looper backgroundLooper, + @Main Handler mainHandler, + MetricsLogger metricsLogger, + StatusBarStateController statusBarStateController, + ActivityStarter activityStarter, + QSLogger qsLogger, + GarbageMonitor monitor + ) { + super(host, backgroundLooper, mainHandler, metricsLogger, statusBarStateController, + activityStarter, qsLogger); gm = monitor; - mActivityStarter = starter; } @Override diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSTileHostTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSTileHostTest.java index 5d4ef550b36c..c8e1a74d969f 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSTileHostTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSTileHostTest.java @@ -41,14 +41,17 @@ import android.testing.TestableLooper.RunWithLooper; import androidx.test.filters.SmallTest; +import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.UiEventLogger; import com.android.internal.util.CollectionUtils; import com.android.systemui.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.dump.DumpManager; +import com.android.systemui.plugins.ActivityStarter; 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.logging.QSLogger; import com.android.systemui.qs.tileimpl.QSTileImpl; @@ -75,7 +78,7 @@ import javax.inject.Provider; @RunWith(AndroidTestingRunner.class) @SmallTest -@RunWithLooper +@RunWithLooper(setAsMainLooper = true) public class QSTileHostTest extends SysuiTestCase { private static String MOCK_STATE_STRING = "MockState"; @@ -331,7 +334,15 @@ public class QSTileHostTest extends SysuiTestCase { private class TestTile extends QSTileImpl<QSTile.State> { protected TestTile(QSHost host) { - super(host); + super( + host, + mLooper.getLooper(), + new Handler(mLooper.getLooper()), + mock(MetricsLogger.class), + mock(StatusBarStateController.class), + mock(ActivityStarter.class), + mQSLogger + ); } @Override diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/external/CustomTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/external/CustomTileTest.kt index 953198c42d66..3aa40dec1fad 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/external/CustomTileTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/external/CustomTileTest.kt @@ -23,17 +23,23 @@ import android.content.pm.PackageManager import android.content.pm.ServiceInfo import android.graphics.drawable.Drawable import android.graphics.drawable.Icon +import android.os.Handler import android.service.quicksettings.IQSTileService import android.service.quicksettings.Tile import android.test.suitebuilder.annotation.SmallTest +import android.testing.AndroidTestingRunner +import android.testing.TestableLooper import android.view.IWindowManager -import androidx.test.runner.AndroidJUnit4 +import com.android.internal.logging.MetricsLogger import com.android.systemui.SysuiTestCase +import com.android.systemui.plugins.ActivityStarter import com.android.systemui.plugins.qs.QSTile +import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.qs.QSHost -import junit.framework.Assert.assertFalse -import junit.framework.Assert.assertTrue +import com.android.systemui.qs.logging.QSLogger import org.junit.Assert.assertEquals +import org.junit.Assert.assertFalse +import org.junit.Assert.assertTrue import org.junit.Before import org.junit.Test import org.junit.runner.RunWith @@ -46,7 +52,8 @@ import org.mockito.Mockito.mock import org.mockito.MockitoAnnotations @SmallTest -@RunWith(AndroidJUnit4::class) +@RunWith(AndroidTestingRunner::class) +@TestableLooper.RunWithLooper(setAsMainLooper = true) class CustomTileTest : SysuiTestCase() { companion object { @@ -56,36 +63,53 @@ class CustomTileTest : SysuiTestCase() { val TILE_SPEC = CustomTile.toSpec(componentName) } - @Mock private lateinit var mTileHost: QSHost - @Mock private lateinit var mTileService: IQSTileService - @Mock private lateinit var mTileServices: TileServices - @Mock private lateinit var mTileServiceManager: TileServiceManager - @Mock private lateinit var mWindowService: IWindowManager - @Mock private lateinit var mPackageManager: PackageManager - @Mock private lateinit var mApplicationInfo: ApplicationInfo - @Mock private lateinit var mServiceInfo: ServiceInfo + @Mock private lateinit var tileHost: QSHost + @Mock private lateinit var metricsLogger: MetricsLogger + @Mock private lateinit var statusBarStateController: StatusBarStateController + @Mock private lateinit var activityStarter: ActivityStarter + @Mock private lateinit var qsLogger: QSLogger + @Mock private lateinit var tileService: IQSTileService + @Mock private lateinit var tileServices: TileServices + @Mock private lateinit var tileServiceManager: TileServiceManager + @Mock private lateinit var windowService: IWindowManager + @Mock private lateinit var packageManager: PackageManager + @Mock private lateinit var applicationInfo: ApplicationInfo + @Mock private lateinit var serviceInfo: ServiceInfo private lateinit var customTile: CustomTile + private lateinit var testableLooper: TestableLooper + private lateinit var customTileBuilder: CustomTile.Builder @Before fun setUp() { MockitoAnnotations.initMocks(this) - - mContext.addMockSystemService("window", mWindowService) - mContext.setMockPackageManager(mPackageManager) - `when`(mTileHost.tileServices).thenReturn(mTileServices) - `when`(mTileHost.context).thenReturn(mContext) - `when`(mTileServices.getTileWrapper(any(CustomTile::class.java))) - .thenReturn(mTileServiceManager) - `when`(mTileServiceManager.tileService).thenReturn(mTileService) - `when`(mPackageManager.getApplicationInfo(anyString(), anyInt())) - .thenReturn(mApplicationInfo) - - `when`(mPackageManager.getServiceInfo(any(ComponentName::class.java), anyInt())) - .thenReturn(mServiceInfo) - mServiceInfo.applicationInfo = mApplicationInfo - - customTile = CustomTile.create(mTileHost, TILE_SPEC, mContext) + testableLooper = TestableLooper.get(this) + + mContext.addMockSystemService("window", windowService) + mContext.setMockPackageManager(packageManager) + `when`(tileHost.tileServices).thenReturn(tileServices) + `when`(tileHost.context).thenReturn(mContext) + `when`(tileServices.getTileWrapper(any(CustomTile::class.java))) + .thenReturn(tileServiceManager) + `when`(tileServiceManager.tileService).thenReturn(tileService) + `when`(packageManager.getApplicationInfo(anyString(), anyInt())) + .thenReturn(applicationInfo) + + `when`(packageManager.getServiceInfo(any(ComponentName::class.java), anyInt())) + .thenReturn(serviceInfo) + serviceInfo.applicationInfo = applicationInfo + + customTileBuilder = CustomTile.Builder( + { tileHost }, + testableLooper.looper, + Handler(testableLooper.looper), + metricsLogger, + statusBarStateController, + activityStarter, + qsLogger + ) + + customTile = CustomTile.create(customTileBuilder, TILE_SPEC, mContext) } @Test @@ -93,18 +117,18 @@ class CustomTileTest : SysuiTestCase() { assertEquals(0, customTile.user) val userContext = mock(Context::class.java) - `when`(userContext.packageManager).thenReturn(mPackageManager) + `when`(userContext.packageManager).thenReturn(packageManager) `when`(userContext.userId).thenReturn(10) - val tile = CustomTile.create(mTileHost, TILE_SPEC, userContext) + val tile = CustomTile.create(customTileBuilder, TILE_SPEC, userContext) assertEquals(10, tile.user) } @Test fun testToggleableTileHasBooleanState() { - `when`(mTileServiceManager.isToggleableTile).thenReturn(true) - customTile = CustomTile.create(mTileHost, TILE_SPEC, mContext) + `when`(tileServiceManager.isToggleableTile).thenReturn(true) + customTile = CustomTile.create(customTileBuilder, TILE_SPEC, mContext) assertTrue(customTile.state is QSTile.BooleanState) assertTrue(customTile.newTileState() is QSTile.BooleanState) @@ -118,8 +142,8 @@ class CustomTileTest : SysuiTestCase() { @Test fun testValueUpdatedInBooleanTile() { - `when`(mTileServiceManager.isToggleableTile).thenReturn(true) - customTile = CustomTile.create(mTileHost, TILE_SPEC, mContext) + `when`(tileServiceManager.isToggleableTile).thenReturn(true) + customTile = CustomTile.create(customTileBuilder, TILE_SPEC, mContext) customTile.qsTile.icon = mock(Icon::class.java) `when`(customTile.qsTile.icon.loadDrawable(any(Context::class.java))) .thenReturn(mock(Drawable::class.java)) diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileImplTest.java index 438de99015a4..7f74f9f28fad 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileImplTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileImplTest.java @@ -35,17 +35,14 @@ import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Matchers.argThat; -import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import static java.lang.Thread.sleep; - import android.content.Intent; import android.metrics.LogMaker; +import android.os.Handler; +import android.os.Looper; import android.service.quicksettings.Tile; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; @@ -57,7 +54,6 @@ import com.android.internal.logging.InstanceId; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.UiEventLogger; import com.android.internal.logging.testing.UiEventLoggerFake; -import com.android.systemui.Dependency; import com.android.systemui.SysuiTestCase; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.qs.QSTile; @@ -69,7 +65,6 @@ import com.android.systemui.qs.logging.QSLogger; import com.android.systemui.statusbar.StatusBarState; import org.junit.Before; -import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; @@ -91,9 +86,14 @@ public class QSTileImplTest extends SysuiTestCase { private TestableLooper mTestableLooper; private TileImpl mTile; + @Mock private QSTileHost mHost; + @Mock private MetricsLogger mMetricsLogger; + @Mock private StatusBarStateController mStatusBarStateController; + @Mock + private ActivityStarter mActivityStarter; private UiEventLoggerFake mUiEventLoggerFake; private InstanceId mInstanceId = InstanceId.fakeInstanceId(5); @@ -104,21 +104,16 @@ public class QSTileImplTest extends SysuiTestCase { public void setup() throws Exception { MockitoAnnotations.initMocks(this); mTestableLooper = TestableLooper.get(this); - mDependency.injectTestDependency(Dependency.BG_LOOPER, mTestableLooper.getLooper()); - mDependency.injectMockDependency(ActivityStarter.class); - mMetricsLogger = mDependency.injectMockDependency(MetricsLogger.class); mUiEventLoggerFake = new UiEventLoggerFake(); - mStatusBarStateController = - mDependency.injectMockDependency(StatusBarStateController.class); - mHost = mock(QSTileHost.class); when(mHost.indexOf(SPEC)).thenReturn(POSITION); when(mHost.getContext()).thenReturn(mContext.getBaseContext()); - when(mHost.getQSLogger()).thenReturn(mQsLogger); when(mHost.getUiEventLogger()).thenReturn(mUiEventLoggerFake); when(mHost.getNewInstanceId()).thenReturn(mInstanceId); - mTile = spy(new TileImpl(mHost)); - mTile.mHandler = mTile.new H(mTestableLooper.getLooper()); + Handler mainHandler = new Handler(mTestableLooper.getLooper()); + + mTile = new TileImpl(mHost, mTestableLooper.getLooper(), mainHandler, + mMetricsLogger, mStatusBarStateController, mActivityStarter, mQsLogger); mTile.setTileSpec(SPEC); } @@ -223,40 +218,35 @@ public class QSTileImplTest extends SysuiTestCase { verify(maker).addTaggedData(eq(FIELD_QS_POSITION), eq(POSITION)); } - @Test - @Ignore("flaky") - public void testStaleTimeout() throws InterruptedException { - when(mTile.getStaleTimeout()).thenReturn(5l); - clearInvocations(mTile); - - mTile.handleRefreshState(null); - mTestableLooper.processAllMessages(); - verify(mTile, never()).handleStale(); - - sleep(10); - mTestableLooper.processAllMessages(); - verify(mTile).handleStale(); - } + //TODO(b/161799397) Bring back testStaleTimeout when we can use FakeExecutor @Test public void testStaleListening() { mTile.handleStale(); mTestableLooper.processAllMessages(); - verify(mTile).handleSetListening(eq(true)); + verify(mQsLogger).logTileChangeListening(SPEC, true); mTile.handleRefreshState(null); mTestableLooper.processAllMessages(); - verify(mTile).handleSetListening(eq(false)); + verify(mQsLogger).logTileChangeListening(SPEC, false); } @Test public void testHandleDestroyClearsHandlerQueue() { - when(mTile.getStaleTimeout()).thenReturn(0L); mTile.handleRefreshState(null); // this will add a delayed H.STALE message mTile.handleDestroy(); + assertFalse(mTile.mHandler.hasMessages(QSTileImpl.H.STALE)); + } + + @Test + public void testHandleDestroyLifecycle() { + assertNotEquals(DESTROYED, mTile.getLifecycle().getCurrentState()); + mTile.handleDestroy(); + mTestableLooper.processAllMessages(); - verify(mTile, never()).handleStale(); + + assertEquals(DESTROYED, mTile.getLifecycle().getCurrentState()); } @Test @@ -310,6 +300,25 @@ public class QSTileImplTest extends SysuiTestCase { assertNotEquals(DESTROYED, mTile.getLifecycle().getCurrentState()); } + @Test + public void testRefreshStateAfterDestroyedDoesNotCrash() { + mTile.destroy(); + mTile.refreshState(); + + mTestableLooper.processAllMessages(); + } + + @Test + public void testSetListeningAfterDestroyedDoesNotCrash() { + Object o = new Object(); + mTile.destroy(); + + mTile.setListening(o, true); + mTile.setListening(o, false); + + mTestableLooper.processAllMessages(); + } + private void assertEvent(UiEventLogger.UiEventEnum eventType, UiEventLoggerFake.FakeUiEvent fakeEvent) { assertEquals(eventType.getId(), fakeEvent.eventId); @@ -351,8 +360,17 @@ public class QSTileImplTest extends SysuiTestCase { } private static class TileImpl extends QSTileImpl<QSTile.BooleanState> { - protected TileImpl(QSHost host) { - super(host); + protected TileImpl( + QSHost host, + Looper backgroundLooper, + Handler mainHandler, + MetricsLogger metricsLogger, + StatusBarStateController statusBarStateController, + ActivityStarter activityStarter, + QSLogger qsLogger + ) { + super(host, backgroundLooper, mainHandler, metricsLogger, statusBarStateController, + activityStarter, qsLogger); getState().state = Tile.STATE_ACTIVE; } diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BatterySaverTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BatterySaverTileTest.kt index 31992875df07..2006a75c0e16 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BatterySaverTileTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BatterySaverTileTest.kt @@ -17,13 +17,17 @@ package com.android.systemui.qs.tiles import android.content.Context +import android.os.Handler import android.testing.AndroidTestingRunner import android.testing.TestableLooper import android.testing.TestableLooper.RunWithLooper import androidx.test.filters.SmallTest -import com.android.systemui.Dependency +import com.android.internal.logging.MetricsLogger import com.android.systemui.SysuiTestCase +import com.android.systemui.plugins.ActivityStarter +import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.qs.QSHost +import com.android.systemui.qs.logging.QSLogger import com.android.systemui.statusbar.policy.BatteryController import org.junit.Assert.assertEquals import org.junit.Before @@ -34,7 +38,7 @@ import org.mockito.Mockito.`when` import org.mockito.MockitoAnnotations @RunWith(AndroidTestingRunner::class) -@RunWithLooper +@RunWithLooper(setAsMainLooper = true) @SmallTest class BatterySaverTileTest : SysuiTestCase() { @@ -47,6 +51,14 @@ class BatterySaverTileTest : SysuiTestCase() { @Mock private lateinit var qsHost: QSHost @Mock + private lateinit var metricsLogger: MetricsLogger + @Mock + private lateinit var statusBarStateController: StatusBarStateController + @Mock + private lateinit var activityStarter: ActivityStarter + @Mock + private lateinit var qsLogger: QSLogger + @Mock private lateinit var batteryController: BatteryController private lateinit var testableLooper: TestableLooper private lateinit var tile: BatterySaverTile @@ -55,11 +67,18 @@ class BatterySaverTileTest : SysuiTestCase() { fun setUp() { MockitoAnnotations.initMocks(this) testableLooper = TestableLooper.get(this) - mDependency.injectTestDependency(Dependency.BG_LOOPER, testableLooper.looper) `when`(qsHost.userContext).thenReturn(userContext) `when`(userContext.userId).thenReturn(USER) - tile = BatterySaverTile(qsHost, batteryController) + tile = BatterySaverTile( + qsHost, + testableLooper.looper, + Handler(testableLooper.looper), + metricsLogger, + statusBarStateController, + activityStarter, + qsLogger, + batteryController) } @Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/CastTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/CastTileTest.java index 853b2dbbc485..5d14898cdd2c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/CastTileTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/CastTileTest.java @@ -27,6 +27,7 @@ import static org.mockito.Mockito.when; import android.media.MediaRouter; import android.media.MediaRouter.RouteInfo; import android.media.projection.MediaProjectionInfo; +import android.os.Handler; import android.service.quicksettings.Tile; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; @@ -34,10 +35,12 @@ import android.testing.TestableLooper; import androidx.lifecycle.LifecycleOwner; import androidx.test.filters.SmallTest; -import com.android.systemui.Dependency; +import com.android.internal.logging.MetricsLogger; import com.android.systemui.SysuiTestCase; import com.android.systemui.plugins.ActivityStarter; +import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.qs.QSTileHost; +import com.android.systemui.qs.logging.QSLogger; import com.android.systemui.statusbar.policy.CastController; import com.android.systemui.statusbar.policy.CastController.CastDevice; import com.android.systemui.statusbar.policy.KeyguardStateController; @@ -55,7 +58,7 @@ import java.util.List; @RunWith(AndroidTestingRunner.class) -@TestableLooper.RunWithLooper +@TestableLooper.RunWithLooper(setAsMainLooper = true) @SmallTest public class CastTileTest extends SysuiTestCase { @@ -71,6 +74,12 @@ public class CastTileTest extends SysuiTestCase { private QSTileHost mHost; @Mock NetworkController.SignalCallback mCallback; + @Mock + private MetricsLogger mMetricsLogger; + @Mock + private StatusBarStateController mStatusBarStateController; + @Mock + private QSLogger mQSLogger; private TestableLooper mTestableLooper; private CastTile mCastTile; @@ -80,16 +89,20 @@ public class CastTileTest extends SysuiTestCase { MockitoAnnotations.initMocks(this); mTestableLooper = TestableLooper.get(this); - mDependency.injectTestDependency(Dependency.BG_LOOPER, mTestableLooper.getLooper()); - mController = mDependency.injectMockDependency(CastController.class); - mActivityStarter = mDependency.injectMockDependency(ActivityStarter.class); - mKeyguard = mDependency.injectMockDependency(KeyguardStateController.class); - mNetworkController = mDependency.injectMockDependency(NetworkController.class); - when(mHost.getContext()).thenReturn(mContext); - mCastTile = new CastTile(mHost, mController, mKeyguard, mNetworkController, - mActivityStarter); + mCastTile = new CastTile( + mHost, + mTestableLooper.getLooper(), + new Handler(mTestableLooper.getLooper()), + mMetricsLogger, + mStatusBarStateController, + mActivityStarter, + mQSLogger, + mController, + mKeyguard, + mNetworkController + ); // We are not setting the mocks to listening, so we trigger a first refresh state to // set the initial state diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ScreenRecordTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ScreenRecordTileTest.java index 5a6823879942..2d276bb876f3 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ScreenRecordTileTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ScreenRecordTileTest.java @@ -23,16 +23,20 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import android.os.Handler; import android.service.quicksettings.Tile; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import androidx.test.filters.SmallTest; -import com.android.systemui.Dependency; +import com.android.internal.logging.MetricsLogger; import com.android.systemui.R; import com.android.systemui.SysuiTestCase; +import com.android.systemui.plugins.ActivityStarter; +import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.qs.QSTileHost; +import com.android.systemui.qs.logging.QSLogger; import com.android.systemui.screenrecord.RecordingController; import com.android.systemui.statusbar.phone.KeyguardDismissUtil; @@ -43,7 +47,7 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; @RunWith(AndroidTestingRunner.class) -@TestableLooper.RunWithLooper(setAsMainLooper = true) +@TestableLooper.RunWithLooper() @SmallTest public class ScreenRecordTileTest extends SysuiTestCase { @@ -53,6 +57,14 @@ public class ScreenRecordTileTest extends SysuiTestCase { private QSTileHost mHost; @Mock private KeyguardDismissUtil mKeyguardDismissUtil; + @Mock + private MetricsLogger mMetricsLogger; + @Mock + private StatusBarStateController mStatusBarStateController; + @Mock + private ActivityStarter mActivityStarter; + @Mock + private QSLogger mQSLogger; private TestableLooper mTestableLooper; private ScreenRecordTile mTile; @@ -62,12 +74,20 @@ public class ScreenRecordTileTest extends SysuiTestCase { MockitoAnnotations.initMocks(this); mTestableLooper = TestableLooper.get(this); - mDependency.injectTestDependency(Dependency.BG_LOOPER, mTestableLooper.getLooper()); - mController = mDependency.injectMockDependency(RecordingController.class); when(mHost.getContext()).thenReturn(mContext); - mTile = new ScreenRecordTile(mHost, mController, mKeyguardDismissUtil); + mTile = new ScreenRecordTile( + mHost, + mTestableLooper.getLooper(), + new Handler(mTestableLooper.getLooper()), + mMetricsLogger, + mStatusBarStateController, + mActivityStarter, + mQSLogger, + mController, + mKeyguardDismissUtil + ); } // Test that the tile is inactive and labeled correctly when the controller is neither starting diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CallbackControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CallbackControllerTest.java index fa711f1cf9a2..a16fb5e8dc17 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CallbackControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CallbackControllerTest.java @@ -23,10 +23,12 @@ import static org.mockito.Mockito.verify; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper.RunWithLooper; +import androidx.annotation.NonNull; import androidx.lifecycle.Lifecycle; import androidx.lifecycle.Lifecycle.Event; import androidx.lifecycle.LifecycleEventObserver; import androidx.lifecycle.LifecycleOwner; +import androidx.lifecycle.LifecycleRegistry; import androidx.test.filters.SmallTest; import com.android.systemui.SysuiTestCase; @@ -76,6 +78,34 @@ public class CallbackControllerTest extends SysuiTestCase { verify(controller).removeCallback(eq(callback)); } + @Test + public void testCallbackIsRemovedOnDestroy() { + SimpleLifecycleOwner owner = new SimpleLifecycleOwner(); + + Object callback = new Object(); + Controller controller = mock(Controller.class); + controller.observe(owner, callback); + + owner.setState(Lifecycle.State.RESUMED); + verify(controller).addCallback(callback); + + owner.setState(Lifecycle.State.DESTROYED); + verify(controller).removeCallback(callback); + } + + private static class SimpleLifecycleOwner implements LifecycleOwner { + LifecycleRegistry mLifecycle = new LifecycleRegistry(this); + @NonNull + @Override + public Lifecycle getLifecycle() { + return mLifecycle; + } + + public void setState(Lifecycle.State state) { + mLifecycle.setCurrentState(state); + } + } + private static class Controller implements CallbackController<Object> { @Override public void addCallback(Object listener) { |