diff options
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) { |