Switch QS tile creation to use injection

This will make it easy to remove dependency usages from tiles.

Test: existing tests
Change-Id: I943f3098c4e7cf2feaa6ebe190f3ddec557c3850
diff --git a/packages/SystemUI/src/com/android/systemui/DependencyBinder.java b/packages/SystemUI/src/com/android/systemui/DependencyBinder.java
index 23ef030..b93a5fd 100644
--- a/packages/SystemUI/src/com/android/systemui/DependencyBinder.java
+++ b/packages/SystemUI/src/com/android/systemui/DependencyBinder.java
@@ -22,6 +22,8 @@
 import com.android.systemui.plugins.VolumeDialogController;
 import com.android.systemui.power.PowerNotificationWarnings;
 import com.android.systemui.power.PowerUI;
+import com.android.systemui.qs.QSHost;
+import com.android.systemui.qs.QSTileHost;
 import com.android.systemui.statusbar.NotificationRemoteInputManager;
 import com.android.systemui.statusbar.phone.DarkIconDispatcherImpl;
 import com.android.systemui.statusbar.phone.ManagedProfileController;
@@ -224,4 +226,9 @@
      */
     @Binds
     public abstract PowerUI.WarningsUI provideWarningsUi(PowerNotificationWarnings controllerImpl);
+
+    /**
+     */
+    @Binds
+    public abstract QSHost provideQsHost(QSTileHost controllerImpl);
 }
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
index b3e2cff..297c146 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
@@ -34,7 +34,6 @@
 import com.android.systemui.keyguard.DismissCallbackRegistry;
 import com.android.systemui.power.EnhancedEstimates;
 import com.android.systemui.power.EnhancedEstimatesImpl;
-import com.android.systemui.qs.QSTileHost;
 import com.android.systemui.statusbar.KeyguardIndicationController;
 import com.android.systemui.statusbar.NotificationListener;
 import com.android.systemui.statusbar.NotificationLockscreenUserManager;
@@ -52,7 +51,6 @@
 import com.android.systemui.statusbar.phone.ScrimController;
 import com.android.systemui.statusbar.phone.ScrimState;
 import com.android.systemui.statusbar.phone.StatusBar;
-import com.android.systemui.statusbar.phone.StatusBarIconController;
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
 import com.android.systemui.util.InjectionInflationController;
@@ -145,11 +143,6 @@
         return new KeyguardIndicationController(context, indicationArea, lockIcon);
     }
 
-    public QSTileHost createQSTileHost(Context context, StatusBar statusBar,
-            StatusBarIconController iconController) {
-        return new QSTileHost(context, statusBar, iconController);
-    }
-
     public VolumeDialogComponent createVolumeDialogComponent(SystemUI systemUi, Context context) {
         return new VolumeDialogComponent(systemUi, context);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
index bedba9a..34d30fe 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
@@ -79,15 +79,18 @@
 
     private final RemoteInputQuickSettingsDisabler mRemoteInputQuickSettingsDisabler;
     private final InjectionInflationController mInjectionInflater;
+    private final QSTileHost mHost;
 
     @Inject
     public QSFragment(RemoteInputQuickSettingsDisabler remoteInputQsDisabler,
             InjectionInflationController injectionInflater,
-            Context context) {
+            Context context,
+            QSTileHost qsTileHost) {
         mRemoteInputQuickSettingsDisabler = remoteInputQsDisabler;
         mInjectionInflater = injectionInflater;
         SysUiServiceProvider.getComponent(context, CommandQueue.class)
                 .observe(getLifecycle(), this);
+        mHost = qsTileHost;
     }
 
     @Override
@@ -122,6 +125,7 @@
                 mQSPanel.getTileLayout().restoreInstanceState(savedInstanceState);
             }
         }
+        setHost(mHost);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java b/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
index ca8e824..ff73cf1 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
@@ -30,6 +30,7 @@
 
 import com.android.systemui.Dependency;
 import com.android.systemui.R;
+import com.android.systemui.SysUiServiceProvider;
 import com.android.systemui.plugins.PluginListener;
 import com.android.systemui.plugins.qs.QSFactory;
 import com.android.systemui.plugins.qs.QSTile;
@@ -52,7 +53,12 @@
 import java.util.List;
 import java.util.function.Predicate;
 
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
 /** Platform implementation of the quick settings tile host **/
+@Singleton
 public class QSTileHost implements QSHost, Tunable, PluginListener<QSFactory> {
     private static final String TAG = "QSTileHost";
     private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
@@ -60,7 +66,6 @@
     public static final String TILES_SETTING = Secure.QS_TILES;
 
     private final Context mContext;
-    private final StatusBar mStatusBar;
     private final LinkedHashMap<String, QSTile> mTiles = new LinkedHashMap<>();
     protected final ArrayList<String> mTileSpecs = new ArrayList<>();
     private final TileServices mServices;
@@ -70,19 +75,28 @@
     private final StatusBarIconController mIconController;
     private final ArrayList<QSFactory> mQsFactories = new ArrayList<>();
     private int mCurrentUser;
+    private StatusBar mStatusBar;
 
-    public QSTileHost(Context context, StatusBar statusBar,
-            StatusBarIconController iconController) {
+    @Inject
+    public QSTileHost(Context context,
+            StatusBarIconController iconController,
+            QSFactoryImpl defaultFactory,
+            @Named(Dependency.MAIN_HANDLER_NAME) Handler mainHandler) {
         mIconController = iconController;
         mContext = context;
-        mStatusBar = statusBar;
 
         mServices = new TileServices(this, Dependency.get(Dependency.BG_LOOPER));
 
-        mQsFactories.add(new QSFactoryImpl(this));
+        defaultFactory.setHost(this);
+        mQsFactories.add(defaultFactory);
         Dependency.get(PluginManager.class).addPluginListener(this, QSFactory.class, true);
 
-        Dependency.get(TunerService.class).addTunable(this, TILES_SETTING);
+        mainHandler.post(() -> {
+            // This is technically a hack to avoid circular dependency of
+            // QSTileHost -> XXXTile -> QSTileHost. Posting ensures creation
+            // finishes before creating any tiles.
+            Dependency.get(TunerService.class).addTunable(this, TILES_SETTING);
+        });
         // AutoTileManager can modify mTiles so make sure mTiles has already been initialized.
         mAutoTiles = new AutoTileManager(context, this);
     }
@@ -140,16 +154,25 @@
 
     @Override
     public void collapsePanels() {
+        if (mStatusBar == null) {
+            mStatusBar = SysUiServiceProvider.getComponent(mContext, StatusBar.class);
+        }
         mStatusBar.postAnimateCollapsePanels();
     }
 
     @Override
     public void forceCollapsePanels() {
+        if (mStatusBar == null) {
+            mStatusBar = SysUiServiceProvider.getComponent(mContext, StatusBar.class);
+        }
         mStatusBar.postAnimateForceCollapsePanels();
     }
 
     @Override
     public void openPanels() {
+        if (mStatusBar == null) {
+            mStatusBar = SysUiServiceProvider.getComponent(mContext, StatusBar.class);
+        }
         mStatusBar.postAnimateOpenPanels();
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java
index fd2c4e3..d26cee9 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java
@@ -47,12 +47,79 @@
 import com.android.systemui.qs.tiles.WorkModeTile;
 import com.android.systemui.util.leak.GarbageMonitor;
 
+import javax.inject.Inject;
+import javax.inject.Provider;
+import javax.inject.Singleton;
+
+@Singleton
 public class QSFactoryImpl implements QSFactory {
 
     private static final String TAG = "QSFactory";
-    private final QSTileHost mHost;
 
-    public QSFactoryImpl(QSTileHost host) {
+    private final Provider<WifiTile> mWifiTileProvider;
+    private final Provider<BluetoothTile> mBluetoothTileProvider;
+    private final Provider<CellularTile> mCellularTileProvider;
+    private final Provider<DndTile> mDndTileProvider;
+    private final Provider<ColorInversionTile> mColorInversionTileProvider;
+    private final Provider<AirplaneModeTile> mAirplaneModeTileProvider;
+    private final Provider<WorkModeTile> mWorkModeTileProvider;
+    private final Provider<RotationLockTile> mRotationLockTileProvider;
+    private final Provider<FlashlightTile> mFlashlightTileProvider;
+    private final Provider<LocationTile> mLocationTileProvider;
+    private final Provider<CastTile> mCastTileProvider;
+    private final Provider<HotspotTile> mHotspotTileProvider;
+    private final Provider<UserTile> mUserTileProvider;
+    private final Provider<BatterySaverTile> mBatterySaverTileProvider;
+    private final Provider<DataSaverTile> mDataSaverTileProvider;
+    private final Provider<NightDisplayTile> mNightDisplayTileProvider;
+    private final Provider<NfcTile> mNfcTileProvider;
+    private final Provider<SensorPrivacyTile> mSensorPrivacyTileProvider;
+    private final Provider<GarbageMonitor.MemoryTile> mMemoryTileProvider;
+
+    private QSTileHost mHost;
+
+    @Inject
+    public QSFactoryImpl(Provider<WifiTile> wifiTileProvider,
+            Provider<BluetoothTile> bluetoothTileProvider,
+            Provider<CellularTile> cellularTileProvider,
+            Provider<DndTile> dndTileProvider,
+            Provider<ColorInversionTile> colorInversionTileProvider,
+            Provider<AirplaneModeTile> airplaneModeTileProvider,
+            Provider<WorkModeTile> workModeTileProvider,
+            Provider<RotationLockTile> rotationLockTileProvider,
+            Provider<FlashlightTile> flashlightTileProvider,
+            Provider<LocationTile> locationTileProvider,
+            Provider<CastTile> castTileProvider,
+            Provider<HotspotTile> hotspotTileProvider,
+            Provider<UserTile> userTileProvider,
+            Provider<BatterySaverTile> batterySaverTileProvider,
+            Provider<DataSaverTile> dataSaverTileProvider,
+            Provider<NightDisplayTile> nightDisplayTileProvider,
+            Provider<NfcTile> nfcTileProvider,
+            Provider<SensorPrivacyTile> sensorPrivacyTileProvider,
+            Provider<GarbageMonitor.MemoryTile> memoryTileProvider) {
+        mWifiTileProvider = wifiTileProvider;
+        mBluetoothTileProvider = bluetoothTileProvider;
+        mCellularTileProvider = cellularTileProvider;
+        mDndTileProvider = dndTileProvider;
+        mColorInversionTileProvider = colorInversionTileProvider;
+        mAirplaneModeTileProvider = airplaneModeTileProvider;
+        mWorkModeTileProvider = workModeTileProvider;
+        mRotationLockTileProvider = rotationLockTileProvider;
+        mFlashlightTileProvider = flashlightTileProvider;
+        mLocationTileProvider = locationTileProvider;
+        mCastTileProvider = castTileProvider;
+        mHotspotTileProvider = hotspotTileProvider;
+        mUserTileProvider = userTileProvider;
+        mBatterySaverTileProvider = batterySaverTileProvider;
+        mDataSaverTileProvider = dataSaverTileProvider;
+        mNightDisplayTileProvider = nightDisplayTileProvider;
+        mNfcTileProvider = nfcTileProvider;
+        mSensorPrivacyTileProvider = sensorPrivacyTileProvider;
+        mMemoryTileProvider = memoryTileProvider;
+    }
+
+    public void setHost(QSTileHost host) {
         mHost = host;
     }
 
@@ -68,41 +135,41 @@
         // Stock tiles.
         switch (tileSpec) {
             case "wifi":
-                return new WifiTile(mHost);
+                return mWifiTileProvider.get();
             case "bt":
-                return new BluetoothTile(mHost);
+                return mBluetoothTileProvider.get();
             case "cell":
-                return new CellularTile(mHost);
+                return mCellularTileProvider.get();
             case "dnd":
-                return new DndTile(mHost);
+                return mDndTileProvider.get();
             case "inversion":
-                return new ColorInversionTile(mHost);
+                return mColorInversionTileProvider.get();
             case "airplane":
-                return new AirplaneModeTile(mHost);
+                return mAirplaneModeTileProvider.get();
             case "work":
-                return new WorkModeTile(mHost);
+                return mWorkModeTileProvider.get();
             case "rotation":
-                return new RotationLockTile(mHost);
+                return mRotationLockTileProvider.get();
             case "flashlight":
-                return new FlashlightTile(mHost);
+                return mFlashlightTileProvider.get();
             case "location":
-                return new LocationTile(mHost);
+                return mLocationTileProvider.get();
             case "cast":
-                return new CastTile(mHost);
+                return mCastTileProvider.get();
             case "hotspot":
-                return new HotspotTile(mHost);
+                return mHotspotTileProvider.get();
             case "user":
-                return new UserTile(mHost);
+                return mUserTileProvider.get();
             case "battery":
-                return new BatterySaverTile(mHost);
+                return mBatterySaverTileProvider.get();
             case "saver":
-                return new DataSaverTile(mHost);
+                return mDataSaverTileProvider.get();
             case "night":
-                return new NightDisplayTile(mHost);
+                return mNightDisplayTileProvider.get();
             case "nfc":
-                return new NfcTile(mHost);
+                return mNfcTileProvider.get();
             case "sensorprivacy":
-                return new SensorPrivacyTile(mHost);
+                return mSensorPrivacyTileProvider.get();
         }
 
         // Intent tiles.
@@ -112,7 +179,7 @@
         // Debug tiles.
         if (Build.IS_DEBUGGABLE) {
             if (tileSpec.equals(GarbageMonitor.MemoryTile.TILE_SPEC)) {
-                return new GarbageMonitor.MemoryTile(mHost);
+                return mMemoryTileProvider.get();
             }
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java
index c8c2158..85427e2 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java
@@ -40,6 +40,8 @@
 import com.android.systemui.qs.QSHost;
 import com.android.systemui.qs.tileimpl.QSTileImpl;
 
+import javax.inject.Inject;
+
 /** Quick settings tile: Airplane mode **/
 public class AirplaneModeTile extends QSTileImpl<BooleanState> {
     private final Icon mIcon =
@@ -48,6 +50,7 @@
 
     private boolean mListening;
 
+    @Inject
     public AirplaneModeTile(QSHost host) {
         super(host);
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java
index da2828e..5f7e20a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java
@@ -30,6 +30,8 @@
 import com.android.systemui.qs.tileimpl.QSTileImpl;
 import com.android.systemui.statusbar.policy.BatteryController;
 
+import javax.inject.Inject;
+
 public class BatterySaverTile extends QSTileImpl<BooleanState> implements
         BatteryController.BatteryStateChangeCallback {
 
@@ -40,6 +42,7 @@
     private boolean mCharging;
     private boolean mPluggedIn;
 
+    @Inject
     public BatterySaverTile(QSHost host) {
         super(host);
         mBatteryController = Dependency.get(BatteryController.class);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
index 3ab1c21..81ffbe6 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
@@ -51,6 +51,8 @@
 import java.util.Collection;
 import java.util.List;
 
+import javax.inject.Inject;
+
 /** Quick settings tile: Bluetooth **/
 public class BluetoothTile extends QSTileImpl<BooleanState> {
     private static final Intent BLUETOOTH_SETTINGS = new Intent(Settings.ACTION_BLUETOOTH_SETTINGS);
@@ -59,6 +61,7 @@
     private final BluetoothDetailAdapter mDetailAdapter;
     private final ActivityStarter mActivityStarter;
 
+    @Inject
     public BluetoothTile(QSHost host) {
         super(host);
         mController = Dependency.get(BluetoothController.class);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
index 921db69..2b7fafc 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
@@ -51,6 +51,8 @@
 import java.util.LinkedHashMap;
 import java.util.Set;
 
+import javax.inject.Inject;
+
 /** Quick settings tile: Cast **/
 public class CastTile extends QSTileImpl<BooleanState> {
     private static final Intent CAST_SETTINGS =
@@ -65,6 +67,7 @@
     private Dialog mDialog;
     private boolean mWifiConnected;
 
+    @Inject
     public CastTile(QSHost host) {
         super(host);
         mController = Dependency.get(CastController.class);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
index 9e341e2..7855c4a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
@@ -51,6 +51,8 @@
 import com.android.systemui.statusbar.policy.NetworkController.IconState;
 import com.android.systemui.statusbar.policy.NetworkController.SignalCallback;
 
+import javax.inject.Inject;
+
 /** Quick settings tile: Cellular **/
 public class CellularTile extends QSTileImpl<SignalState> {
     private static final String ENABLE_SETTINGS_DATA_PLAN = "enable.settings.data.plan";
@@ -63,6 +65,7 @@
     private final ActivityStarter mActivityStarter;
     private final KeyguardMonitor mKeyguardMonitor;
 
+    @Inject
     public CellularTile(QSHost host) {
         super(host);
         mController = Dependency.get(NetworkController.class);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
index c13a07f..ecb4048 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
@@ -30,6 +30,8 @@
 import com.android.systemui.qs.SecureSetting;
 import com.android.systemui.qs.tileimpl.QSTileImpl;
 
+import javax.inject.Inject;
+
 /** Quick settings tile: Invert colors **/
 public class ColorInversionTile extends QSTileImpl<BooleanState> {
 
@@ -38,6 +40,7 @@
 
     private boolean mListening;
 
+    @Inject
     public ColorInversionTile(QSHost host) {
         super(host);
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java
index fd8b9c9..42b9590 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java
@@ -30,11 +30,14 @@
 import com.android.systemui.statusbar.policy.DataSaverController;
 import com.android.systemui.statusbar.policy.NetworkController;
 
+import javax.inject.Inject;
+
 public class DataSaverTile extends QSTileImpl<BooleanState> implements
         DataSaverController.Listener{
 
     private final DataSaverController mDataSaverController;
 
+    @Inject
     public DataSaverTile(QSHost host) {
         super(host);
         mDataSaverController = Dependency.get(NetworkController.class).getDataSaverController();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
index 50c8698..a868a8d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
@@ -62,6 +62,8 @@
 import com.android.systemui.statusbar.policy.ZenModeController;
 import com.android.systemui.volume.ZenModePanel;
 
+import javax.inject.Inject;
+
 /** Quick settings tile: Do not disturb **/
 public class DndTile extends QSTileImpl<BooleanState> {
 
@@ -81,6 +83,7 @@
     private boolean mShowingDetail;
     private boolean mReceiverRegistered;
 
+    @Inject
     public DndTile(QSHost host) {
         super(host);
         mController = Dependency.get(ZenModeController.class);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
index d7ac253..2cf6021 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
@@ -30,6 +30,8 @@
 import com.android.systemui.qs.tileimpl.QSTileImpl;
 import com.android.systemui.statusbar.policy.FlashlightController;
 
+import javax.inject.Inject;
+
 /** Quick settings tile: Control flashlight **/
 public class FlashlightTile extends QSTileImpl<BooleanState> implements
         FlashlightController.FlashlightListener {
@@ -37,6 +39,7 @@
     private final Icon mIcon = ResourceIcon.get(R.drawable.ic_signal_flashlight);
     private final FlashlightController mFlashlightController;
 
+    @Inject
     public FlashlightTile(QSHost host) {
         super(host);
         mFlashlightController = Dependency.get(FlashlightController.class);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
index 6bf0793..e7c6da6 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
@@ -34,6 +34,8 @@
 import com.android.systemui.statusbar.policy.DataSaverController;
 import com.android.systemui.statusbar.policy.HotspotController;
 
+import javax.inject.Inject;
+
 /** Quick settings tile: Hotspot **/
 public class HotspotTile extends QSTileImpl<AirplaneBooleanState> {
     private static final Intent TETHER_SETTINGS = new Intent().setComponent(new ComponentName(
@@ -48,6 +50,7 @@
     private final GlobalSetting mAirplaneMode;
     private boolean mListening;
 
+    @Inject
     public HotspotTile(QSHost host) {
         super(host);
         mHotspotController = Dependency.get(HotspotController.class);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
index b5f2d00..108bde2 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
@@ -34,6 +34,8 @@
 import com.android.systemui.statusbar.policy.LocationController;
 import com.android.systemui.statusbar.policy.LocationController.LocationChangeCallback;
 
+import javax.inject.Inject;
+
 /** Quick settings tile: Location **/
 public class LocationTile extends QSTileImpl<BooleanState> {
 
@@ -43,6 +45,7 @@
     private final KeyguardMonitor mKeyguard;
     private final Callback mCallback = new Callback();
 
+    @Inject
     public LocationTile(QSHost host) {
         super(host);
         mController = Dependency.get(LocationController.class);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/NfcTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/NfcTile.java
index a365e4c..476a239 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/NfcTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/NfcTile.java
@@ -33,6 +33,8 @@
 import com.android.systemui.qs.QSHost;
 import com.android.systemui.qs.tileimpl.QSTileImpl;
 
+import javax.inject.Inject;
+
 /** Quick settings tile: Enable/Disable NFC **/
 public class NfcTile extends QSTileImpl<BooleanState> {
 
@@ -40,6 +42,7 @@
 
     private boolean mListening;
 
+    @Inject
     public NfcTile(QSHost host) {
         super(host);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java
index 90890c0..b04132d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java
@@ -44,6 +44,8 @@
 import java.util.Calendar;
 import java.util.TimeZone;
 
+import javax.inject.Inject;
+
 public class NightDisplayTile extends QSTileImpl<BooleanState>
         implements ColorDisplayController.Callback {
 
@@ -58,6 +60,7 @@
     private ColorDisplayController mController;
     private boolean mIsListening;
 
+    @Inject
     public NightDisplayTile(QSHost host) {
         super(host);
         mController = new ColorDisplayController(mContext, ActivityManager.getCurrentUser());
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java
index 63458163..5f49852 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java
@@ -32,12 +32,15 @@
 import com.android.systemui.statusbar.policy.RotationLockController;
 import com.android.systemui.statusbar.policy.RotationLockController.RotationLockControllerCallback;
 
+import javax.inject.Inject;
+
 /** Quick settings tile: Rotation **/
 public class RotationLockTile extends QSTileImpl<BooleanState> {
 
     private final Icon mIcon = ResourceIcon.get(R.drawable.ic_qs_auto_rotate);
     private final RotationLockController mController;
 
+    @Inject
     public RotationLockTile(QSHost host) {
         super(host);
         mController = Dependency.get(RotationLockController.class);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/SensorPrivacyTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/SensorPrivacyTile.java
index ff368f8..8e709c8 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/SensorPrivacyTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/SensorPrivacyTile.java
@@ -31,6 +31,8 @@
 import com.android.systemui.qs.tileimpl.QSTileImpl;
 import com.android.systemui.statusbar.policy.KeyguardMonitor;
 
+import javax.inject.Inject;
+
 /** Quick settings tile: SensorPrivacy mode **/
 public class SensorPrivacyTile extends QSTileImpl<BooleanState> implements
         SensorPrivacyManager.OnSensorPrivacyChangedListener {
@@ -40,6 +42,7 @@
     private final KeyguardMonitor mKeyguard;
     private final SensorPrivacyManager mSensorPrivacyManager;
 
+    @Inject
     public SensorPrivacyTile(QSHost host) {
         super(host);
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserTile.java
index e5c51a6..c58dc80 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserTile.java
@@ -31,12 +31,15 @@
 import com.android.systemui.statusbar.policy.UserInfoController;
 import com.android.systemui.statusbar.policy.UserSwitcherController;
 
+import javax.inject.Inject;
+
 public class UserTile extends QSTileImpl<State> implements UserInfoController.OnUserInfoChangedListener {
 
     private final UserSwitcherController mUserSwitcherController;
     private final UserInfoController mUserInfoController;
     private Pair<String, Drawable> mLastUpdate;
 
+    @Inject
     public UserTile(QSHost host) {
         super(host);
         mUserSwitcherController = Dependency.get(UserSwitcherController.class);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
index 6939ae7..7424c16 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
@@ -51,6 +51,8 @@
 
 import java.util.List;
 
+import javax.inject.Inject;
+
 /** Quick settings tile: Wifi **/
 public class WifiTile extends QSTileImpl<SignalState> {
     private static final Intent WIFI_SETTINGS = new Intent(Settings.ACTION_WIFI_SETTINGS);
@@ -64,6 +66,7 @@
     private final ActivityStarter mActivityStarter;
     private boolean mExpectDisabled;
 
+    @Inject
     public WifiTile(QSHost host) {
         super(host);
         mController = Dependency.get(NetworkController.class);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java
index 3109dea..9451886 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java
@@ -29,6 +29,8 @@
 import com.android.systemui.qs.tileimpl.QSTileImpl;
 import com.android.systemui.statusbar.phone.ManagedProfileController;
 
+import javax.inject.Inject;
+
 /** Quick settings tile: Work profile on/off */
 public class WorkModeTile extends QSTileImpl<BooleanState> implements
         ManagedProfileController.Callback {
@@ -36,6 +38,7 @@
 
     private final ManagedProfileController mProfileController;
 
+    @Inject
     public WorkModeTile(QSHost host) {
         super(host);
         mProfileController = Dependency.get(ManagedProfileController.class);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index 40e2aae..0a8c08e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -160,7 +160,6 @@
 import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper.SnoozeOption;
 import com.android.systemui.qs.QSFragment;
 import com.android.systemui.qs.QSPanel;
-import com.android.systemui.qs.QSTileHost;
 import com.android.systemui.recents.Recents;
 import com.android.systemui.recents.ScreenPinningRequest;
 import com.android.systemui.shared.system.WindowManagerWrapper;
@@ -940,8 +939,6 @@
                             .withPlugin(QS.class)
                             .withDefault(this::createDefaultQSFragment)
                             .build());
-            final QSTileHost qsh = SystemUIFactory.getInstance().createQSTileHost(mContext, this,
-                    mIconController);
             mBrightnessMirrorController = new BrightnessMirrorController(mStatusBarWindow,
                     (visible) -> {
                         mBrightnessMirrorVisible = visible;
@@ -950,7 +947,6 @@
             fragmentHostManager.addTagListener(QS.TAG, (tag, f) -> {
                 QS qs = (QS) f;
                 if (qs instanceof QSFragment) {
-                    ((QSFragment) qs).setHost(qsh);
                     mQSPanel = ((QSFragment) qs).getQsPanel();
                     mQSPanel.setBrightnessMirror(mBrightnessMirrorController);
                 }
diff --git a/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java b/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java
index 0328c7b..b590e77 100644
--- a/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java
+++ b/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java
@@ -346,6 +346,7 @@
         private final GarbageMonitor gm;
         private ProcessMemInfo pmi;
 
+        @Inject
         public MemoryTile(QSHost host) {
             super(host);
             gm = SystemUIFactory.getInstance().getRootComponent().createGarbageMonitor();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
index bbf2032..5bdaf60 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
@@ -21,6 +21,7 @@
 import android.app.Fragment;
 import android.content.Context;
 import android.os.Bundle;
+import android.os.Handler;
 import android.os.Looper;
 import android.support.test.filters.SmallTest;
 import android.testing.AndroidTestingRunner;
@@ -36,6 +37,7 @@
 import com.android.systemui.R;
 import com.android.systemui.SystemUIFactory;
 import com.android.systemui.SysuiBaseFragmentTest;
+import com.android.systemui.qs.tileimpl.QSFactoryImpl;
 import com.android.systemui.statusbar.phone.StatusBarIconController;
 import com.android.systemui.statusbar.policy.Clock;
 import com.android.systemui.statusbar.policy.ConfigurationController;
@@ -86,7 +88,8 @@
         QSFragment qs = (QSFragment) mFragment;
         mFragments.dispatchResume();
         processAllMessages();
-        QSTileHost host = new QSTileHost(mContext, null, mock(StatusBarIconController.class));
+        QSTileHost host = new QSTileHost(mContext, mock(StatusBarIconController.class),
+                mock(QSFactoryImpl.class), new Handler());
         qs.setHost(host);
 
         qs.setListening(true);
@@ -128,6 +131,7 @@
         return new QSFragment(
                 new RemoteInputQuickSettingsDisabler(context, mock(ConfigurationController.class)),
                 new InjectionInflationController(SystemUIFactory.getInstance().getRootComponent()),
-                context);
+                context,
+                mock(QSTileHost.class));
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTest.java
index c6597b9..de5952e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTest.java
@@ -21,6 +21,7 @@
 import static org.mockito.Mockito.mock;
 
 import android.content.ComponentName;
+import android.os.Handler;
 import android.os.Looper;
 import android.service.quicksettings.Tile;
 import android.test.suitebuilder.annotation.SmallTest;
@@ -30,6 +31,7 @@
 
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.qs.QSTileHost;
+import com.android.systemui.qs.tileimpl.QSFactoryImpl;
 import com.android.systemui.statusbar.phone.StatusBarIconController;
 import com.android.systemui.statusbar.policy.BluetoothController;
 
@@ -55,8 +57,10 @@
     public void setUp() throws Exception {
         mDependency.injectMockDependency(BluetoothController.class);
         mManagers = new ArrayList<>();
-        QSTileHost host = new QSTileHost(mContext, null,
-                mock(StatusBarIconController.class));
+        QSTileHost host = new QSTileHost(mContext,
+                mock(StatusBarIconController.class),
+                mock(QSFactoryImpl.class),
+                new Handler());
         mTileService = new TestTileServices(host, Looper.getMainLooper());
     }