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.content.res.Resources;
import android.hardware.SensorManager; import android.hardware.SensorManager;
import android.hardware.SensorPrivacyManager; import android.hardware.SensorPrivacyManager;
import android.hardware.display.ColorDisplayManager;
import android.hardware.display.DisplayManager; import android.hardware.display.DisplayManager;
import android.media.AudioManager; import android.media.AudioManager;
import android.media.MediaRouter2Manager; import android.media.MediaRouter2Manager;
@@ -105,6 +106,12 @@ public class SystemServicesModule {
return context.getSystemService(AudioManager.class); return context.getSystemService(AudioManager.class);
} }
@Provides
@Singleton
static ColorDisplayManager provideColorDisplayManager(Context context) {
return context.getSystemService(ColorDisplayManager.class);
}
@Provides @Provides
@Singleton @Singleton
static ConnectivityManager provideConnectivityManagager(Context context) { 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.internal.logging.UiEventLogger;
import com.android.systemui.plugins.qs.QSTile; import com.android.systemui.plugins.qs.QSTile;
import com.android.systemui.qs.external.TileServices; import com.android.systemui.qs.external.TileServices;
import com.android.systemui.qs.logging.QSLogger;
import java.util.Collection; import java.util.Collection;
@@ -31,7 +30,6 @@ public interface QSHost {
void openPanels(); void openPanels();
Context getContext(); Context getContext();
Context getUserContext(); Context getUserContext();
QSLogger getQSLogger();
UiEventLogger getUiEventLogger(); UiEventLogger getUiEventLogger();
Collection<QSTile> getTiles(); Collection<QSTile> getTiles();
void addCallback(Callback callback); void addCallback(Callback callback);

View File

@@ -179,10 +179,6 @@ public class QSTileHost implements QSHost, Tunable, PluginListener<QSFactory>, D
onTuningChanged(TILES_SETTING, value); onTuningChanged(TILES_SETTING, value);
} }
public QSLogger getQSLogger() {
return mQSLogger;
}
@Override @Override
public UiEventLogger getUiEventLogger() { public UiEventLogger getUiEventLogger() {
return mUiEventLogger; return mUiEventLogger;

View File

@@ -29,7 +29,9 @@ import android.graphics.drawable.Drawable;
import android.metrics.LogMaker; import android.metrics.LogMaker;
import android.net.Uri; import android.net.Uri;
import android.os.Binder; import android.os.Binder;
import android.os.Handler;
import android.os.IBinder; import android.os.IBinder;
import android.os.Looper;
import android.os.RemoteException; import android.os.RemoteException;
import android.provider.Settings; import android.provider.Settings;
import android.service.quicksettings.IQSTileService; import android.service.quicksettings.IQSTileService;
@@ -42,16 +44,27 @@ import android.view.IWindowManager;
import android.view.WindowManagerGlobal; import android.view.WindowManagerGlobal;
import android.widget.Switch; 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.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.systemui.Dependency; 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.ActivityStarter;
import com.android.systemui.plugins.qs.QSTile.State; 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.QSHost;
import com.android.systemui.qs.external.TileLifecycleManager.TileChangeListener; import com.android.systemui.qs.external.TileLifecycleManager.TileChangeListener;
import com.android.systemui.qs.logging.QSLogger;
import com.android.systemui.qs.tileimpl.QSTileImpl; import com.android.systemui.qs.tileimpl.QSTileImpl;
import java.util.Objects; import java.util.Objects;
import javax.inject.Inject;
import dagger.Lazy;
public class CustomTile extends QSTileImpl<State> implements TileChangeListener { public class CustomTile extends QSTileImpl<State> implements TileChangeListener {
public static final String PREFIX = "custom("; public static final String PREFIX = "custom(";
@@ -79,8 +92,19 @@ public class CustomTile extends QSTileImpl<State> implements TileChangeListener
private boolean mIsTokenGranted; private boolean mIsTokenGranted;
private boolean mIsShowingDialog; private boolean mIsShowingDialog;
private CustomTile(QSHost host, String action, Context userContext) { private CustomTile(
super(host); 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(); mWindowManager = WindowManagerGlobal.getWindowManagerService();
mComponent = ComponentName.unflattenFromString(action); mComponent = ComponentName.unflattenFromString(action);
mTile = new Tile(); mTile = new Tile();
@@ -397,7 +421,7 @@ public class CustomTile extends QSTileImpl<State> implements TileChangeListener
return ComponentName.unflattenFromString(action); 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(")")) { if (spec == null || !spec.startsWith(PREFIX) || !spec.endsWith(")")) {
throw new IllegalArgumentException("Bad custom tile spec: " + spec); throw new IllegalArgumentException("Bad custom tile spec: " + spec);
} }
@@ -405,6 +429,81 @@ public class CustomTile extends QSTileImpl<State> implements TileChangeListener
if (action.isEmpty()) { if (action.isEmpty()) {
throw new IllegalArgumentException("Empty custom tile spec action"); 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 Provider<ScreenRecordTile> mScreenRecordTileProvider;
private final Lazy<QSHost> mQsHostLazy; private final Lazy<QSHost> mQsHostLazy;
private final Provider<CustomTile.Builder> mCustomTileBuilderProvider;
@Inject @Inject
public QSFactoryImpl(Lazy<QSHost> qsHostLazy, public QSFactoryImpl(
Lazy<QSHost> qsHostLazy,
Provider<CustomTile.Builder> customTileBuilderProvider,
Provider<WifiTile> wifiTileProvider, Provider<WifiTile> wifiTileProvider,
Provider<BluetoothTile> bluetoothTileProvider, Provider<BluetoothTile> bluetoothTileProvider,
Provider<CellularTile> cellularTileProvider, Provider<CellularTile> cellularTileProvider,
@@ -104,6 +107,8 @@ public class QSFactoryImpl implements QSFactory {
Provider<UiModeNightTile> uiModeNightTileProvider, Provider<UiModeNightTile> uiModeNightTileProvider,
Provider<ScreenRecordTile> screenRecordTileProvider) { Provider<ScreenRecordTile> screenRecordTileProvider) {
mQsHostLazy = qsHostLazy; mQsHostLazy = qsHostLazy;
mCustomTileBuilderProvider = customTileBuilderProvider;
mWifiTileProvider = wifiTileProvider; mWifiTileProvider = wifiTileProvider;
mBluetoothTileProvider = bluetoothTileProvider; mBluetoothTileProvider = bluetoothTileProvider;
mCellularTileProvider = cellularTileProvider; mCellularTileProvider = cellularTileProvider;
@@ -179,8 +184,8 @@ public class QSFactoryImpl implements QSFactory {
// Custom tiles // Custom tiles
if (tileSpec.startsWith(CustomTile.PREFIX)) { if (tileSpec.startsWith(CustomTile.PREFIX)) {
return CustomTile.create(mQsHostLazy.get(), tileSpec, return CustomTile.create(
mQsHostLazy.get().getUserContext()); mCustomTileBuilderProvider.get(), tileSpec, mQsHostLazy.get().getUserContext());
} }
// Debug tiles. // Debug tiles.

View File

@@ -14,6 +14,8 @@
package com.android.systemui.qs.tileimpl; 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.RESUMED;
import static androidx.lifecycle.Lifecycle.State.STARTED; 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.RestrictedLockUtils;
import com.android.settingslib.RestrictedLockUtilsInternal; import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.settingslib.Utils; import com.android.settingslib.Utils;
import com.android.systemui.Dependency;
import com.android.systemui.Dumpable; import com.android.systemui.Dumpable;
import com.android.systemui.Prefs; import com.android.systemui.Prefs;
import com.android.systemui.plugins.ActivityStarter; 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 QSHost mHost;
protected final Context mContext; protected final Context mContext;
// @NonFinalForTesting // @NonFinalForTesting
protected H mHandler = new H(Dependency.get(Dependency.BG_LOOPER)); protected final H mHandler;
protected final Handler mUiHandler = new Handler(Looper.getMainLooper()); protected final Handler mUiHandler;
private final ArraySet<Object> mListeners = new ArraySet<>(); private final ArraySet<Object> mListeners = new ArraySet<>();
private final MetricsLogger mMetricsLogger = Dependency.get(MetricsLogger.class); private final MetricsLogger mMetricsLogger;
private final StatusBarStateController private final StatusBarStateController mStatusBarStateController;
mStatusBarStateController = Dependency.get(StatusBarStateController.class); protected final ActivityStarter mActivityStarter;
private final UiEventLogger mUiEventLogger; private final UiEventLogger mUiEventLogger;
private final QSLogger mQSLogger; private final QSLogger mQSLogger;
@@ -150,14 +151,30 @@ public abstract class QSTileImpl<TState extends State> implements QSTile, Lifecy
*/ */
abstract public int getMetricsCategory(); 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; mHost = host;
mContext = host.getContext(); mContext = host.getContext();
mInstanceId = host.getNewInstanceId(); mInstanceId = host.getNewInstanceId();
mUiEventLogger = host.getUiEventLogger();
mUiHandler = mainHandler;
mHandler = new H(backgroundLooper);
mQSLogger = qsLogger;
mMetricsLogger = metricsLogger;
mStatusBarStateController = statusBarStateController;
mActivityStarter = activityStarter;
mState = newTileState(); mState = newTileState();
mTmpState = newTileState(); mTmpState = newTileState();
mQSLogger = host.getQSLogger(); mUiHandler.post(() -> mLifecycle.setCurrentState(CREATED));
mUiEventLogger = host.getUiEventLogger();
} }
protected final void resetStates() { protected final void resetStates() {
@@ -357,8 +374,7 @@ public abstract class QSTileImpl<TState extends State> implements QSTile, Lifecy
* {@link QSTileImpl#getLongClickIntent} * {@link QSTileImpl#getLongClickIntent}
*/ */
protected void handleLongClick() { protected void handleLongClick() {
Dependency.get(ActivityStarter.class).postStartActivityDismissingKeyguard( mActivityStarter.postStartActivityDismissingKeyguard(getLongClickIntent(), 0);
getLongClickIntent(), 0);
} }
/** /**
@@ -437,15 +453,24 @@ public abstract class QSTileImpl<TState extends State> implements QSTile, Lifecy
if (listening) { if (listening) {
if (mListeners.add(listener) && mListeners.size() == 1) { if (mListeners.add(listener) && mListeners.size() == 1) {
if (DEBUG) Log.d(TAG, "handleSetListening true"); if (DEBUG) Log.d(TAG, "handleSetListening true");
mLifecycle.setCurrentState(RESUMED);
handleSetListening(listening); 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 { } else {
if (mListeners.remove(listener) && mListeners.size() == 0) { if (mListeners.remove(listener) && mListeners.size() == 0) {
if (DEBUG) Log.d(TAG, "handleSetListening false"); if (DEBUG) Log.d(TAG, "handleSetListening false");
mLifecycle.setCurrentState(STARTED);
handleSetListening(listening); 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(); updateIsFullQs();
@@ -472,9 +497,14 @@ public abstract class QSTileImpl<TState extends State> implements QSTile, Lifecy
mQSLogger.logTileDestroyed(mTileSpec, "Handle destroy"); mQSLogger.logTileDestroyed(mTileSpec, "Handle destroy");
if (mListeners.size() != 0) { if (mListeners.size() != 0) {
handleSetListening(false); handleSetListening(false);
mListeners.clear();
} }
mCallbacks.clear(); mCallbacks.clear();
mHandler.removeCallbacksAndMessages(null); 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) { 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_CALLBACKS = 11;
private static final int REMOVE_CALLBACK = 12; private static final int REMOVE_CALLBACK = 12;
private static final int SET_LISTENING = 13; private static final int SET_LISTENING = 13;
private static final int STALE = 14; @VisibleForTesting
protected static final int STALE = 14;
@VisibleForTesting @VisibleForTesting
protected H(Looper looper) { protected H(Looper looper) {
@@ -555,8 +586,7 @@ public abstract class QSTileImpl<TState extends State> implements QSTile, Lifecy
if (mState.disabledByPolicy) { if (mState.disabledByPolicy) {
Intent intent = RestrictedLockUtils.getShowAdminSupportDetailsIntent( Intent intent = RestrictedLockUtils.getShowAdminSupportDetailsIntent(
mContext, mEnforcedAdmin); mContext, mEnforcedAdmin);
Dependency.get(ActivityStarter.class).postStartActivityDismissingKeyguard( mActivityStarter.postStartActivityDismissingKeyguard(intent, 0);
intent, 0);
} else { } else {
handleClick(); handleClick();
} }

View File

@@ -21,6 +21,8 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
import android.net.ConnectivityManager; import android.net.ConnectivityManager;
import android.os.Handler;
import android.os.Looper;
import android.os.UserManager; import android.os.UserManager;
import android.provider.Settings; import android.provider.Settings;
import android.provider.Settings.Global; 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.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.systemui.R; import com.android.systemui.R;
import com.android.systemui.broadcast.BroadcastDispatcher; 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.ActivityStarter;
import com.android.systemui.plugins.qs.QSTile.BooleanState; 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.GlobalSetting;
import com.android.systemui.qs.QSHost; import com.android.systemui.qs.QSHost;
import com.android.systemui.qs.logging.QSLogger;
import com.android.systemui.qs.tileimpl.QSTileImpl; import com.android.systemui.qs.tileimpl.QSTileImpl;
import javax.inject.Inject; import javax.inject.Inject;
import dagger.Lazy;
/** Quick settings tile: Airplane mode **/ /** Quick settings tile: Airplane mode **/
public class AirplaneModeTile extends QSTileImpl<BooleanState> { public class AirplaneModeTile extends QSTileImpl<BooleanState> {
private final Icon mIcon = ResourceIcon.get(com.android.internal.R.drawable.ic_qs_airplane); private final Icon mIcon = ResourceIcon.get(com.android.internal.R.drawable.ic_qs_airplane);
private final GlobalSetting mSetting; private final GlobalSetting mSetting;
private final ActivityStarter mActivityStarter;
private final BroadcastDispatcher mBroadcastDispatcher; private final BroadcastDispatcher mBroadcastDispatcher;
private final Lazy<ConnectivityManager> mLazyConnectivityManager;
private boolean mListening; private boolean mListening;
@Inject @Inject
public AirplaneModeTile(QSHost host, ActivityStarter activityStarter, public AirplaneModeTile(
BroadcastDispatcher broadcastDispatcher) { QSHost host,
super(host); @Background Looper backgroundLooper,
mActivityStarter = activityStarter; @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; mBroadcastDispatcher = broadcastDispatcher;
mLazyConnectivityManager = lazyConnectivityManager;
mSetting = new GlobalSetting(mContext, mHandler, Global.AIRPLANE_MODE_ON) { mSetting = new GlobalSetting(mContext, mHandler, Global.AIRPLANE_MODE_ON) {
@Override @Override
protected void handleValueChanged(int value) { protected void handleValueChanged(int value) {
// mHandler is the background handler so calling this is OK
handleRefreshState(value); handleRefreshState(value);
} }
}; };
@@ -83,9 +102,7 @@ public class AirplaneModeTile extends QSTileImpl<BooleanState> {
} }
private void setEnabled(boolean enabled) { private void setEnabled(boolean enabled) {
final ConnectivityManager mgr = mLazyConnectivityManager.get().setAirplaneMode(enabled);
(ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
mgr.setAirplaneMode(enabled);
} }
@Override @Override

View File

@@ -16,16 +16,24 @@
package com.android.systemui.qs.tiles; package com.android.systemui.qs.tiles;
import android.content.Intent; import android.content.Intent;
import android.os.Handler;
import android.os.Looper;
import android.provider.Settings.Secure; import android.provider.Settings.Secure;
import android.service.quicksettings.Tile; import android.service.quicksettings.Tile;
import android.widget.Switch; import android.widget.Switch;
import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.systemui.R; 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.qs.QSTile.BooleanState;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.qs.QSHost; import com.android.systemui.qs.QSHost;
import com.android.systemui.qs.SecureSetting; import com.android.systemui.qs.SecureSetting;
import com.android.systemui.qs.logging.QSLogger;
import com.android.systemui.qs.tileimpl.QSTileImpl; import com.android.systemui.qs.tileimpl.QSTileImpl;
import com.android.systemui.statusbar.policy.BatteryController; 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); private Icon mIcon = ResourceIcon.get(com.android.internal.R.drawable.ic_qs_battery_saver);
@Inject @Inject
public BatterySaverTile(QSHost host, BatteryController batteryController) { public BatterySaverTile(
super(host); 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 = batteryController;
mBatteryController.observe(getLifecycle(), this); mBatteryController.observe(getLifecycle(), this);
int currentUser = host.getUserContext().getUserId(); int currentUser = host.getUserContext().getUserId();
@@ -55,6 +73,7 @@ public class BatterySaverTile extends QSTileImpl<BooleanState> implements
currentUser) { currentUser) {
@Override @Override
protected void handleValueChanged(int value, boolean observedChange) { protected void handleValueChanged(int value, boolean observedChange) {
// mHandler is the background handler so calling this is OK
handleRefreshState(null); handleRefreshState(null);
} }
}; };

View File

@@ -24,6 +24,8 @@ import android.bluetooth.BluetoothProfile;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Looper;
import android.provider.Settings; import android.provider.Settings;
import android.service.quicksettings.Tile; import android.service.quicksettings.Tile;
import android.text.TextUtils; import android.text.TextUtils;
@@ -37,12 +39,16 @@ import com.android.settingslib.Utils;
import com.android.settingslib.bluetooth.CachedBluetoothDevice; import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.settingslib.graph.BluetoothDeviceLayerDrawable; import com.android.settingslib.graph.BluetoothDeviceLayerDrawable;
import com.android.systemui.R; 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.ActivityStarter;
import com.android.systemui.plugins.qs.DetailAdapter; import com.android.systemui.plugins.qs.DetailAdapter;
import com.android.systemui.plugins.qs.QSTile.BooleanState; 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;
import com.android.systemui.qs.QSDetailItems.Item; import com.android.systemui.qs.QSDetailItems.Item;
import com.android.systemui.qs.QSHost; import com.android.systemui.qs.QSHost;
import com.android.systemui.qs.logging.QSLogger;
import com.android.systemui.qs.tileimpl.QSTileImpl; import com.android.systemui.qs.tileimpl.QSTileImpl;
import com.android.systemui.statusbar.policy.BluetoothController; import com.android.systemui.statusbar.policy.BluetoothController;
@@ -58,15 +64,21 @@ public class BluetoothTile extends QSTileImpl<BooleanState> {
private final BluetoothController mController; private final BluetoothController mController;
private final BluetoothDetailAdapter mDetailAdapter; private final BluetoothDetailAdapter mDetailAdapter;
private final ActivityStarter mActivityStarter;
@Inject @Inject
public BluetoothTile(QSHost host, public BluetoothTile(
BluetoothController bluetoothController, QSHost host,
ActivityStarter activityStarter) { @Background Looper backgroundLooper,
super(host); @Main Handler mainHandler,
MetricsLogger metricsLogger,
StatusBarStateController statusBarStateController,
ActivityStarter activityStarter,
QSLogger qsLogger,
BluetoothController bluetoothController
) {
super(host, backgroundLooper, mainHandler, metricsLogger, statusBarStateController,
activityStarter, qsLogger);
mController = bluetoothController; mController = bluetoothController;
mActivityStarter = activityStarter;
mDetailAdapter = (BluetoothDetailAdapter) createDetailAdapter(); mDetailAdapter = (BluetoothDetailAdapter) createDetailAdapter();
mController.observe(getLifecycle(), mCallback); mController.observe(getLifecycle(), mCallback);
} }

View File

@@ -22,6 +22,8 @@ import android.app.Dialog;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.media.MediaRouter.RouteInfo; import android.media.MediaRouter.RouteInfo;
import android.os.Handler;
import android.os.Looper;
import android.provider.Settings; import android.provider.Settings;
import android.service.quicksettings.Tile; import android.service.quicksettings.Tile;
import android.util.Log; 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.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.systemui.R; 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.ActivityStarter;
import com.android.systemui.plugins.qs.DetailAdapter; import com.android.systemui.plugins.qs.DetailAdapter;
import com.android.systemui.plugins.qs.QSTile.BooleanState; 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;
import com.android.systemui.qs.QSDetailItems.Item; import com.android.systemui.qs.QSDetailItems.Item;
import com.android.systemui.qs.QSHost; import com.android.systemui.qs.QSHost;
import com.android.systemui.qs.logging.QSLogger;
import com.android.systemui.qs.tileimpl.QSTileImpl; import com.android.systemui.qs.tileimpl.QSTileImpl;
import com.android.systemui.statusbar.phone.SystemUIDialog; import com.android.systemui.statusbar.phone.SystemUIDialog;
import com.android.systemui.statusbar.policy.CastController; import com.android.systemui.statusbar.policy.CastController;
@@ -64,20 +70,28 @@ public class CastTile extends QSTileImpl<BooleanState> {
private final KeyguardStateController mKeyguard; private final KeyguardStateController mKeyguard;
private final NetworkController mNetworkController; private final NetworkController mNetworkController;
private final Callback mCallback = new Callback(); private final Callback mCallback = new Callback();
private final ActivityStarter mActivityStarter;
private Dialog mDialog; private Dialog mDialog;
private boolean mWifiConnected; private boolean mWifiConnected;
@Inject @Inject
public CastTile(QSHost host, CastController castController, public CastTile(
KeyguardStateController keyguardStateController, NetworkController networkController, QSHost host,
ActivityStarter activityStarter) { @Background Looper backgroundLooper,
super(host); @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; mController = castController;
mDetailAdapter = new CastDetailAdapter(); mDetailAdapter = new CastDetailAdapter();
mKeyguard = keyguardStateController; mKeyguard = keyguardStateController;
mNetworkController = networkController; mNetworkController = networkController;
mActivityStarter = activityStarter;
mController.observe(this, mCallback); mController.observe(this, mCallback);
mKeyguard.observe(this, mCallback); mKeyguard.observe(this, mCallback);
mNetworkController.observe(this, mSignalCallback); mNetworkController.observe(this, mSignalCallback);

View File

@@ -23,6 +23,8 @@ import android.app.AlertDialog.Builder;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.res.Resources; import android.content.res.Resources;
import android.os.Handler;
import android.os.Looper;
import android.os.UserHandle; import android.os.UserHandle;
import android.provider.Settings; import android.provider.Settings;
import android.service.quicksettings.Tile; 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.settingslib.net.DataUsageController;
import com.android.systemui.Prefs; import com.android.systemui.Prefs;
import com.android.systemui.R; 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.ActivityStarter;
import com.android.systemui.plugins.qs.DetailAdapter; import com.android.systemui.plugins.qs.DetailAdapter;
import com.android.systemui.plugins.qs.QSIconView; import com.android.systemui.plugins.qs.QSIconView;
import com.android.systemui.plugins.qs.QSTile.SignalState; 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.QSHost;
import com.android.systemui.qs.SignalTileView; import com.android.systemui.qs.SignalTileView;
import com.android.systemui.qs.logging.QSLogger;
import com.android.systemui.qs.tileimpl.QSTileImpl; import com.android.systemui.qs.tileimpl.QSTileImpl;
import com.android.systemui.statusbar.phone.SystemUIDialog; import com.android.systemui.statusbar.phone.SystemUIDialog;
import com.android.systemui.statusbar.policy.NetworkController; import com.android.systemui.statusbar.policy.NetworkController;
@@ -63,14 +69,21 @@ public class CellularTile extends QSTileImpl<SignalState> {
private final CellularDetailAdapter mDetailAdapter; private final CellularDetailAdapter mDetailAdapter;
private final CellSignalCallback mSignalCallback = new CellSignalCallback(); private final CellSignalCallback mSignalCallback = new CellSignalCallback();
private final ActivityStarter mActivityStarter;
@Inject @Inject
public CellularTile(QSHost host, NetworkController networkController, public CellularTile(
ActivityStarter activityStarter) { QSHost host,
super(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; mController = networkController;
mActivityStarter = activityStarter;
mDataController = mController.getMobileDataController(); mDataController = mController.getMobileDataController();
mDetailAdapter = new CellularDetailAdapter(); mDetailAdapter = new CellularDetailAdapter();
mController.observe(getLifecycle(), mSignalCallback); mController.observe(getLifecycle(), mSignalCallback);

View File

@@ -17,17 +17,25 @@
package com.android.systemui.qs.tiles; package com.android.systemui.qs.tiles;
import android.content.Intent; import android.content.Intent;
import android.os.Handler;
import android.os.Looper;
import android.provider.Settings; import android.provider.Settings;
import android.provider.Settings.Secure; import android.provider.Settings.Secure;
import android.service.quicksettings.Tile; import android.service.quicksettings.Tile;
import android.widget.Switch; import android.widget.Switch;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.systemui.R; import com.android.systemui.R;
import com.android.systemui.R.drawable; 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.qs.QSTile.BooleanState;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.qs.QSHost; import com.android.systemui.qs.QSHost;
import com.android.systemui.qs.SecureSetting; import com.android.systemui.qs.SecureSetting;
import com.android.systemui.qs.logging.QSLogger;
import com.android.systemui.qs.tileimpl.QSTileImpl; import com.android.systemui.qs.tileimpl.QSTileImpl;
import javax.inject.Inject; import javax.inject.Inject;
@@ -41,13 +49,23 @@ public class ColorInversionTile extends QSTileImpl<BooleanState> {
private boolean mListening; private boolean mListening;
@Inject @Inject
public ColorInversionTile(QSHost host) { public ColorInversionTile(
super(host); 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) { Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED) {
@Override @Override
protected void handleValueChanged(int value, boolean observedChange) { protected void handleValueChanged(int value, boolean observedChange) {
// mHandler is the background handler so calling this is OK
handleRefreshState(value); handleRefreshState(value);
} }
}; };

View File

@@ -16,19 +16,26 @@ package com.android.systemui.qs.tiles;
import android.content.DialogInterface.OnClickListener; import android.content.DialogInterface.OnClickListener;
import android.content.Intent; import android.content.Intent;
import android.os.Handler;
import android.os.Looper;
import android.provider.Settings; import android.provider.Settings;
import android.service.quicksettings.Tile; import android.service.quicksettings.Tile;
import android.widget.Switch; import android.widget.Switch;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.systemui.Prefs; import com.android.systemui.Prefs;
import com.android.systemui.R; 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.qs.QSTile.BooleanState;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.qs.QSHost; import com.android.systemui.qs.QSHost;
import com.android.systemui.qs.logging.QSLogger;
import com.android.systemui.qs.tileimpl.QSTileImpl; import com.android.systemui.qs.tileimpl.QSTileImpl;
import com.android.systemui.statusbar.phone.SystemUIDialog; import com.android.systemui.statusbar.phone.SystemUIDialog;
import com.android.systemui.statusbar.policy.DataSaverController; import com.android.systemui.statusbar.policy.DataSaverController;
import com.android.systemui.statusbar.policy.NetworkController;
import javax.inject.Inject; import javax.inject.Inject;
@@ -38,9 +45,19 @@ public class DataSaverTile extends QSTileImpl<BooleanState> implements
private final DataSaverController mDataSaverController; private final DataSaverController mDataSaverController;
@Inject @Inject
public DataSaverTile(QSHost host, NetworkController networkController) { public DataSaverTile(
super(host); QSHost host,
mDataSaverController = networkController.getDataSaverController(); @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); mDataSaverController.observe(getLifecycle(), this);
} }

View File

@@ -30,6 +30,8 @@ import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.content.pm.ApplicationInfo; import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.net.Uri; import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
import android.os.UserManager; import android.os.UserManager;
import android.provider.Settings; import android.provider.Settings;
import android.provider.Settings.Global; import android.provider.Settings.Global;
@@ -53,11 +55,14 @@ import com.android.systemui.Prefs;
import com.android.systemui.R; import com.android.systemui.R;
import com.android.systemui.SysUIToast; import com.android.systemui.SysUIToast;
import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.qs.DetailAdapter; import com.android.systemui.plugins.qs.DetailAdapter;
import com.android.systemui.plugins.qs.QSTile.BooleanState; 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.QSHost;
import com.android.systemui.qs.logging.QSLogger;
import com.android.systemui.qs.tileimpl.QSTileImpl; import com.android.systemui.qs.tileimpl.QSTileImpl;
import com.android.systemui.statusbar.phone.SystemUIDialog; import com.android.systemui.statusbar.phone.SystemUIDialog;
import com.android.systemui.statusbar.policy.ZenModeController; import com.android.systemui.statusbar.policy.ZenModeController;
@@ -79,7 +84,6 @@ public class DndTile extends QSTileImpl<BooleanState> {
private final ZenModeController mController; private final ZenModeController mController;
private final DndDetailAdapter mDetailAdapter; private final DndDetailAdapter mDetailAdapter;
private final ActivityStarter mActivityStarter;
private final SharedPreferences mSharedPreferences; private final SharedPreferences mSharedPreferences;
private final BroadcastDispatcher mBroadcastDispatcher; private final BroadcastDispatcher mBroadcastDispatcher;
@@ -88,12 +92,21 @@ public class DndTile extends QSTileImpl<BooleanState> {
private boolean mReceiverRegistered; private boolean mReceiverRegistered;
@Inject @Inject
public DndTile(QSHost host, ZenModeController zenModeController, public DndTile(
ActivityStarter activityStarter, BroadcastDispatcher broadcastDispatcher, QSHost host,
@Main SharedPreferences sharedPreferences) { @Background Looper backgroundLooper,
super(host); @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; mController = zenModeController;
mActivityStarter = activityStarter;
mSharedPreferences = sharedPreferences; mSharedPreferences = sharedPreferences;
mDetailAdapter = new DndDetailAdapter(); mDetailAdapter = new DndDetailAdapter();
mBroadcastDispatcher = broadcastDispatcher; mBroadcastDispatcher = broadcastDispatcher;

View File

@@ -18,14 +18,22 @@ package com.android.systemui.qs.tiles;
import android.app.ActivityManager; import android.app.ActivityManager;
import android.content.Intent; import android.content.Intent;
import android.os.Handler;
import android.os.Looper;
import android.provider.MediaStore; import android.provider.MediaStore;
import android.service.quicksettings.Tile; import android.service.quicksettings.Tile;
import android.widget.Switch; import android.widget.Switch;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.systemui.R; 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.qs.QSTile.BooleanState;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.qs.QSHost; import com.android.systemui.qs.QSHost;
import com.android.systemui.qs.logging.QSLogger;
import com.android.systemui.qs.tileimpl.QSTileImpl; import com.android.systemui.qs.tileimpl.QSTileImpl;
import com.android.systemui.statusbar.policy.FlashlightController; import com.android.systemui.statusbar.policy.FlashlightController;
@@ -39,8 +47,18 @@ public class FlashlightTile extends QSTileImpl<BooleanState> implements
private final FlashlightController mFlashlightController; private final FlashlightController mFlashlightController;
@Inject @Inject
public FlashlightTile(QSHost host, FlashlightController flashlightController) { public FlashlightTile(
super(host); 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 = flashlightController;
mFlashlightController.observe(getLifecycle(), this); mFlashlightController.observe(getLifecycle(), this);
} }

View File

@@ -18,16 +18,24 @@ package com.android.systemui.qs.tiles;
import android.annotation.Nullable; import android.annotation.Nullable;
import android.content.Intent; import android.content.Intent;
import android.os.Handler;
import android.os.Looper;
import android.os.UserManager; import android.os.UserManager;
import android.provider.Settings; import android.provider.Settings;
import android.service.quicksettings.Tile; import android.service.quicksettings.Tile;
import android.util.Log; import android.util.Log;
import android.widget.Switch; import android.widget.Switch;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.systemui.R; 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.qs.QSTile.BooleanState;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.qs.QSHost; import com.android.systemui.qs.QSHost;
import com.android.systemui.qs.logging.QSLogger;
import com.android.systemui.qs.tileimpl.QSTileImpl; import com.android.systemui.qs.tileimpl.QSTileImpl;
import com.android.systemui.statusbar.policy.DataSaverController; import com.android.systemui.statusbar.policy.DataSaverController;
import com.android.systemui.statusbar.policy.HotspotController; import com.android.systemui.statusbar.policy.HotspotController;
@@ -45,9 +53,19 @@ public class HotspotTile extends QSTileImpl<BooleanState> {
private boolean mListening; private boolean mListening;
@Inject @Inject
public HotspotTile(QSHost host, HotspotController hotspotController, public HotspotTile(
DataSaverController dataSaverController) { QSHost host,
super(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; mHotspotController = hotspotController;
mDataSaverController = dataSaverController; mDataSaverController = dataSaverController;
mHotspotController.observe(this, mCallbacks); mHotspotController.observe(this, mCallbacks);

View File

@@ -17,16 +17,23 @@
package com.android.systemui.qs.tiles; package com.android.systemui.qs.tiles;
import android.content.Intent; import android.content.Intent;
import android.os.Handler;
import android.os.Looper;
import android.os.UserManager; import android.os.UserManager;
import android.provider.Settings; import android.provider.Settings;
import android.service.quicksettings.Tile; import android.service.quicksettings.Tile;
import android.widget.Switch; import android.widget.Switch;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.systemui.R; 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.ActivityStarter;
import com.android.systemui.plugins.qs.QSTile.BooleanState; 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.QSHost;
import com.android.systemui.qs.logging.QSLogger;
import com.android.systemui.qs.tileimpl.QSTileImpl; import com.android.systemui.qs.tileimpl.QSTileImpl;
import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.statusbar.policy.LocationController; import com.android.systemui.statusbar.policy.LocationController;
@@ -41,16 +48,24 @@ public class LocationTile extends QSTileImpl<BooleanState> {
private final LocationController mController; private final LocationController mController;
private final KeyguardStateController mKeyguard; private final KeyguardStateController mKeyguard;
private final ActivityStarter mActivityStarter;
private final Callback mCallback = new Callback(); private final Callback mCallback = new Callback();
@Inject @Inject
public LocationTile(QSHost host, LocationController locationController, public LocationTile(
KeyguardStateController keyguardStateController, ActivityStarter activityStarter) { QSHost host,
super(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; mController = locationController;
mKeyguard = keyguardStateController; mKeyguard = keyguardStateController;
mActivityStarter = activityStarter;
mController.observe(this, mCallback); mController.observe(this, mCallback);
mKeyguard.observe(this, mCallback); mKeyguard.observe(this, mCallback);
} }

View File

@@ -23,15 +23,23 @@ import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.nfc.NfcAdapter; import android.nfc.NfcAdapter;
import android.os.Handler;
import android.os.Looper;
import android.provider.Settings; import android.provider.Settings;
import android.service.quicksettings.Tile; import android.service.quicksettings.Tile;
import android.widget.Switch; import android.widget.Switch;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.systemui.R; import com.android.systemui.R;
import com.android.systemui.broadcast.BroadcastDispatcher; 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.qs.QSTile.BooleanState;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.qs.QSHost; import com.android.systemui.qs.QSHost;
import com.android.systemui.qs.logging.QSLogger;
import com.android.systemui.qs.tileimpl.QSTileImpl; import com.android.systemui.qs.tileimpl.QSTileImpl;
import javax.inject.Inject; import javax.inject.Inject;
@@ -47,8 +55,18 @@ public class NfcTile extends QSTileImpl<BooleanState> {
private boolean mListening; private boolean mListening;
@Inject @Inject
public NfcTile(QSHost host, BroadcastDispatcher broadcastDispatcher) { public NfcTile(
super(host); 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; mBroadcastDispatcher = broadcastDispatcher;
} }

View File

@@ -33,10 +33,16 @@ import android.widget.Switch;
import androidx.annotation.StringRes; import androidx.annotation.StringRes;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.systemui.R; 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.qs.QSTile.BooleanState;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.qs.QSHost; import com.android.systemui.qs.QSHost;
import com.android.systemui.qs.logging.QSLogger;
import com.android.systemui.qs.tileimpl.QSTileImpl; import com.android.systemui.qs.tileimpl.QSTileImpl;
import com.android.systemui.statusbar.policy.LocationController; import com.android.systemui.statusbar.policy.LocationController;
@@ -66,11 +72,22 @@ public class NightDisplayTile extends QSTileImpl<BooleanState> implements
private boolean mIsListening; private boolean mIsListening;
@Inject @Inject
public NightDisplayTile(QSHost host, LocationController locationController) { public NightDisplayTile(
super(host); 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; mLocationController = locationController;
mManager = mContext.getSystemService(ColorDisplayManager.class); mManager = colorDisplayManager;
mListener = new NightDisplayListener(mContext, new Handler(Looper.myLooper())); mListener = new NightDisplayListener(mContext, mainHandler);
} }
@Override @Override

View File

@@ -19,14 +19,22 @@ package com.android.systemui.qs.tiles;
import android.content.Intent; import android.content.Intent;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.content.res.Resources; import android.content.res.Resources;
import android.os.Handler;
import android.os.Looper;
import android.provider.Settings; import android.provider.Settings;
import android.service.quicksettings.Tile; import android.service.quicksettings.Tile;
import android.widget.Switch; import android.widget.Switch;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.systemui.R; 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.qs.QSTile.BooleanState;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.qs.QSHost; import com.android.systemui.qs.QSHost;
import com.android.systemui.qs.logging.QSLogger;
import com.android.systemui.qs.tileimpl.QSTileImpl; import com.android.systemui.qs.tileimpl.QSTileImpl;
import com.android.systemui.statusbar.policy.RotationLockController; import com.android.systemui.statusbar.policy.RotationLockController;
import com.android.systemui.statusbar.policy.RotationLockController.RotationLockControllerCallback; import com.android.systemui.statusbar.policy.RotationLockController.RotationLockControllerCallback;
@@ -40,8 +48,18 @@ public class RotationLockTile extends QSTileImpl<BooleanState> {
private final RotationLockController mController; private final RotationLockController mController;
@Inject @Inject
public RotationLockTile(QSHost host, RotationLockController rotationLockController) { public RotationLockTile(
super(host); 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 = rotationLockController;
mController.observe(this, mCallback); mController.observe(this, mCallback);
} }

View File

@@ -17,15 +17,22 @@
package com.android.systemui.qs.tiles; package com.android.systemui.qs.tiles;
import android.content.Intent; import android.content.Intent;
import android.os.Handler;
import android.os.Looper;
import android.service.quicksettings.Tile; import android.service.quicksettings.Tile;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import android.widget.Switch; import android.widget.Switch;
import com.android.internal.logging.MetricsLogger;
import com.android.systemui.R; 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.ActivityStarter;
import com.android.systemui.plugins.qs.QSTile; 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.QSHost;
import com.android.systemui.qs.logging.QSLogger;
import com.android.systemui.qs.tileimpl.QSTileImpl; import com.android.systemui.qs.tileimpl.QSTileImpl;
import com.android.systemui.screenrecord.RecordingController; import com.android.systemui.screenrecord.RecordingController;
import com.android.systemui.statusbar.phone.KeyguardDismissUtil; import com.android.systemui.statusbar.phone.KeyguardDismissUtil;
@@ -44,9 +51,19 @@ public class ScreenRecordTile extends QSTileImpl<QSTile.BooleanState>
private Callback mCallback = new Callback(); private Callback mCallback = new Callback();
@Inject @Inject
public ScreenRecordTile(QSHost host, RecordingController controller, public ScreenRecordTile(
KeyguardDismissUtil keyguardDismissUtil) { QSHost host,
super(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 = controller;
mController.observe(this, mCallback); mController.observe(this, mCallback);
mKeyguardDismissUtil = keyguardDismissUtil; mKeyguardDismissUtil = keyguardDismissUtil;

View File

@@ -19,15 +19,23 @@ package com.android.systemui.qs.tiles;
import android.app.UiModeManager; import android.app.UiModeManager;
import android.content.Intent; import android.content.Intent;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.os.Handler;
import android.os.Looper;
import android.provider.Settings; import android.provider.Settings;
import android.service.quicksettings.Tile; import android.service.quicksettings.Tile;
import android.text.TextUtils; import android.text.TextUtils;
import android.widget.Switch; import android.widget.Switch;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto; import com.android.internal.logging.nano.MetricsProto;
import com.android.systemui.R; 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.qs.QSTile;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.qs.QSHost; import com.android.systemui.qs.QSHost;
import com.android.systemui.qs.logging.QSLogger;
import com.android.systemui.qs.tileimpl.QSTileImpl; import com.android.systemui.qs.tileimpl.QSTileImpl;
import com.android.systemui.statusbar.policy.BatteryController; import com.android.systemui.statusbar.policy.BatteryController;
import com.android.systemui.statusbar.policy.ConfigurationController; 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 BatteryController mBatteryController;
private final LocationController mLocationController; private final LocationController mLocationController;
@Inject @Inject
public UiModeNightTile(QSHost host, ConfigurationController configurationController, public UiModeNightTile(
BatteryController batteryController, LocationController locationController) { QSHost host,
super(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; mBatteryController = batteryController;
mUiModeManager = host.getUserContext().getSystemService(UiModeManager.class); mUiModeManager = host.getUserContext().getSystemService(UiModeManager.class);
mLocationController = locationController; mLocationController = locationController;

View File

@@ -18,14 +18,22 @@ package com.android.systemui.qs.tiles;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Looper;
import android.provider.Settings; import android.provider.Settings;
import android.util.Pair; import android.util.Pair;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent; 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.DetailAdapter;
import com.android.systemui.plugins.qs.QSTile; import com.android.systemui.plugins.qs.QSTile;
import com.android.systemui.plugins.qs.QSTile.State; 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.QSHost;
import com.android.systemui.qs.logging.QSLogger;
import com.android.systemui.qs.tileimpl.QSTileImpl; import com.android.systemui.qs.tileimpl.QSTileImpl;
import com.android.systemui.statusbar.policy.UserInfoController; import com.android.systemui.statusbar.policy.UserInfoController;
import com.android.systemui.statusbar.policy.UserSwitcherController; 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; private Pair<String, Drawable> mLastUpdate;
@Inject @Inject
public UserTile(QSHost host, UserSwitcherController userSwitcherController, public UserTile(
UserInfoController userInfoController) { QSHost host,
super(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; mUserSwitcherController = userSwitcherController;
mUserInfoController = userInfoController; mUserInfoController = userInfoController;
mUserInfoController.observe(getLifecycle(), this); mUserInfoController.observe(getLifecycle(), this);

View File

@@ -20,6 +20,8 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.content.res.Resources; import android.content.res.Resources;
import android.os.Handler;
import android.os.Looper;
import android.provider.Settings; import android.provider.Settings;
import android.service.quicksettings.Tile; import android.service.quicksettings.Tile;
import android.text.TextUtils; 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.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settingslib.wifi.AccessPoint; import com.android.settingslib.wifi.AccessPoint;
import com.android.systemui.R; 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.ActivityStarter;
import com.android.systemui.plugins.qs.DetailAdapter; import com.android.systemui.plugins.qs.DetailAdapter;
import com.android.systemui.plugins.qs.QSIconView; import com.android.systemui.plugins.qs.QSIconView;
import com.android.systemui.plugins.qs.QSTile; import com.android.systemui.plugins.qs.QSTile;
import com.android.systemui.plugins.qs.QSTile.SignalState; 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.AlphaControlledSignalTileView;
import com.android.systemui.qs.QSDetailItems; import com.android.systemui.qs.QSDetailItems;
import com.android.systemui.qs.QSDetailItems.Item; import com.android.systemui.qs.QSDetailItems.Item;
import com.android.systemui.qs.QSHost; 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.QSIconViewImpl;
import com.android.systemui.qs.tileimpl.QSTileImpl; import com.android.systemui.qs.tileimpl.QSTileImpl;
import com.android.systemui.statusbar.policy.NetworkController; import com.android.systemui.statusbar.policy.NetworkController;
@@ -63,17 +69,24 @@ public class WifiTile extends QSTileImpl<SignalState> {
private final QSTile.SignalState mStateBeforeClick = newTileState(); private final QSTile.SignalState mStateBeforeClick = newTileState();
protected final WifiSignalCallback mSignalCallback = new WifiSignalCallback(); protected final WifiSignalCallback mSignalCallback = new WifiSignalCallback();
private final ActivityStarter mActivityStarter;
private boolean mExpectDisabled; private boolean mExpectDisabled;
@Inject @Inject
public WifiTile(QSHost host, NetworkController networkController, public WifiTile(
ActivityStarter activityStarter) { QSHost host,
super(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; mController = networkController;
mWifiController = mController.getAccessPointController(); mWifiController = mController.getAccessPointController();
mDetailAdapter = (WifiDetailAdapter) createDetailAdapter(); mDetailAdapter = (WifiDetailAdapter) createDetailAdapter();
mActivityStarter = activityStarter;
mController.observe(getLifecycle(), mSignalCallback); mController.observe(getLifecycle(), mSignalCallback);
} }

View File

@@ -17,14 +17,22 @@
package com.android.systemui.qs.tiles; package com.android.systemui.qs.tiles;
import android.content.Intent; import android.content.Intent;
import android.os.Handler;
import android.os.Looper;
import android.provider.Settings; import android.provider.Settings;
import android.service.quicksettings.Tile; import android.service.quicksettings.Tile;
import android.widget.Switch; import android.widget.Switch;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.systemui.R; 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.qs.QSTile.BooleanState;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.qs.QSHost; import com.android.systemui.qs.QSHost;
import com.android.systemui.qs.logging.QSLogger;
import com.android.systemui.qs.tileimpl.QSTileImpl; import com.android.systemui.qs.tileimpl.QSTileImpl;
import com.android.systemui.statusbar.phone.ManagedProfileController; import com.android.systemui.statusbar.phone.ManagedProfileController;
@@ -38,8 +46,18 @@ public class WorkModeTile extends QSTileImpl<BooleanState> implements
private final ManagedProfileController mProfileController; private final ManagedProfileController mProfileController;
@Inject @Inject
public WorkModeTile(QSHost host, ManagedProfileController managedProfileController) { public WorkModeTile(
super(host); 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 = managedProfileController;
mProfileController.observe(getLifecycle(), this); mProfileController.observe(getLifecycle(), this);
} }

View File

@@ -44,13 +44,17 @@ import android.text.format.DateUtils;
import android.util.Log; import android.util.Log;
import android.util.LongSparseArray; import android.util.LongSparseArray;
import com.android.internal.logging.MetricsLogger;
import com.android.systemui.Dumpable; import com.android.systemui.Dumpable;
import com.android.systemui.R; import com.android.systemui.R;
import com.android.systemui.SystemUI; import com.android.systemui.SystemUI;
import com.android.systemui.dagger.qualifiers.Background; 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.ActivityStarter;
import com.android.systemui.plugins.qs.QSTile; 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.QSHost;
import com.android.systemui.qs.logging.QSLogger;
import com.android.systemui.qs.tileimpl.QSTileImpl; import com.android.systemui.qs.tileimpl.QSTileImpl;
import java.io.FileDescriptor; import java.io.FileDescriptor;
@@ -396,15 +400,23 @@ public class GarbageMonitor implements Dumpable {
public static final String TILE_SPEC = "dbg:mem"; public static final String TILE_SPEC = "dbg:mem";
private final GarbageMonitor gm; private final GarbageMonitor gm;
private final ActivityStarter mActivityStarter;
private ProcessMemInfo pmi; private ProcessMemInfo pmi;
private boolean dumpInProgress; private boolean dumpInProgress;
@Inject @Inject
public MemoryTile(QSHost host, GarbageMonitor monitor, ActivityStarter starter) { public MemoryTile(
super(host); 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; gm = monitor;
mActivityStarter = starter;
} }
@Override @Override

View File

@@ -41,14 +41,17 @@ import android.testing.TestableLooper.RunWithLooper;
import androidx.test.filters.SmallTest; import androidx.test.filters.SmallTest;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.UiEventLogger; import com.android.internal.logging.UiEventLogger;
import com.android.internal.util.CollectionUtils; import com.android.internal.util.CollectionUtils;
import com.android.systemui.R; import com.android.systemui.R;
import com.android.systemui.SysuiTestCase; import com.android.systemui.SysuiTestCase;
import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dump.DumpManager; 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.QSFactory;
import com.android.systemui.plugins.qs.QSTile; import com.android.systemui.plugins.qs.QSTile;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.qs.external.CustomTile; import com.android.systemui.qs.external.CustomTile;
import com.android.systemui.qs.logging.QSLogger; import com.android.systemui.qs.logging.QSLogger;
import com.android.systemui.qs.tileimpl.QSTileImpl; import com.android.systemui.qs.tileimpl.QSTileImpl;
@@ -75,7 +78,7 @@ import javax.inject.Provider;
@RunWith(AndroidTestingRunner.class) @RunWith(AndroidTestingRunner.class)
@SmallTest @SmallTest
@RunWithLooper @RunWithLooper(setAsMainLooper = true)
public class QSTileHostTest extends SysuiTestCase { public class QSTileHostTest extends SysuiTestCase {
private static String MOCK_STATE_STRING = "MockState"; private static String MOCK_STATE_STRING = "MockState";
@@ -331,7 +334,15 @@ public class QSTileHostTest extends SysuiTestCase {
private class TestTile extends QSTileImpl<QSTile.State> { private class TestTile extends QSTileImpl<QSTile.State> {
protected TestTile(QSHost host) { 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 @Override

View File

@@ -23,17 +23,23 @@ import android.content.pm.PackageManager
import android.content.pm.ServiceInfo import android.content.pm.ServiceInfo
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import android.graphics.drawable.Icon import android.graphics.drawable.Icon
import android.os.Handler
import android.service.quicksettings.IQSTileService import android.service.quicksettings.IQSTileService
import android.service.quicksettings.Tile import android.service.quicksettings.Tile
import android.test.suitebuilder.annotation.SmallTest import android.test.suitebuilder.annotation.SmallTest
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import android.view.IWindowManager import android.view.IWindowManager
import androidx.test.runner.AndroidJUnit4 import com.android.internal.logging.MetricsLogger
import com.android.systemui.SysuiTestCase import com.android.systemui.SysuiTestCase
import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.plugins.qs.QSTile 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.QSHost
import junit.framework.Assert.assertFalse import com.android.systemui.qs.logging.QSLogger
import junit.framework.Assert.assertTrue
import org.junit.Assert.assertEquals import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.junit.Before import org.junit.Before
import org.junit.Test import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
@@ -46,7 +52,8 @@ import org.mockito.Mockito.mock
import org.mockito.MockitoAnnotations import org.mockito.MockitoAnnotations
@SmallTest @SmallTest
@RunWith(AndroidJUnit4::class) @RunWith(AndroidTestingRunner::class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
class CustomTileTest : SysuiTestCase() { class CustomTileTest : SysuiTestCase() {
companion object { companion object {
@@ -56,36 +63,53 @@ class CustomTileTest : SysuiTestCase() {
val TILE_SPEC = CustomTile.toSpec(componentName) val TILE_SPEC = CustomTile.toSpec(componentName)
} }
@Mock private lateinit var mTileHost: QSHost @Mock private lateinit var tileHost: QSHost
@Mock private lateinit var mTileService: IQSTileService @Mock private lateinit var metricsLogger: MetricsLogger
@Mock private lateinit var mTileServices: TileServices @Mock private lateinit var statusBarStateController: StatusBarStateController
@Mock private lateinit var mTileServiceManager: TileServiceManager @Mock private lateinit var activityStarter: ActivityStarter
@Mock private lateinit var mWindowService: IWindowManager @Mock private lateinit var qsLogger: QSLogger
@Mock private lateinit var mPackageManager: PackageManager @Mock private lateinit var tileService: IQSTileService
@Mock private lateinit var mApplicationInfo: ApplicationInfo @Mock private lateinit var tileServices: TileServices
@Mock private lateinit var mServiceInfo: ServiceInfo @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 customTile: CustomTile
private lateinit var testableLooper: TestableLooper
private lateinit var customTileBuilder: CustomTile.Builder
@Before @Before
fun setUp() { fun setUp() {
MockitoAnnotations.initMocks(this) MockitoAnnotations.initMocks(this)
testableLooper = TestableLooper.get(this)
mContext.addMockSystemService("window", mWindowService) mContext.addMockSystemService("window", windowService)
mContext.setMockPackageManager(mPackageManager) mContext.setMockPackageManager(packageManager)
`when`(mTileHost.tileServices).thenReturn(mTileServices) `when`(tileHost.tileServices).thenReturn(tileServices)
`when`(mTileHost.context).thenReturn(mContext) `when`(tileHost.context).thenReturn(mContext)
`when`(mTileServices.getTileWrapper(any(CustomTile::class.java))) `when`(tileServices.getTileWrapper(any(CustomTile::class.java)))
.thenReturn(mTileServiceManager) .thenReturn(tileServiceManager)
`when`(mTileServiceManager.tileService).thenReturn(mTileService) `when`(tileServiceManager.tileService).thenReturn(tileService)
`when`(mPackageManager.getApplicationInfo(anyString(), anyInt())) `when`(packageManager.getApplicationInfo(anyString(), anyInt()))
.thenReturn(mApplicationInfo) .thenReturn(applicationInfo)
`when`(mPackageManager.getServiceInfo(any(ComponentName::class.java), anyInt())) `when`(packageManager.getServiceInfo(any(ComponentName::class.java), anyInt()))
.thenReturn(mServiceInfo) .thenReturn(serviceInfo)
mServiceInfo.applicationInfo = mApplicationInfo 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 @Test
@@ -93,18 +117,18 @@ class CustomTileTest : SysuiTestCase() {
assertEquals(0, customTile.user) assertEquals(0, customTile.user)
val userContext = mock(Context::class.java) val userContext = mock(Context::class.java)
`when`(userContext.packageManager).thenReturn(mPackageManager) `when`(userContext.packageManager).thenReturn(packageManager)
`when`(userContext.userId).thenReturn(10) `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) assertEquals(10, tile.user)
} }
@Test @Test
fun testToggleableTileHasBooleanState() { fun testToggleableTileHasBooleanState() {
`when`(mTileServiceManager.isToggleableTile).thenReturn(true) `when`(tileServiceManager.isToggleableTile).thenReturn(true)
customTile = CustomTile.create(mTileHost, TILE_SPEC, mContext) customTile = CustomTile.create(customTileBuilder, TILE_SPEC, mContext)
assertTrue(customTile.state is QSTile.BooleanState) assertTrue(customTile.state is QSTile.BooleanState)
assertTrue(customTile.newTileState() is QSTile.BooleanState) assertTrue(customTile.newTileState() is QSTile.BooleanState)
@@ -118,8 +142,8 @@ class CustomTileTest : SysuiTestCase() {
@Test @Test
fun testValueUpdatedInBooleanTile() { fun testValueUpdatedInBooleanTile() {
`when`(mTileServiceManager.isToggleableTile).thenReturn(true) `when`(tileServiceManager.isToggleableTile).thenReturn(true)
customTile = CustomTile.create(mTileHost, TILE_SPEC, mContext) customTile = CustomTile.create(customTileBuilder, TILE_SPEC, mContext)
customTile.qsTile.icon = mock(Icon::class.java) customTile.qsTile.icon = mock(Icon::class.java)
`when`(customTile.qsTile.icon.loadDrawable(any(Context::class.java))) `when`(customTile.qsTile.icon.loadDrawable(any(Context::class.java)))
.thenReturn(mock(Drawable::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.anyString;
import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Matchers.argThat; import static org.mockito.Matchers.argThat;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.mock; 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.verify;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import static java.lang.Thread.sleep;
import android.content.Intent; import android.content.Intent;
import android.metrics.LogMaker; import android.metrics.LogMaker;
import android.os.Handler;
import android.os.Looper;
import android.service.quicksettings.Tile; import android.service.quicksettings.Tile;
import android.testing.AndroidTestingRunner; import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper; 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.MetricsLogger;
import com.android.internal.logging.UiEventLogger; import com.android.internal.logging.UiEventLogger;
import com.android.internal.logging.testing.UiEventLoggerFake; import com.android.internal.logging.testing.UiEventLoggerFake;
import com.android.systemui.Dependency;
import com.android.systemui.SysuiTestCase; import com.android.systemui.SysuiTestCase;
import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.qs.QSTile; 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 com.android.systemui.statusbar.StatusBarState;
import org.junit.Before; import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor; import org.mockito.ArgumentCaptor;
@@ -91,9 +86,14 @@ public class QSTileImplTest extends SysuiTestCase {
private TestableLooper mTestableLooper; private TestableLooper mTestableLooper;
private TileImpl mTile; private TileImpl mTile;
@Mock
private QSTileHost mHost; private QSTileHost mHost;
@Mock
private MetricsLogger mMetricsLogger; private MetricsLogger mMetricsLogger;
@Mock
private StatusBarStateController mStatusBarStateController; private StatusBarStateController mStatusBarStateController;
@Mock
private ActivityStarter mActivityStarter;
private UiEventLoggerFake mUiEventLoggerFake; private UiEventLoggerFake mUiEventLoggerFake;
private InstanceId mInstanceId = InstanceId.fakeInstanceId(5); private InstanceId mInstanceId = InstanceId.fakeInstanceId(5);
@@ -104,21 +104,16 @@ public class QSTileImplTest extends SysuiTestCase {
public void setup() throws Exception { public void setup() throws Exception {
MockitoAnnotations.initMocks(this); MockitoAnnotations.initMocks(this);
mTestableLooper = TestableLooper.get(this); mTestableLooper = TestableLooper.get(this);
mDependency.injectTestDependency(Dependency.BG_LOOPER, mTestableLooper.getLooper());
mDependency.injectMockDependency(ActivityStarter.class);
mMetricsLogger = mDependency.injectMockDependency(MetricsLogger.class);
mUiEventLoggerFake = new UiEventLoggerFake(); mUiEventLoggerFake = new UiEventLoggerFake();
mStatusBarStateController =
mDependency.injectMockDependency(StatusBarStateController.class);
mHost = mock(QSTileHost.class);
when(mHost.indexOf(SPEC)).thenReturn(POSITION); when(mHost.indexOf(SPEC)).thenReturn(POSITION);
when(mHost.getContext()).thenReturn(mContext.getBaseContext()); when(mHost.getContext()).thenReturn(mContext.getBaseContext());
when(mHost.getQSLogger()).thenReturn(mQsLogger);
when(mHost.getUiEventLogger()).thenReturn(mUiEventLoggerFake); when(mHost.getUiEventLogger()).thenReturn(mUiEventLoggerFake);
when(mHost.getNewInstanceId()).thenReturn(mInstanceId); when(mHost.getNewInstanceId()).thenReturn(mInstanceId);
mTile = spy(new TileImpl(mHost)); Handler mainHandler = new Handler(mTestableLooper.getLooper());
mTile.mHandler = mTile.new H(mTestableLooper.getLooper());
mTile = new TileImpl(mHost, mTestableLooper.getLooper(), mainHandler,
mMetricsLogger, mStatusBarStateController, mActivityStarter, mQsLogger);
mTile.setTileSpec(SPEC); mTile.setTileSpec(SPEC);
} }
@@ -223,40 +218,35 @@ public class QSTileImplTest extends SysuiTestCase {
verify(maker).addTaggedData(eq(FIELD_QS_POSITION), eq(POSITION)); verify(maker).addTaggedData(eq(FIELD_QS_POSITION), eq(POSITION));
} }
@Test //TODO(b/161799397) Bring back testStaleTimeout when we can use FakeExecutor
@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();
}
@Test @Test
public void testStaleListening() { public void testStaleListening() {
mTile.handleStale(); mTile.handleStale();
mTestableLooper.processAllMessages(); mTestableLooper.processAllMessages();
verify(mTile).handleSetListening(eq(true)); verify(mQsLogger).logTileChangeListening(SPEC, true);
mTile.handleRefreshState(null); mTile.handleRefreshState(null);
mTestableLooper.processAllMessages(); mTestableLooper.processAllMessages();
verify(mTile).handleSetListening(eq(false)); verify(mQsLogger).logTileChangeListening(SPEC, false);
} }
@Test @Test
public void testHandleDestroyClearsHandlerQueue() { public void testHandleDestroyClearsHandlerQueue() {
when(mTile.getStaleTimeout()).thenReturn(0L);
mTile.handleRefreshState(null); // this will add a delayed H.STALE message mTile.handleRefreshState(null); // this will add a delayed H.STALE message
mTile.handleDestroy(); mTile.handleDestroy();
assertFalse(mTile.mHandler.hasMessages(QSTileImpl.H.STALE));
}
@Test
public void testHandleDestroyLifecycle() {
assertNotEquals(DESTROYED, mTile.getLifecycle().getCurrentState());
mTile.handleDestroy();
mTestableLooper.processAllMessages(); mTestableLooper.processAllMessages();
verify(mTile, never()).handleStale();
assertEquals(DESTROYED, mTile.getLifecycle().getCurrentState());
} }
@Test @Test
@@ -310,6 +300,25 @@ public class QSTileImplTest extends SysuiTestCase {
assertNotEquals(DESTROYED, mTile.getLifecycle().getCurrentState()); 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, private void assertEvent(UiEventLogger.UiEventEnum eventType,
UiEventLoggerFake.FakeUiEvent fakeEvent) { UiEventLoggerFake.FakeUiEvent fakeEvent) {
assertEquals(eventType.getId(), fakeEvent.eventId); assertEquals(eventType.getId(), fakeEvent.eventId);
@@ -351,8 +360,17 @@ public class QSTileImplTest extends SysuiTestCase {
} }
private static class TileImpl extends QSTileImpl<QSTile.BooleanState> { private static class TileImpl extends QSTileImpl<QSTile.BooleanState> {
protected TileImpl(QSHost host) { protected TileImpl(
super(host); 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; getState().state = Tile.STATE_ACTIVE;
} }

View File

@@ -17,13 +17,17 @@
package com.android.systemui.qs.tiles package com.android.systemui.qs.tiles
import android.content.Context import android.content.Context
import android.os.Handler
import android.testing.AndroidTestingRunner import android.testing.AndroidTestingRunner
import android.testing.TestableLooper import android.testing.TestableLooper
import android.testing.TestableLooper.RunWithLooper import android.testing.TestableLooper.RunWithLooper
import androidx.test.filters.SmallTest 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.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.QSHost
import com.android.systemui.qs.logging.QSLogger
import com.android.systemui.statusbar.policy.BatteryController import com.android.systemui.statusbar.policy.BatteryController
import org.junit.Assert.assertEquals import org.junit.Assert.assertEquals
import org.junit.Before import org.junit.Before
@@ -34,7 +38,7 @@ import org.mockito.Mockito.`when`
import org.mockito.MockitoAnnotations import org.mockito.MockitoAnnotations
@RunWith(AndroidTestingRunner::class) @RunWith(AndroidTestingRunner::class)
@RunWithLooper @RunWithLooper(setAsMainLooper = true)
@SmallTest @SmallTest
class BatterySaverTileTest : SysuiTestCase() { class BatterySaverTileTest : SysuiTestCase() {
@@ -47,6 +51,14 @@ class BatterySaverTileTest : SysuiTestCase() {
@Mock @Mock
private lateinit var qsHost: QSHost private lateinit var qsHost: QSHost
@Mock @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 batteryController: BatteryController
private lateinit var testableLooper: TestableLooper private lateinit var testableLooper: TestableLooper
private lateinit var tile: BatterySaverTile private lateinit var tile: BatterySaverTile
@@ -55,11 +67,18 @@ class BatterySaverTileTest : SysuiTestCase() {
fun setUp() { fun setUp() {
MockitoAnnotations.initMocks(this) MockitoAnnotations.initMocks(this)
testableLooper = TestableLooper.get(this) testableLooper = TestableLooper.get(this)
mDependency.injectTestDependency(Dependency.BG_LOOPER, testableLooper.looper)
`when`(qsHost.userContext).thenReturn(userContext) `when`(qsHost.userContext).thenReturn(userContext)
`when`(userContext.userId).thenReturn(USER) `when`(userContext.userId).thenReturn(USER)
tile = BatterySaverTile(qsHost, batteryController) tile = BatterySaverTile(
qsHost,
testableLooper.looper,
Handler(testableLooper.looper),
metricsLogger,
statusBarStateController,
activityStarter,
qsLogger,
batteryController)
} }
@Test @Test

View File

@@ -27,6 +27,7 @@ import static org.mockito.Mockito.when;
import android.media.MediaRouter; import android.media.MediaRouter;
import android.media.MediaRouter.RouteInfo; import android.media.MediaRouter.RouteInfo;
import android.media.projection.MediaProjectionInfo; import android.media.projection.MediaProjectionInfo;
import android.os.Handler;
import android.service.quicksettings.Tile; import android.service.quicksettings.Tile;
import android.testing.AndroidTestingRunner; import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper; import android.testing.TestableLooper;
@@ -34,10 +35,12 @@ import android.testing.TestableLooper;
import androidx.lifecycle.LifecycleOwner; import androidx.lifecycle.LifecycleOwner;
import androidx.test.filters.SmallTest; 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.SysuiTestCase;
import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.qs.QSTileHost; 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;
import com.android.systemui.statusbar.policy.CastController.CastDevice; import com.android.systemui.statusbar.policy.CastController.CastDevice;
import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.statusbar.policy.KeyguardStateController;
@@ -55,7 +58,7 @@ import java.util.List;
@RunWith(AndroidTestingRunner.class) @RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper @TestableLooper.RunWithLooper(setAsMainLooper = true)
@SmallTest @SmallTest
public class CastTileTest extends SysuiTestCase { public class CastTileTest extends SysuiTestCase {
@@ -71,6 +74,12 @@ public class CastTileTest extends SysuiTestCase {
private QSTileHost mHost; private QSTileHost mHost;
@Mock @Mock
NetworkController.SignalCallback mCallback; NetworkController.SignalCallback mCallback;
@Mock
private MetricsLogger mMetricsLogger;
@Mock
private StatusBarStateController mStatusBarStateController;
@Mock
private QSLogger mQSLogger;
private TestableLooper mTestableLooper; private TestableLooper mTestableLooper;
private CastTile mCastTile; private CastTile mCastTile;
@@ -80,16 +89,20 @@ public class CastTileTest extends SysuiTestCase {
MockitoAnnotations.initMocks(this); MockitoAnnotations.initMocks(this);
mTestableLooper = TestableLooper.get(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); when(mHost.getContext()).thenReturn(mContext);
mCastTile = new CastTile(mHost, mController, mKeyguard, mNetworkController, mCastTile = new CastTile(
mActivityStarter); 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 // We are not setting the mocks to listening, so we trigger a first refresh state to
// set the initial state // 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.verify;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import android.os.Handler;
import android.service.quicksettings.Tile; import android.service.quicksettings.Tile;
import android.testing.AndroidTestingRunner; import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper; import android.testing.TestableLooper;
import androidx.test.filters.SmallTest; 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.R;
import com.android.systemui.SysuiTestCase; 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.QSTileHost;
import com.android.systemui.qs.logging.QSLogger;
import com.android.systemui.screenrecord.RecordingController; import com.android.systemui.screenrecord.RecordingController;
import com.android.systemui.statusbar.phone.KeyguardDismissUtil; import com.android.systemui.statusbar.phone.KeyguardDismissUtil;
@@ -43,7 +47,7 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations; import org.mockito.MockitoAnnotations;
@RunWith(AndroidTestingRunner.class) @RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper(setAsMainLooper = true) @TestableLooper.RunWithLooper()
@SmallTest @SmallTest
public class ScreenRecordTileTest extends SysuiTestCase { public class ScreenRecordTileTest extends SysuiTestCase {
@@ -53,6 +57,14 @@ public class ScreenRecordTileTest extends SysuiTestCase {
private QSTileHost mHost; private QSTileHost mHost;
@Mock @Mock
private KeyguardDismissUtil mKeyguardDismissUtil; private KeyguardDismissUtil mKeyguardDismissUtil;
@Mock
private MetricsLogger mMetricsLogger;
@Mock
private StatusBarStateController mStatusBarStateController;
@Mock
private ActivityStarter mActivityStarter;
@Mock
private QSLogger mQSLogger;
private TestableLooper mTestableLooper; private TestableLooper mTestableLooper;
private ScreenRecordTile mTile; private ScreenRecordTile mTile;
@@ -62,12 +74,20 @@ public class ScreenRecordTileTest extends SysuiTestCase {
MockitoAnnotations.initMocks(this); MockitoAnnotations.initMocks(this);
mTestableLooper = TestableLooper.get(this); mTestableLooper = TestableLooper.get(this);
mDependency.injectTestDependency(Dependency.BG_LOOPER, mTestableLooper.getLooper());
mController = mDependency.injectMockDependency(RecordingController.class);
when(mHost.getContext()).thenReturn(mContext); 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 // 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.AndroidTestingRunner;
import android.testing.TestableLooper.RunWithLooper; import android.testing.TestableLooper.RunWithLooper;
import androidx.annotation.NonNull;
import androidx.lifecycle.Lifecycle; import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.Lifecycle.Event; import androidx.lifecycle.Lifecycle.Event;
import androidx.lifecycle.LifecycleEventObserver; import androidx.lifecycle.LifecycleEventObserver;
import androidx.lifecycle.LifecycleOwner; import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.LifecycleRegistry;
import androidx.test.filters.SmallTest; import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase; import com.android.systemui.SysuiTestCase;
@@ -76,6 +78,34 @@ public class CallbackControllerTest extends SysuiTestCase {
verify(controller).removeCallback(eq(callback)); 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> { private static class Controller implements CallbackController<Object> {
@Override @Override
public void addCallback(Object listener) { public void addCallback(Object listener) {