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
This commit is contained in:
Treehugger Robot
2021-05-27 22:33:27 +00:00
committed by Gerrit Code Review
33 changed files with 790 additions and 196 deletions

View File

@@ -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;
@@ -105,6 +106,12 @@ public class SystemServicesModule {
return context.getSystemService(AudioManager.class);
}
@Provides
@Singleton
static ColorDisplayManager provideColorDisplayManager(Context context) {
return context.getSystemService(ColorDisplayManager.class);
}
@Provides
@Singleton
static ConnectivityManager provideConnectivityManagager(Context context) {

View File

@@ -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);

View File

@@ -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;

View File

@@ -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
);
}
}
}

View File

@@ -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.

View File

@@ -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();
}

View File

@@ -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

View File

@@ -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);
}
};

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);
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, mHandler,
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);
}
};

View File

@@ -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);
}

View File

@@ -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;

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -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);
}

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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;

View File

@@ -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;

View File

@@ -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);

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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

View File

@@ -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)
testableLooper = TestableLooper.get(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)
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`(mPackageManager.getServiceInfo(any(ComponentName::class.java), anyInt()))
.thenReturn(mServiceInfo)
mServiceInfo.applicationInfo = mApplicationInfo
`when`(packageManager.getServiceInfo(any(ComponentName::class.java), anyInt()))
.thenReturn(serviceInfo)
serviceInfo.applicationInfo = applicationInfo
customTile = CustomTile.create(mTileHost, TILE_SPEC, mContext)
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))

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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) {