summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Dave Mankoff <mankoff@google.com> 2020-10-20 13:30:41 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2020-10-20 13:30:41 +0000
commitf4c81035208d3f8e7798b84fb48daedd480de680 (patch)
tree372b5447d5e2c2cea0527964d3763fc2118d1944
parentae31181f133dba251225d95169d95ee1574599af (diff)
parent3834b11c62b2b396b4516480408373379b7889c5 (diff)
Merge changes from topic "b168904199-qs-injection"
* changes: 5/N Move QS Tile tracking logic into QSPanelControllerBase. 4/N Add QSPanelControllerBase 3/N Remove UserTracker from QSPanel 2/N Remove BroadcastDispatcher from QSPanel 1/N Add QSFragmentComponent
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardRootViewController.java2
-rw-r--r--packages/SystemUI/src/com/android/keyguard/dagger/KeyguardBouncerModule.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/dagger/qualifiers/RootView.java (renamed from packages/SystemUI/src/com/android/keyguard/dagger/RootView.java)4
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/DoubleLineTileLayout.kt10
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java44
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSContainerImplController.java34
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSFragment.java85
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSPanel.java371
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java195
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java250
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java11
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSTileRevealController.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java74
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QuickQSPanelController.java83
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java70
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/TileLayout.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/dagger/QSFragmentComponent.java51
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/dagger/QSFragmentModule.java73
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/dagger/QSModule.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/dagger/QSScope.java32
-rw-r--r--packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java18
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java30
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java17
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerBaseTest.java141
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.java106
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java77
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/TileLayoutTest.java24
31 files changed, 1224 insertions, 613 deletions
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardRootViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardRootViewController.java
index 5c125fcc95cb..4e375c2d1227 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardRootViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardRootViewController.java
@@ -19,7 +19,7 @@ package com.android.keyguard;
import android.view.ViewGroup;
import com.android.keyguard.dagger.KeyguardBouncerScope;
-import com.android.keyguard.dagger.RootView;
+import com.android.systemui.dagger.qualifiers.RootView;
import com.android.systemui.statusbar.phone.KeyguardBouncer;
import com.android.systemui.util.ViewController;
diff --git a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardBouncerModule.java b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardBouncerModule.java
index 881108858b51..4fad9a916d0d 100644
--- a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardBouncerModule.java
+++ b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardBouncerModule.java
@@ -24,6 +24,7 @@ import com.android.keyguard.KeyguardMessageArea;
import com.android.keyguard.KeyguardSecurityContainer;
import com.android.keyguard.KeyguardSecurityViewFlipper;
import com.android.systemui.R;
+import com.android.systemui.dagger.qualifiers.RootView;
import com.android.systemui.statusbar.phone.KeyguardBouncer;
import dagger.Module;
diff --git a/packages/SystemUI/src/com/android/keyguard/dagger/RootView.java b/packages/SystemUI/src/com/android/systemui/dagger/qualifiers/RootView.java
index 5ebff097604b..e6c46c07fff8 100644
--- a/packages/SystemUI/src/com/android/keyguard/dagger/RootView.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/qualifiers/RootView.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.keyguard.dagger;
+package com.android.systemui.dagger.qualifiers;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/DoubleLineTileLayout.kt b/packages/SystemUI/src/com/android/systemui/qs/DoubleLineTileLayout.kt
index dc157a8dd257..81076475c5ce 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/DoubleLineTileLayout.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/DoubleLineTileLayout.kt
@@ -33,7 +33,7 @@ class DoubleLineTileLayout(
private const val NUM_LINES = 2
}
- protected val mRecords = ArrayList<QSPanel.TileRecord>()
+ protected val mRecords = ArrayList<QSPanelControllerBase.TileRecord>()
private var _listening = false
private var smallTileSize = 0
private val twoLineHeight
@@ -50,17 +50,17 @@ class DoubleLineTileLayout(
updateResources()
}
- override fun addTile(tile: QSPanel.TileRecord) {
+ override fun addTile(tile: QSPanelControllerBase.TileRecord) {
mRecords.add(tile)
tile.tile.setListening(this, _listening)
addTileView(tile)
}
- protected fun addTileView(tile: QSPanel.TileRecord) {
+ protected fun addTileView(tile: QSPanelControllerBase.TileRecord) {
addView(tile.tileView)
}
- override fun removeTile(tile: QSPanel.TileRecord) {
+ override fun removeTile(tile: QSPanelControllerBase.TileRecord) {
mRecords.remove(tile)
tile.tile.setListening(this, false)
removeView(tile.tileView)
@@ -72,7 +72,7 @@ class DoubleLineTileLayout(
super.removeAllViews()
}
- override fun getOffsetTop(tile: QSPanel.TileRecord?) = top
+ override fun getOffsetTop(tile: QSPanelControllerBase.TileRecord?) = top
override fun updateResources(): Boolean {
with(mContext.resources) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
index 04f379ef35ea..3062a77bcbe1 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
@@ -26,7 +26,7 @@ import com.android.internal.logging.UiEventLogger;
import com.android.systemui.R;
import com.android.systemui.plugins.qs.QSTile;
import com.android.systemui.qs.QSPanel.QSTileLayout;
-import com.android.systemui.qs.QSPanel.TileRecord;
+import com.android.systemui.qs.QSPanelControllerBase.TileRecord;
import java.util.ArrayList;
import java.util.Set;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
index 9dcc924f161e..4d4195063227 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
@@ -28,12 +28,17 @@ import com.android.systemui.qs.QSHost.Callback;
import com.android.systemui.qs.QSPanel.QSTileLayout;
import com.android.systemui.qs.TouchAnimator.Builder;
import com.android.systemui.qs.TouchAnimator.Listener;
+import com.android.systemui.qs.dagger.QSScope;
import com.android.systemui.tuner.TunerService;
import com.android.systemui.tuner.TunerService.Tunable;
import java.util.ArrayList;
import java.util.Collection;
+import javax.inject.Inject;
+
+/** */
+@QSScope
public class QSAnimator implements Callback, PageListener, Listener, OnLayoutChangeListener,
OnAttachStateChangeListener, Tunable {
@@ -53,6 +58,9 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha
private final ArrayList<View> mQuickQsViews = new ArrayList<>();
private final QuickQSPanel mQuickQsPanel;
private final QSPanel mQsPanel;
+ private final QSPanelController mQsPanelController;
+ private final QuickQSPanelController mQuickQSPanelController;
+ private final QSSecurityFooter mSecurityFooter;
private final QS mQs;
private PagedTileLayout mPagedLayout;
@@ -78,10 +86,19 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha
private QSTileHost mHost;
private boolean mShowCollapsedOnKeyguard;
- public QSAnimator(QS qs, QuickQSPanel quickPanel, QSPanel panel) {
+ @Inject
+ public QSAnimator(QS qs, QuickQSPanel quickPanel, QSPanel panel,
+ QSPanelController qsPanelController, QuickQSPanelController quickQSPanelController,
+ QSTileHost qsTileHost,
+ QSSecurityFooter securityFooter) {
mQs = qs;
mQuickQsPanel = quickPanel;
mQsPanel = panel;
+ mQsPanelController = qsPanelController;
+ mQuickQSPanelController = quickQSPanelController;
+ mSecurityFooter = securityFooter;
+ mHost = qsTileHost;
+ mHost.addCallback(this);
mQsPanel.addOnAttachStateChangeListener(this);
qs.getView().addOnLayoutChangeListener(this);
if (mQsPanel.isAttachedToWindow()) {
@@ -134,12 +151,6 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha
&& !mShowCollapsedOnKeyguard ? View.INVISIBLE : View.VISIBLE);
}
- public void setHost(QSTileHost qsh) {
- mHost = qsh;
- qsh.addCallback(this);
- updateAnimators();
- }
-
@Override
public void onViewAttachedToWindow(View v) {
Dependency.get(TunerService.class).addTunable(this, ALLOW_FANCY_ANIMATION,
@@ -148,9 +159,7 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha
@Override
public void onViewDetachedFromWindow(View v) {
- if (mHost != null) {
- mHost.removeCallback(this);
- }
+ mHost.removeCallback(this);
Dependency.get(TunerService.class).removeTunable(this);
}
@@ -185,8 +194,7 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha
TouchAnimator.Builder translationXBuilder = new Builder();
TouchAnimator.Builder translationYBuilder = new Builder();
- if (mQsPanel.getHost() == null) return;
- Collection<QSTile> tiles = mQsPanel.getHost().getTiles();
+ Collection<QSTile> tiles = mHost.getTiles();
int count = 0;
int[] loc1 = new int[2];
int[] loc2 = new int[2];
@@ -206,7 +214,7 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha
firstPageBuilder.addFloat(tileLayout, "translationY", heightDiff, 0);
for (QSTile tile : tiles) {
- QSTileView tileView = mQsPanel.getTileView(tile);
+ QSTileView tileView = mQsPanelController.getTileView(tile);
if (tileView == null) {
Log.e(TAG, "tileView is null " + tile.getTileSpec());
continue;
@@ -217,7 +225,7 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha
// This case: less tiles to animate in small displays.
if (count < mQuickQsPanel.getTileLayout().getNumVisibleTiles() && mAllowFancy) {
// Quick tiles.
- QSTileView quickTileView = mQuickQsPanel.getTileView(tile);
+ QSTileView quickTileView = mQuickQSPanelController.getTileView(tile);
if (quickTileView == null) continue;
lastX = loc1[0];
@@ -302,16 +310,12 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha
// Fade in the security footer and the divider as we reach the final position
builder = new Builder().setStartDelay(EXPANDED_TILE_DELAY);
- if (mQsPanel.getSecurityFooter() != null) {
- builder.addFloat(mQsPanel.getSecurityFooter().getView(), "alpha", 0, 1);
- }
+ builder.addFloat(mSecurityFooter.getView(), "alpha", 0, 1);
if (mQsPanel.getDivider() != null) {
builder.addFloat(mQsPanel.getDivider(), "alpha", 0, 1);
}
mAllPagesDelayedAnimator = builder.build();
- if (mQsPanel.getSecurityFooter() != null) {
- mAllViews.add(mQsPanel.getSecurityFooter().getView());
- }
+ mAllViews.add(mSecurityFooter.getView());
if (mQsPanel.getDivider() != null) {
mAllViews.add(mQsPanel.getDivider());
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImplController.java b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImplController.java
index 1e239b1e9ec9..acead987a06a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImplController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImplController.java
@@ -16,19 +16,21 @@
package com.android.systemui.qs;
-import com.android.systemui.R;
+import com.android.systemui.qs.dagger.QSScope;
import com.android.systemui.util.ViewController;
import javax.inject.Inject;
-class QSContainerImplController extends ViewController<QSContainerImpl> {
+/** */
+@QSScope
+public class QSContainerImplController extends ViewController<QSContainerImpl> {
private final QuickStatusBarHeaderController mQuickStatusBarHeaderController;
- private QSContainerImplController(QSContainerImpl view,
- QuickStatusBarHeaderController.Builder quickStatusBarHeaderControllerBuilder) {
+ @Inject
+ QSContainerImplController(QSContainerImpl view,
+ QuickStatusBarHeaderController quickStatusBarHeaderController) {
super(view);
- mQuickStatusBarHeaderController = quickStatusBarHeaderControllerBuilder
- .setQuickStatusBarHeader(mView.findViewById(R.id.header)).build();
+ mQuickStatusBarHeaderController = quickStatusBarHeaderController;
}
@Override
@@ -49,23 +51,7 @@ class QSContainerImplController extends ViewController<QSContainerImpl> {
protected void onViewDetached() {
}
- static class Builder {
- private final QuickStatusBarHeaderController.Builder mQuickStatusBarHeaderControllerBuilder;
- private QSContainerImpl mView;
-
- @Inject
- Builder(
- QuickStatusBarHeaderController.Builder quickStatusBarHeaderControllerBuilder) {
- mQuickStatusBarHeaderControllerBuilder = quickStatusBarHeaderControllerBuilder;
- }
-
- public Builder setQSContainerImpl(QSContainerImpl view) {
- mView = view;
- return this;
- }
-
- public QSContainerImplController build() {
- return new QSContainerImplController(mView, mQuickStatusBarHeaderControllerBuilder);
- }
+ public QSContainerImpl getView() {
+ return mView;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
index 3a783653a2d8..4ea600ab5e25 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
@@ -35,11 +35,11 @@ import androidx.annotation.VisibleForTesting;
import com.android.systemui.Interpolators;
import com.android.systemui.R;
-import com.android.systemui.R.id;
import com.android.systemui.media.MediaHost;
import com.android.systemui.plugins.qs.QS;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.qs.customize.QSCustomizer;
+import com.android.systemui.qs.dagger.QSFragmentComponent;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
@@ -70,7 +70,6 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca
private HeightListener mPanelView;
protected QuickStatusBarHeader mHeader;
private QSCustomizer mQSCustomizer;
- protected QSPanel mQSPanel;
protected NonInterceptingScrollView mQSPanelScrollView;
private QSDetail mQSDetail;
private boolean mListening;
@@ -82,7 +81,7 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca
private final RemoteInputQuickSettingsDisabler mRemoteInputQuickSettingsDisabler;
private final InjectionInflationController mInjectionInflater;
- private final QSContainerImplController.Builder mQSContainerImplControllerBuilder;
+ private final QSFragmentComponent.Factory mQsComponentFactory;
private final QSTileHost mHost;
private boolean mShowCollapsedOnKeyguard;
private boolean mLastKeyguardAndExpanded;
@@ -96,15 +95,17 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca
private int[] mTmpLocation = new int[2];
private int mLastViewHeight;
private float mLastHeaderTranslation;
+ private QSPanelController mQSPanelController;
+ private QuickQSPanelController mQuickQSPanelController;
@Inject
public QSFragment(RemoteInputQuickSettingsDisabler remoteInputQsDisabler,
InjectionInflationController injectionInflater, QSTileHost qsTileHost,
StatusBarStateController statusBarStateController, CommandQueue commandQueue,
- QSContainerImplController.Builder qsContainerImplControllerBuilder) {
+ QSFragmentComponent.Factory qsComponentFactory) {
mRemoteInputQuickSettingsDisabler = remoteInputQsDisabler;
mInjectionInflater = injectionInflater;
- mQSContainerImplControllerBuilder = qsContainerImplControllerBuilder;
+ mQsComponentFactory = qsComponentFactory;
commandQueue.observe(getLifecycle(), this);
mHost = qsTileHost;
mStatusBarStateController = statusBarStateController;
@@ -120,8 +121,13 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
- super.onViewCreated(view, savedInstanceState);
- mQSPanel = view.findViewById(R.id.quick_settings_panel);
+ QSFragmentComponent qsFragmentComponent = mQsComponentFactory.create(this);
+ mQSPanelController = qsFragmentComponent.getQSPanelController();
+ mQuickQSPanelController = qsFragmentComponent.getQuickQSPanelController();
+
+ mQSPanelController.init();
+ mQuickQSPanelController.init();
+
mQSPanelScrollView = view.findViewById(R.id.expanded_qs_scroll_view);
mQSPanelScrollView.addOnLayoutChangeListener(
(v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> {
@@ -135,18 +141,15 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca
});
mQSDetail = view.findViewById(R.id.qs_detail);
mHeader = view.findViewById(R.id.header);
- mQSPanel.setHeaderContainer(view.findViewById(R.id.header_text_container));
+ mQSPanelController.setHeaderContainer(view.findViewById(R.id.header_text_container));
mFooter = view.findViewById(R.id.qs_footer);
- mContainer = view.findViewById(id.quick_settings_container);
- mQSContainerImplController = mQSContainerImplControllerBuilder
- .setQSContainerImpl((QSContainerImpl) view)
- .build();
+ mQSContainerImplController = qsFragmentComponent.getQSContainerImplController();
mQSContainerImplController.init();
+ mContainer = mQSContainerImplController.getView();
- mQSDetail.setQsPanel(mQSPanel, mHeader, (View) mFooter);
- mQSAnimator = new QSAnimator(this, mHeader.findViewById(R.id.quick_qs_panel), mQSPanel);
-
+ mQSDetail.setQsPanel(mQSPanelController.getView(), mHeader, (View) mFooter);
+ mQSAnimator = qsFragmentComponent.getQSAnimator();
mQSCustomizer = view.findViewById(R.id.qs_customize);
mQSCustomizer.setQs(this);
@@ -156,7 +159,7 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca
setEditLocation(view);
mQSCustomizer.restoreInstanceState(savedInstanceState);
if (mQsExpanded) {
- mQSPanel.getTileLayout().restoreInstanceState(savedInstanceState);
+ mQSPanelController.getTileLayout().restoreInstanceState(savedInstanceState);
}
}
setHost(mHost);
@@ -188,7 +191,7 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca
outState.putBoolean(EXTRA_LISTENING, mListening);
mQSCustomizer.saveInstanceState(outState);
if (mQsExpanded) {
- mQSPanel.getTileLayout().saveInstanceState(outState);
+ mQSPanelController.getTileLayout().saveInstanceState(outState);
}
}
@@ -249,14 +252,10 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca
}
public void setHost(QSTileHost qsh) {
- mQSPanel.setHost(qsh, mQSCustomizer);
- mHeader.setQSPanel(mQSPanel);
- mFooter.setQSPanel(mQSPanel);
+ mQSPanelController.setCustomizer(mQSCustomizer);
+ mHeader.setQSPanel(mQSPanelController.getView());
+ mFooter.setQSPanel(mQSPanelController.getView());
mQSDetail.setHost(qsh);
-
- if (mQSAnimator != null) {
- mQSAnimator.setHost(qsh);
- }
}
@Override
@@ -278,7 +277,7 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca
private void updateQsState() {
final boolean expandVisually = mQsExpanded || mStackScrollerOverscrolling
|| mHeaderAnimating;
- mQSPanel.setExpanded(mQsExpanded);
+ mQSPanelController.setExpanded(mQsExpanded);
mQSDetail.setExpanded(mQsExpanded);
boolean keyguardShowing = isKeyguardShowing();
mHeader.setVisibility((mQsExpanded || !keyguardShowing || mHeaderAnimating
@@ -294,7 +293,8 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca
: View.INVISIBLE);
mFooter.setExpanded((keyguardShowing && !mHeaderAnimating && !mShowCollapsedOnKeyguard)
|| (mQsExpanded && !mStackScrollerOverscrolling));
- mQSPanel.setVisibility(!mQsDisabled && expandVisually ? View.VISIBLE : View.INVISIBLE);
+ mQSPanelController.setVisibility(
+ !mQsDisabled && expandVisually ? View.VISIBLE : View.INVISIBLE);
}
private boolean isKeyguardShowing() {
@@ -317,8 +317,12 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca
}
}
+ public QSPanelController getQSPanelController() {
+ return mQSPanelController;
+ }
+
public QSPanel getQsPanel() {
- return mQSPanel;
+ return mQSPanelController.getView();
}
public QSCustomizer getCustomizer() {
@@ -327,7 +331,7 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca
@Override
public boolean isShowingDetail() {
- return mQSPanel.isShowingCustomize() || mQSDetail.isShowingDetail();
+ return mQSPanelController.isShowingCustomize() || mQSDetail.isShowingDetail();
}
@Override
@@ -339,7 +343,7 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca
public void setExpanded(boolean expanded) {
if (DEBUG) Log.d(TAG, "setExpanded " + expanded);
mQsExpanded = expanded;
- mQSPanel.setListening(mListening, mQsExpanded);
+ mQSPanelController.setListening(mListening, mQsExpanded);
updateQsState();
}
@@ -368,7 +372,7 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca
mListening = listening;
mQSContainerImplController.setListening(listening);
mFooter.setListening(listening);
- mQSPanel.setListening(mListening, mQsExpanded);
+ mQSPanelController.setListening(mListening, mQsExpanded);
}
@Override
@@ -406,11 +410,15 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca
float panelTranslationY = translationScaleY * heightDiff;
// Let the views animate their contents correctly by giving them the necessary context.
- mHeader.setExpansion(onKeyguardAndExpanded, expansion,
- panelTranslationY);
+ mHeader.setExpansion(onKeyguardAndExpanded, expansion, panelTranslationY);
+ if (expansion < 1 && expansion > 0.99) {
+ if (mQuickQSPanelController.switchTileLayout(false)) {
+ mHeader.updateResources();
+ }
+ }
mFooter.setExpansion(onKeyguardAndExpanded ? 1 : expansion);
- mQSPanel.getQsTileRevealController().setExpansion(expansion);
- mQSPanel.getTileLayout().setExpansion(expansion);
+ mQSPanelController.getQsTileRevealController().setExpansion(expansion);
+ mQSPanelController.getTileLayout().setExpansion(expansion);
mQSPanelScrollView.setTranslationY(translationScaleY * heightDiff);
if (fullyCollapsed) {
mQSPanelScrollView.setScrollY(0);
@@ -448,7 +456,8 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca
float expandedMediaPosition = absoluteBottomPosition - mQSPanelScrollView.getScrollY()
+ mQSPanelScrollView.getScrollRange();
// The expanded media host should never move below the laid out position
- pinToBottom(expandedMediaPosition, mQSPanel.getMediaHost(), true /* expanded */);
+ pinToBottom(
+ expandedMediaPosition, mQSPanelController.getMediaHost(), true /* expanded */);
// The expanded media host should never move above the laid out position
pinToBottom(absoluteBottomPosition, mHeader.getHeaderQsPanel().getMediaHost(),
false /* expanded */);
@@ -538,7 +547,7 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca
@Override
public void closeDetail() {
- mQSPanel.closeDetail();
+ mQSPanelController.closeDetail();
}
public void notifyCustomizeChanged() {
@@ -553,8 +562,8 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca
}
/**
- * The height this view wants to be. This is different from {@link #getMeasuredHeight} such that
- * during closing the detail panel, this already returns the smaller height.
+ * The height this view wants to be. This is different from {@link View#getMeasuredHeight} such
+ * that during closing the detail panel, this already returns the smaller height.
*/
@Override
public int getDesiredHeight() {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index efe46096239f..1b17a2a277f2 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -22,11 +22,9 @@ import static com.android.systemui.util.Utils.useQsMediaPlayer;
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.content.ComponentName;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
-import android.metrics.LogMaker;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
@@ -43,41 +41,30 @@ import com.android.internal.logging.UiEventLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.widget.RemeasuringLinearLayout;
import com.android.systemui.Dependency;
-import com.android.systemui.Dumpable;
import com.android.systemui.R;
-import com.android.systemui.broadcast.BroadcastDispatcher;
-import com.android.systemui.dump.DumpManager;
import com.android.systemui.media.MediaHierarchyManager;
import com.android.systemui.media.MediaHost;
import com.android.systemui.plugins.qs.DetailAdapter;
import com.android.systemui.plugins.qs.QSTile;
-import com.android.systemui.plugins.qs.QSTileView;
-import com.android.systemui.qs.QSHost.Callback;
import com.android.systemui.qs.customize.QSCustomizer;
-import com.android.systemui.qs.external.CustomTile;
import com.android.systemui.qs.logging.QSLogger;
-import com.android.systemui.settings.BrightnessController;
import com.android.systemui.settings.ToggleSliderView;
-import com.android.systemui.settings.UserTracker;
import com.android.systemui.statusbar.policy.BrightnessMirrorController;
import com.android.systemui.statusbar.policy.BrightnessMirrorController.BrightnessMirrorListener;
import com.android.systemui.tuner.TunerService;
import com.android.systemui.tuner.TunerService.Tunable;
import com.android.systemui.util.animation.DisappearParameters;
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.List;
import java.util.function.Consumer;
-import java.util.stream.Collectors;
import javax.inject.Inject;
import javax.inject.Named;
/** View that represents the quick settings tile panel (when expanded/pulled down). **/
-public class QSPanel extends LinearLayout implements Tunable, Callback, BrightnessMirrorListener,
- Dumpable {
+public class QSPanel extends LinearLayout implements Tunable, BrightnessMirrorListener {
public static final String QS_SHOW_BRIGHTNESS = "qs_show_brightness";
public static final String QS_SHOW_HEADER = "qs_show_header";
@@ -85,20 +72,15 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
private static final String TAG = "QSPanel";
protected final Context mContext;
- protected final ArrayList<TileRecord> mRecords = new ArrayList<>();
- private final BroadcastDispatcher mBroadcastDispatcher;
protected final MediaHost mMediaHost;
/**
* The index where the content starts that needs to be moved between parents
*/
private final int mMovableContentStartIndex;
- private String mCachedSpecs = "";
@Nullable
protected View mBrightnessView;
- @Nullable
- private BrightnessController mBrightnessController;
private final H mHandler = new H();
private final MetricsLogger mMetricsLogger = Dependency.get(MetricsLogger.class);
@@ -112,14 +94,14 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
protected boolean mListening;
private QSDetail.Callback mCallback;
- private final DumpManager mDumpManager;
private final QSLogger mQSLogger;
protected final UiEventLogger mUiEventLogger;
protected QSTileHost mHost;
- private final UserTracker mUserTracker;
+ private final List<OnConfigurationChangedListener> mOnConfigurationChangedListeners =
+ new ArrayList<>();
@Nullable
- protected QSSecurityFooter mSecurityFooter;
+ protected View mSecurityFooter;
@Nullable
protected View mFooter;
@@ -156,12 +138,9 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
public QSPanel(
@Named(VIEW_CONTEXT) Context context,
AttributeSet attrs,
- DumpManager dumpManager,
- BroadcastDispatcher broadcastDispatcher,
QSLogger qsLogger,
@Named(QS_PANEL) MediaHost mediaHost,
- UiEventLogger uiEventLogger,
- UserTracker userTracker
+ UiEventLogger uiEventLogger
) {
super(context, attrs);
mUsingMediaPlayer = useQsMediaPlayer(context);
@@ -174,16 +153,14 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
});
mContext = context;
mQSLogger = qsLogger;
- mDumpManager = dumpManager;
- mBroadcastDispatcher = broadcastDispatcher;
mUiEventLogger = uiEventLogger;
- mUserTracker = userTracker;
setOrientation(VERTICAL);
addViewsAboveTiles();
mMovableContentStartIndex = getChildCount();
mRegularTileLayout = createRegularTileLayout();
+ mTileLayout = mRegularTileLayout;
if (mUsingMediaPlayer) {
mHorizontalLinearLayout = new RemeasuringLinearLayout(mContext);
@@ -209,35 +186,27 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
initMediaHostState();
}
- addSecurityFooter();
if (mRegularTileLayout instanceof PagedTileLayout) {
mQsTileRevealController = new QSTileRevealController(mContext, this,
(PagedTileLayout) mRegularTileLayout);
}
- mQSLogger.logAllTilesChangeListening(mListening, getDumpableTag(), mCachedSpecs);
- updateResources();
+ mQSLogger.logAllTilesChangeListening(mListening, getDumpableTag(), "");
}
protected void onMediaVisibilityChanged(Boolean visible) {
- switchTileLayout();
if (mMediaVisibilityChangedListener != null) {
mMediaVisibilityChangedListener.accept(visible);
}
}
- protected void addSecurityFooter() {
- mSecurityFooter = new QSSecurityFooter(this, mContext, mUserTracker);
- }
-
protected void addViewsAboveTiles() {
mBrightnessView = LayoutInflater.from(mContext).inflate(
R.layout.quick_settings_brightness_dialog, this, false);
addView(mBrightnessView);
- mBrightnessController = new BrightnessController(getContext(),
- findViewById(R.id.brightness_slider), mBroadcastDispatcher);
}
- protected QSTileLayout createRegularTileLayout() {
+ /** */
+ public QSTileLayout createRegularTileLayout() {
if (mRegularTileLayout == null) {
mRegularTileLayout = (QSTileLayout) LayoutInflater.from(mContext).inflate(
R.layout.qs_paged_tile_layout, this, false);
@@ -337,37 +306,10 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
}
@Override
- protected void onAttachedToWindow() {
- super.onAttachedToWindow();
- final TunerService tunerService = Dependency.get(TunerService.class);
- tunerService.addTunable(this, QS_SHOW_BRIGHTNESS);
-
- if (mHost != null) {
- setTiles(mHost.getTiles());
- }
- if (mBrightnessMirrorController != null) {
- mBrightnessMirrorController.addCallback(this);
- }
- mDumpManager.registerDumpable(getDumpableTag(), this);
- }
-
- @Override
protected void onDetachedFromWindow() {
- Dependency.get(TunerService.class).removeTunable(this);
- if (mHost != null) {
- mHost.removeCallback(this);
- }
if (mTileLayout != null) {
mTileLayout.setListening(false);
}
- for (TileRecord record : mRecords) {
- record.tile.removeCallbacks();
- }
- mRecords.clear();
- if (mBrightnessMirrorController != null) {
- mBrightnessMirrorController.removeCallback(this);
- }
- mDumpManager.unregisterDumpable(getDumpableTag());
super.onDetachedFromWindow();
}
@@ -376,11 +318,6 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
}
@Override
- public void onTilesChanged() {
- setTiles(mHost.getTiles());
- }
-
- @Override
public void onTuningChanged(String key, String newValue) {
if (QS_SHOW_BRIGHTNESS.equals(key) && mBrightnessView != null) {
updateViewVisibilityForTuningValue(mBrightnessView, newValue);
@@ -391,8 +328,8 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
view.setVisibility(TunerService.parseIntegerSwitch(newValue, true) ? VISIBLE : GONE);
}
- public void openDetails(String subPanel) {
- QSTile tile = getTile(subPanel);
+ /** */
+ public void openDetails(QSTile tile) {
// If there's no tile with that name (as defined in QSFactoryImpl or other QSFactory),
// QSFactory will not be able to create a tile and getTile will return null
if (tile != null) {
@@ -400,15 +337,6 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
}
}
- private QSTile getTile(String subPanel) {
- for (int i = 0; i < mRecords.size(); i++) {
- if (subPanel.equals(mRecords.get(i).tile.getTileSpec())) {
- return mRecords.get(i).tile;
- }
- }
- return mHost.createTile(subPanel);
- }
-
public void setBrightnessMirror(BrightnessMirrorController c) {
if (mBrightnessMirrorController != null) {
mBrightnessMirrorController.removeCallback(this);
@@ -434,17 +362,8 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
mCallback = callback;
}
- public void setHost(QSTileHost host, QSCustomizer customizer) {
- mHost = host;
- mHost.addCallback(this);
- setTiles(mHost.getTiles());
- if (mSecurityFooter != null) {
- mSecurityFooter.setHostEnvironment(host);
- }
+ void setCustomizer(QSCustomizer customizer) {
mCustomizePanel = customizer;
- if (mCustomizePanel != null) {
- mCustomizePanel.setHost(mHost);
- }
}
/**
@@ -483,9 +402,6 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
updatePageIndicator();
- if (mListening) {
- refreshAllTiles();
- }
if (mTileLayout != null) {
mTileLayout.updateResources();
}
@@ -506,20 +422,21 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
res.getDimensionPixelSize(R.dimen.qs_panel_padding_bottom));
}
+ void addOnConfigurationChangedListener(OnConfigurationChangedListener listener) {
+ mOnConfigurationChangedListeners.add(listener);
+ }
+
+ void removeOnConfigurationChangedListener(OnConfigurationChangedListener listener) {
+ mOnConfigurationChangedListeners.remove(listener);
+ }
+
@Override
protected void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
- if (mSecurityFooter != null) {
- mSecurityFooter.onConfigurationChanged();
- }
- updateResources();
+ mOnConfigurationChangedListeners.forEach(
+ listener -> listener.onConfigurationChange(newConfig));
updateBrightnessMirror();
-
- if (newConfig.orientation != mLastOrientation) {
- mLastOrientation = newConfig.orientation;
- switchTileLayout();
- }
}
@Override
@@ -527,14 +444,9 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
super.onFinishInflate();
mFooter = findViewById(R.id.qs_footer);
mDivider = findViewById(R.id.divider);
- switchTileLayout(true /* force */);
- }
-
- boolean switchTileLayout() {
- return switchTileLayout(false /* force */);
}
- private boolean switchTileLayout(boolean force) {
+ boolean switchTileLayout(boolean force, List<QSPanelControllerBase.TileRecord> records) {
/** Whether or not the QuickQSPanel currently contains a media player. */
boolean horizontal = shouldUseHorizontalLayout();
if (mDivider != null) {
@@ -562,13 +474,12 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
reAttachMediaHost();
if (mTileLayout != null) {
mTileLayout.setListening(false);
- for (TileRecord record : mRecords) {
+ for (QSPanelControllerBase.TileRecord record : records) {
mTileLayout.removeTile(record);
record.tile.removeCallback(record.callback);
}
}
mTileLayout = newLayout;
- if (mHost != null) setTiles(mHost.getTiles());
newLayout.setListening(mListening);
if (needsDynamicRowsAndColumns()) {
newLayout.setMinRows(horizontal ? 2 : 1);
@@ -617,20 +528,20 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
index++;
if (mSecurityFooter != null) {
- View view = mSecurityFooter.getView();
- LinearLayout.LayoutParams layoutParams = (LayoutParams) view.getLayoutParams();
+ LinearLayout.LayoutParams layoutParams =
+ (LayoutParams) mSecurityFooter.getLayoutParams();
if (mUsingHorizontalLayout && mHeaderContainer != null) {
// Adding the security view to the header, that enables us to avoid scrolling
layoutParams.width = 0;
layoutParams.weight = 1.6f;
- switchToParent(view, mHeaderContainer, 1 /* always in second place */);
+ switchToParent(mSecurityFooter, mHeaderContainer, 1 /* always in second place */);
} else {
layoutParams.width = LayoutParams.WRAP_CONTENT;
layoutParams.weight = 0;
- switchToParent(view, parent, index);
+ switchToParent(mSecurityFooter, parent, index);
index++;
}
- view.setLayoutParams(layoutParams);
+ mSecurityFooter.setLayoutParams(layoutParams);
}
if (mFooter != null) {
@@ -703,14 +614,6 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
if (!mExpanded && mTileLayout instanceof PagedTileLayout) {
((PagedTileLayout) mTileLayout).setCurrentItem(0, false);
}
- mMetricsLogger.visibility(MetricsEvent.QS_PANEL, mExpanded);
- if (!mExpanded) {
- mUiEventLogger.log(closePanelEvent());
- closeDetail();
- } else {
- mUiEventLogger.log(openPanelEvent());
- logTiles();
- }
}
public void setPageListener(final PagedTileLayout.PageListener pageListener) {
@@ -723,56 +626,16 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
return mExpanded;
}
- public void setListening(boolean listening) {
+ /** */
+ public void setListening(boolean listening, String cachedSpecs) {
if (mListening == listening) return;
mListening = listening;
if (mTileLayout != null) {
- mQSLogger.logAllTilesChangeListening(listening, getDumpableTag(), mCachedSpecs);
+ mQSLogger.logAllTilesChangeListening(listening, getDumpableTag(), cachedSpecs);
mTileLayout.setListening(listening);
}
- if (mListening) {
- refreshAllTiles();
- }
}
- private String getTilesSpecs() {
- return mRecords.stream()
- .map(tileRecord -> tileRecord.tile.getTileSpec())
- .collect(Collectors.joining(","));
- }
-
- public void setListening(boolean listening, boolean expanded) {
- setListening(listening && expanded);
- if (mSecurityFooter != null) {
- mSecurityFooter.setListening(listening);
- }
- // Set the listening as soon as the QS fragment starts listening regardless of the expansion,
- // so it will update the current brightness before the slider is visible.
- setBrightnessListening(listening);
- }
-
- public void setBrightnessListening(boolean listening) {
- if (mBrightnessController == null) {
- return;
- }
- if (listening) {
- mBrightnessController.registerCallbacks();
- } else {
- mBrightnessController.unregisterCallbacks();
- }
- }
-
- public void refreshAllTiles() {
- if (mBrightnessController != null) {
- mBrightnessController.checkRestrictionAndSetEnabled();
- }
- for (TileRecord r : mRecords) {
- r.tile.refreshState();
- }
- if (mSecurityFooter != null) {
- mSecurityFooter.refreshState();
- }
- }
public void showDetailAdapter(boolean show, DetailAdapter adapter, int[] locationInWindow) {
int xInWindow = locationInWindow[0];
@@ -794,33 +657,10 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
mHandler.obtainMessage(H.SHOW_DETAIL, show ? 1 : 0, 0, r).sendToTarget();
}
- public void setTiles(Collection<QSTile> tiles) {
- setTiles(tiles, false);
- }
-
- public void setTiles(Collection<QSTile> tiles, boolean collapsedView) {
- if (!collapsedView) {
- mQsTileRevealController.updateRevealedTiles(tiles);
- }
- for (TileRecord record : mRecords) {
- mTileLayout.removeTile(record);
- record.tile.removeCallback(record.callback);
- }
- mRecords.clear();
- mCachedSpecs = "";
- for (QSTile tile : tiles) {
- addTile(tile, collapsedView);
- }
- }
-
- protected void drawTile(TileRecord r, QSTile.State state) {
+ protected void drawTile(QSPanelControllerBase.TileRecord r, QSTile.State state) {
r.tileView.onStateChanged(state);
}
- protected QSTileView createTileView(QSTile tile, boolean collapsedView) {
- return mHost.createTileView(tile, collapsedView);
- }
-
protected QSEvent openPanelEvent() {
return QSEvent.QS_PANEL_EXPANDED;
}
@@ -837,14 +677,15 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
return mExpanded;
}
- protected TileRecord addTile(final QSTile tile, boolean collapsedView) {
- final TileRecord r = new TileRecord();
- r.tile = tile;
- r.tileView = createTileView(tile, collapsedView);
+ void updateRevealedTiles(Collection<QSTile> tiles) {
+ mQsTileRevealController.updateRevealedTiles(tiles);
+ }
+
+ void addTile(QSPanelControllerBase.TileRecord tileRecord) {
final QSTile.Callback callback = new QSTile.Callback() {
@Override
public void onStateChanged(QSTile.State state) {
- drawTile(r, state);
+ drawTile(tileRecord, state);
}
@Override
@@ -852,22 +693,22 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
// Both the collapsed and full QS panels get this callback, this check determines
// which one should handle showing the detail.
if (shouldShowDetail()) {
- QSPanel.this.showDetail(show, r);
+ QSPanel.this.showDetail(show, tileRecord);
}
}
@Override
public void onToggleStateChanged(boolean state) {
- if (mDetailRecord == r) {
+ if (mDetailRecord == tileRecord) {
fireToggleStateChanged(state);
}
}
@Override
public void onScanStateChanged(boolean state) {
- r.scanState = state;
- if (mDetailRecord == r) {
- fireScanStateChanged(r.scanState);
+ tileRecord.scanState = state;
+ if (mDetailRecord == tileRecord) {
+ fireScanStateChanged(tileRecord.scanState);
}
}
@@ -879,20 +720,20 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
}
}
};
- r.tile.addCallback(callback);
- r.callback = callback;
- r.tileView.init(r.tile);
- r.tile.refreshState();
- mRecords.add(r);
- mCachedSpecs = getTilesSpecs();
+
+ tileRecord.tile.addCallback(callback);
+ tileRecord.callback = callback;
+ tileRecord.tileView.init(tileRecord.tile);
+ tileRecord.tile.refreshState();
if (mTileLayout != null) {
- mTileLayout.addTile(r);
+ mTileLayout.addTile(tileRecord);
}
-
- return r;
}
+ void removeTile(QSPanelControllerBase.TileRecord tileRecord) {
+ mTileLayout.removeTile(tileRecord);
+ }
public void showEdit(final View v) {
v.post(new Runnable() {
@@ -925,8 +766,8 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
}
protected void handleShowDetail(Record r, boolean show) {
- if (r instanceof TileRecord) {
- handleShowDetailTile((TileRecord) r, show);
+ if (r instanceof QSPanelControllerBase.TileRecord) {
+ handleShowDetailTile((QSPanelControllerBase.TileRecord) r, show);
} else {
int x = 0;
int y = 0;
@@ -938,7 +779,7 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
}
}
- private void handleShowDetailTile(TileRecord r, boolean show) {
+ private void handleShowDetailTile(QSPanelControllerBase.TileRecord r, boolean show) {
if ((mDetailRecord != null) == show && mDetailRecord == r) return;
if (show) {
@@ -959,8 +800,8 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
protected void setDetailRecord(Record r) {
if (r == mDetailRecord) return;
mDetailRecord = r;
- final boolean scanState = mDetailRecord instanceof TileRecord
- && ((TileRecord) mDetailRecord).scanState;
+ final boolean scanState = mDetailRecord instanceof QSPanelControllerBase.TileRecord
+ && ((QSPanelControllerBase.TileRecord) mDetailRecord).scanState;
fireScanStateChanged(scanState);
}
@@ -972,15 +813,6 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
}
mGridContentVisible = visible;
}
-
- private void logTiles() {
- for (int i = 0; i < mRecords.size(); i++) {
- QSTile tile = mRecords.get(i).tile;
- mMetricsLogger.write(tile.populate(new LogMaker(tile.getMetricsCategory())
- .setType(MetricsEvent.TYPE_OPEN)));
- }
- }
-
private void fireShowingDetail(DetailAdapter detail, int x, int y) {
if (mCallback != null) {
mCallback.onShowingDetail(detail, x, y);
@@ -999,46 +831,15 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
}
}
- public void clickTile(ComponentName tile) {
- final String spec = CustomTile.toSpec(tile);
- final int N = mRecords.size();
- for (int i = 0; i < N; i++) {
- if (mRecords.get(i).tile.getTileSpec().equals(spec)) {
- mRecords.get(i).tile.click();
- break;
- }
- }
- }
-
QSTileLayout getTileLayout() {
return mTileLayout;
}
- QSTileView getTileView(QSTile tile) {
- for (TileRecord r : mRecords) {
- if (r.tile == tile) {
- return r.tileView;
- }
- }
- return null;
- }
-
- @Nullable
- public QSSecurityFooter getSecurityFooter() {
- return mSecurityFooter;
- }
-
@Nullable
public View getDivider() {
return mDivider;
}
- public void showDeviceMonitoringDialog() {
- if (mSecurityFooter != null) {
- mSecurityFooter.showDeviceMonitoringDialog();
- }
- }
-
public void setContentMargins(int startMargin, int endMargin) {
// Only some views actually want this content padding, others want to go all the way
// to the edge like the brightness slider
@@ -1121,9 +922,11 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
*/
protected void updateMargins(View view, int start, int end) {
LayoutParams lp = (LayoutParams) view.getLayoutParams();
- lp.setMarginStart(start);
- lp.setMarginEnd(end);
- view.setLayoutParams(lp);
+ if (lp != null) {
+ lp.setMarginStart(start);
+ lp.setMarginEnd(end);
+ view.setLayoutParams(lp);
+ }
}
public MediaHost getMediaHost() {
@@ -1141,6 +944,14 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
mMediaVisibilityChangedListener = visibilityChangedListener;
}
+ public boolean isListening() {
+ return mListening;
+ }
+
+ public void setSecurityFooter(View view) {
+ mSecurityFooter = view;
+ }
+
private class H extends Handler {
private static final int SHOW_DETAIL = 1;
private static final int SET_TILE_VISIBILITY = 2;
@@ -1156,46 +967,32 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
}
}
- @Override
- public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- pw.println(getClass().getSimpleName() + ":");
- pw.println(" Tile records:");
- for (TileRecord record : mRecords) {
- if (record.tile instanceof Dumpable) {
- pw.print(" "); ((Dumpable) record.tile).dump(fd, pw, args);
- pw.print(" "); pw.println(record.tileView.toString());
- }
- }
- }
-
-
protected static class Record {
DetailAdapter detailAdapter;
int x;
int y;
}
- public static final class TileRecord extends Record {
- public QSTile tile;
- public com.android.systemui.plugins.qs.QSTileView tileView;
- public boolean scanState;
- public QSTile.Callback callback;
- }
-
public interface QSTileLayout {
-
+ /** */
default void saveInstanceState(Bundle outState) {}
+ /** */
default void restoreInstanceState(Bundle savedInstanceState) {}
- void addTile(TileRecord tile);
+ /** */
+ void addTile(QSPanelControllerBase.TileRecord tile);
- void removeTile(TileRecord tile);
+ /** */
+ void removeTile(QSPanelControllerBase.TileRecord tile);
- int getOffsetTop(TileRecord tile);
+ /** */
+ int getOffsetTop(QSPanelControllerBase.TileRecord tile);
+ /** */
boolean updateResources();
+ /** */
void setListening(boolean listening);
/**
@@ -1222,4 +1019,8 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
int getNumVisibleTiles();
}
+
+ interface OnConfigurationChangedListener {
+ void onConfigurationChange(Configuration newConfig);
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java
new file mode 100644
index 000000000000..4e2351f66ca2
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs;
+
+import static com.android.systemui.qs.QSPanel.QS_SHOW_BRIGHTNESS;
+
+import android.annotation.NonNull;
+import android.content.res.Configuration;
+import android.view.ViewGroup;
+
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.UiEventLogger;
+import com.android.systemui.R;
+import com.android.systemui.dump.DumpManager;
+import com.android.systemui.media.MediaHost;
+import com.android.systemui.plugins.qs.QSTile;
+import com.android.systemui.qs.customize.QSCustomizer;
+import com.android.systemui.qs.dagger.QSScope;
+import com.android.systemui.settings.BrightnessController;
+import com.android.systemui.statusbar.policy.BrightnessMirrorController;
+import com.android.systemui.tuner.TunerService;
+
+import javax.inject.Inject;
+
+/**
+ * Controller for {@link QSPanel}.
+ */
+@QSScope
+public class QSPanelController extends QSPanelControllerBase<QSPanel> {
+ private final QSSecurityFooter mQsSecurityFooter;
+ private final TunerService mTunerService;
+ private final BrightnessController mBrightnessController;
+
+ private final QSPanel.OnConfigurationChangedListener mOnConfigurationChangedListener =
+ new QSPanel.OnConfigurationChangedListener() {
+ @Override
+ public void onConfigurationChange(Configuration newConfig) {
+ mView.updateResources();
+ mQsSecurityFooter.onConfigurationChanged();
+ if (mView.isListening()) {
+ refreshAllTiles();
+ }
+ }
+ };
+ private BrightnessMirrorController mBrightnessMirrorController;
+
+ @Inject
+ QSPanelController(QSPanel view, QSSecurityFooter qsSecurityFooter, TunerService tunerService,
+ QSTileHost qstileHost, DumpManager dumpManager,
+ MetricsLogger metricsLogger, UiEventLogger uiEventLogger,
+ BrightnessController.Factory brightnessControllerFactory) {
+ super(view, qstileHost, metricsLogger, uiEventLogger, dumpManager);
+ mQsSecurityFooter = qsSecurityFooter;
+ mTunerService = tunerService;
+ mQsSecurityFooter.setHostEnvironment(qstileHost);
+ mBrightnessController = brightnessControllerFactory.create(
+ mView.findViewById(R.id.brightness_slider));
+ }
+
+ @Override
+ protected void onViewAttached() {
+ super.onViewAttached();
+ mTunerService.addTunable(mView, QS_SHOW_BRIGHTNESS);
+ mView.updateResources();
+ if (mView.isListening()) {
+ refreshAllTiles();
+ }
+ mView.addOnConfigurationChangedListener(mOnConfigurationChangedListener);
+ mView.setSecurityFooter(mQsSecurityFooter.getView());
+ switchTileLayout(true);
+ if (mBrightnessMirrorController != null) {
+ mBrightnessMirrorController.addCallback(mView);
+ }
+ }
+
+ @Override
+ protected void onViewDetached() {
+ mTunerService.removeTunable(mView);
+ mView.removeOnConfigurationChangedListener(mOnConfigurationChangedListener);
+ if (mBrightnessMirrorController != null) {
+ mBrightnessMirrorController.removeCallback(mView);
+ }
+ super.onViewDetached();
+ }
+
+ /** TODO(b/168904199): Remove this method once view is controllerized. */
+ QSPanel getView() {
+ return mView;
+ }
+
+ /**
+ * Set the header container of quick settings.
+ */
+ public void setHeaderContainer(@NonNull ViewGroup headerContainer) {
+ mView.setHeaderContainer(headerContainer);
+ }
+
+ public QSPanel.QSTileLayout getTileLayout() {
+ return mView.getTileLayout();
+ }
+
+ /** */
+ public void setCustomizer(QSCustomizer customizer) {
+ mView.setCustomizer(customizer);
+ }
+
+ /** */
+ public boolean isShowingCustomize() {
+ return mView.isShowingCustomize();
+ }
+
+ /** */
+ public void setVisibility(int visibility) {
+ mView.setVisibility(visibility);
+ }
+
+ /** */
+ public void setListening(boolean listening, boolean expanded) {
+ setListening(listening && expanded);
+ if (mView.isListening()) {
+ refreshAllTiles();
+ }
+
+ mQsSecurityFooter.setListening(listening);
+
+ // Set the listening as soon as the QS fragment starts listening regardless of the
+ //expansion, so it will update the current brightness before the slider is visible.
+ if (listening) {
+ mBrightnessController.registerCallbacks();
+ } else {
+ mBrightnessController.unregisterCallbacks();
+ }
+ }
+
+ /** */
+ public QSTileRevealController getQsTileRevealController() {
+ return mView.getQsTileRevealController();
+ }
+
+ /** */
+ public MediaHost getMediaHost() {
+ return mView.getMediaHost();
+ }
+
+ /** */
+ public void setBrightnessMirror(BrightnessMirrorController brightnessMirrorController) {
+ mBrightnessMirrorController = brightnessMirrorController;
+ mView.setBrightnessMirror(brightnessMirrorController);
+ }
+
+ /** Get the QSTileHost this panel uses. */
+ public QSTileHost getHost() {
+ return mHost;
+ }
+
+
+ /** Open the details for a specific tile.. */
+ public void openDetails(String subPanel) {
+ QSTile tile = getTile(subPanel);
+ if (tile != null) {
+ mView.openDetails(tile);
+ }
+ }
+
+ /** Show the device monitoring dialog. */
+ public void showDeviceMonitoringDialog() {
+ mQsSecurityFooter.showDeviceMonitoringDialog();
+ }
+
+ /** Update appearance of QSPanel. */
+ public void updateResources() {
+ mView.updateResources();
+ }
+
+ /** Update state of all tiles. */
+ public void refreshAllTiles() {
+ mBrightnessController.checkRestrictionAndSetEnabled();
+ super.refreshAllTiles();
+ mQsSecurityFooter.refreshState();
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java
new file mode 100644
index 000000000000..fe92827806c6
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java
@@ -0,0 +1,250 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs;
+
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+
+import android.content.ComponentName;
+import android.content.res.Configuration;
+import android.metrics.LogMaker;
+
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.UiEventLogger;
+import com.android.systemui.Dumpable;
+import com.android.systemui.dump.DumpManager;
+import com.android.systemui.media.MediaHost;
+import com.android.systemui.plugins.qs.QSTile;
+import com.android.systemui.plugins.qs.QSTileView;
+import com.android.systemui.qs.external.CustomTile;
+import com.android.systemui.util.ViewController;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.stream.Collectors;
+
+/**
+ * Controller for QSPanel views.
+ *
+ * @param <T> Type of QSPanel.
+ */
+public abstract class QSPanelControllerBase<T extends QSPanel> extends ViewController<T>
+ implements Dumpable{
+ protected final QSTileHost mHost;
+ private final MediaHost mMediaHost;
+ private final MetricsLogger mMetricsLogger;
+ private final UiEventLogger mUiEventLogger;
+ private final DumpManager mDumpManager;
+ protected final ArrayList<TileRecord> mRecords = new ArrayList<>();
+
+ private int mLastOrientation;
+
+ private final QSHost.Callback mQSHostCallback = this::setTiles;
+
+ private final QSPanel.OnConfigurationChangedListener mOnConfigurationChangedListener =
+ new QSPanel.OnConfigurationChangedListener() {
+ @Override
+ public void onConfigurationChange(Configuration newConfig) {
+ if (newConfig.orientation != mLastOrientation) {
+ mLastOrientation = newConfig.orientation;
+ switchTileLayout(false);
+ }
+ }
+ };
+ private String mCachedSpecs = "";
+
+ protected QSPanelControllerBase(T view, QSTileHost host,
+ MetricsLogger metricsLogger, UiEventLogger uiEventLogger, DumpManager dumpManager) {
+ super(view);
+ mHost = host;
+ mMediaHost = mView.getMediaHost();
+ mMetricsLogger = metricsLogger;
+ mUiEventLogger = uiEventLogger;
+ mDumpManager = dumpManager;
+ }
+
+ @Override
+ protected void onViewAttached() {
+ mView.addOnConfigurationChangedListener(mOnConfigurationChangedListener);
+ mHost.addCallback(mQSHostCallback);
+ mMediaHost.addVisibilityChangeListener(aBoolean -> {
+ switchTileLayout(false);
+ return null;
+ });
+ setTiles();
+ switchTileLayout(true);
+ mDumpManager.registerDumpable(mView.getDumpableTag(), this);
+ }
+
+ @Override
+ protected void onViewDetached() {
+ mView.removeOnConfigurationChangedListener(mOnConfigurationChangedListener);
+ mHost.removeCallback(mQSHostCallback);
+
+ for (TileRecord record : mRecords) {
+ record.tile.removeCallbacks();
+ }
+ mRecords.clear();
+ mDumpManager.unregisterDumpable(mView.getDumpableTag());
+ }
+
+ /** */
+ public void setTiles() {
+ setTiles(mHost.getTiles(), false);
+ }
+
+ /** */
+ public void setTiles(Collection<QSTile> tiles, boolean collapsedView) {
+ if (!collapsedView) {
+ mView.updateRevealedTiles(tiles);
+ }
+ for (QSPanelControllerBase.TileRecord record : mRecords) {
+ mView.removeTile(record);
+ record.tile.removeCallback(record.callback);
+ }
+ mRecords.clear();
+ mCachedSpecs = "";
+ for (QSTile tile : tiles) {
+ addTile(tile, collapsedView);
+ }
+ }
+
+ /** */
+ public void refreshAllTiles() {
+ for (QSPanelControllerBase.TileRecord r : mRecords) {
+ r.tile.refreshState();
+ }
+ }
+
+ private void addTile(final QSTile tile, boolean collapsedView) {
+ final TileRecord r = new TileRecord();
+ r.tile = tile;
+ r.tileView = mHost.createTileView(tile, collapsedView);
+ mView.addTile(r);
+ mRecords.add(r);
+ mCachedSpecs = getTilesSpecs();
+
+ }
+
+ /** */
+ public void clickTile(ComponentName tile) {
+ final String spec = CustomTile.toSpec(tile);
+ for (TileRecord record : mRecords) {
+ if (record.tile.getTileSpec().equals(spec)) {
+ record.tile.click();
+ break;
+ }
+ }
+ }
+ protected QSTile getTile(String subPanel) {
+ for (int i = 0; i < mRecords.size(); i++) {
+ if (subPanel.equals(mRecords.get(i).tile.getTileSpec())) {
+ return mRecords.get(i).tile;
+ }
+ }
+ return mHost.createTile(subPanel);
+ }
+
+
+ QSTileView getTileView(QSTile tile) {
+ for (QSPanelControllerBase.TileRecord r : mRecords) {
+ if (r.tile == tile) {
+ return r.tileView;
+ }
+ }
+ return null;
+ }
+
+ private String getTilesSpecs() {
+ return mRecords.stream()
+ .map(tileRecord -> tileRecord.tile.getTileSpec())
+ .collect(Collectors.joining(","));
+ }
+
+
+ /** */
+ public void setExpanded(boolean expanded) {
+ mView.setExpanded(expanded);
+ mMetricsLogger.visibility(MetricsEvent.QS_PANEL, expanded);
+ if (!expanded) {
+ mUiEventLogger.log(mView.closePanelEvent());
+ closeDetail();
+ } else {
+ mUiEventLogger.log(mView.openPanelEvent());
+ logTiles();
+ }
+ }
+
+ /** */
+ public void closeDetail() {
+ mView.closeDetail();
+ }
+
+ /** */
+ public void openDetails(String subPanel) {
+ QSTile tile = getTile(subPanel);
+ // If there's no tile with that name (as defined in QSFactoryImpl or other QSFactory),
+ // QSFactory will not be able to create a tile and getTile will return null
+ if (tile != null) {
+ mView.showDetailAdapter(
+ true, tile.getDetailAdapter(), new int[]{mView.getWidth() / 2, 0});
+ }
+ }
+
+
+ void setListening(boolean listening) {
+ mView.setListening(listening, mCachedSpecs);
+ }
+
+ boolean switchTileLayout(boolean force) {
+ if (mView.switchTileLayout(force, mRecords)) {
+ setTiles();
+ return true;
+ }
+ return false;
+ }
+
+ private void logTiles() {
+ for (int i = 0; i < mRecords.size(); i++) {
+ QSTile tile = mRecords.get(i).tile;
+ mMetricsLogger.write(tile.populate(new LogMaker(tile.getMetricsCategory())
+ .setType(MetricsEvent.TYPE_OPEN)));
+ }
+ }
+
+
+ @Override
+ public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ pw.println(getClass().getSimpleName() + ":");
+ pw.println(" Tile records:");
+ for (QSPanelControllerBase.TileRecord record : mRecords) {
+ if (record.tile instanceof Dumpable) {
+ pw.print(" "); ((Dumpable) record.tile).dump(fd, pw, args);
+ pw.print(" "); pw.println(record.tileView.toString());
+ }
+ }
+ }
+
+ /** */
+ public static final class TileRecord extends QSPanel.Record {
+ public QSTile tile;
+ public com.android.systemui.plugins.qs.QSTileView tileView;
+ public boolean scanState;
+ public QSTile.Callback callback;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java b/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java
index 0891972c11d2..c90182b15da6 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java
@@ -44,11 +44,15 @@ import com.android.systemui.Dependency;
import com.android.systemui.FontSizeUtils;
import com.android.systemui.R;
import com.android.systemui.plugins.ActivityStarter;
+import com.android.systemui.qs.dagger.QSScope;
import com.android.systemui.settings.UserTracker;
import com.android.systemui.statusbar.phone.SystemUIDialog;
import com.android.systemui.statusbar.policy.SecurityController;
-public class QSSecurityFooter implements OnClickListener, DialogInterface.OnClickListener {
+import javax.inject.Inject;
+
+@QSScope
+class QSSecurityFooter implements OnClickListener, DialogInterface.OnClickListener {
protected static final String TAG = "QSSecurityFooter";
protected static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
private static final boolean DEBUG_FORCE_VISIBLE = false;
@@ -72,12 +76,13 @@ public class QSSecurityFooter implements OnClickListener, DialogInterface.OnClic
private int mFooterTextId;
private int mFooterIconId;
+ @Inject
public QSSecurityFooter(QSPanel qsPanel, Context context, UserTracker userTracker) {
mRootView = LayoutInflater.from(context)
.inflate(R.layout.quick_settings_footer, qsPanel, false);
mRootView.setOnClickListener(this);
- mFooterText = (TextView) mRootView.findViewById(R.id.footer_text);
- mFooterIcon = (ImageView) mRootView.findViewById(R.id.footer_icon);
+ mFooterText = mRootView.findViewById(R.id.footer_text);
+ mFooterIcon = mRootView.findViewById(R.id.footer_icon);
mFooterIconId = R.drawable.ic_info_outline;
mContext = context;
mMainHandler = new Handler(Looper.myLooper());
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTileRevealController.java b/packages/SystemUI/src/com/android/systemui/qs/QSTileRevealController.java
index 2f012e6e608e..3d4a417abf2e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTileRevealController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTileRevealController.java
@@ -8,11 +8,16 @@ import android.util.ArraySet;
import com.android.systemui.Prefs;
import com.android.systemui.plugins.qs.QSTile;
+import com.android.systemui.qs.dagger.QSScope;
import java.util.Collection;
import java.util.Collections;
import java.util.Set;
+import javax.inject.Inject;
+
+/** */
+@QSScope
public class QSTileRevealController {
private static final long QS_REVEAL_TILES_DELAY = 500L;
@@ -34,6 +39,7 @@ public class QSTileRevealController {
}
};
+ @Inject
QSTileRevealController(Context context, QSPanel qsPanel, PagedTileLayout pagedTileLayout) {
mContext = context;
mQSPanel = qsPanel;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
index 82cb8639e9ee..84a5b6f0538d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
@@ -28,23 +28,13 @@ import android.view.View;
import android.widget.LinearLayout;
import com.android.internal.logging.UiEventLogger;
-import com.android.systemui.Dependency;
import com.android.systemui.R;
-import com.android.systemui.broadcast.BroadcastDispatcher;
-import com.android.systemui.dump.DumpManager;
import com.android.systemui.media.MediaHierarchyManager;
import com.android.systemui.media.MediaHost;
import com.android.systemui.plugins.qs.QSTile;
import com.android.systemui.plugins.qs.QSTile.SignalState;
import com.android.systemui.plugins.qs.QSTile.State;
-import com.android.systemui.qs.customize.QSCustomizer;
import com.android.systemui.qs.logging.QSLogger;
-import com.android.systemui.settings.UserTracker;
-import com.android.systemui.tuner.TunerService;
-import com.android.systemui.tuner.TunerService.Tunable;
-
-import java.util.ArrayList;
-import java.util.Collection;
import javax.inject.Inject;
import javax.inject.Named;
@@ -68,15 +58,10 @@ public class QuickQSPanel extends QSPanel {
public QuickQSPanel(
@Named(VIEW_CONTEXT) Context context,
AttributeSet attrs,
- DumpManager dumpManager,
- BroadcastDispatcher broadcastDispatcher,
QSLogger qsLogger,
@Named(QUICK_QS_PANEL) MediaHost mediaHost,
- UiEventLogger uiEventLogger,
- UserTracker userTracker
- ) {
- super(context, attrs, dumpManager, broadcastDispatcher, qsLogger, mediaHost, uiEventLogger,
- userTracker);
+ UiEventLogger uiEventLogger) {
+ super(context, attrs, qsLogger, mediaHost, uiEventLogger);
sDefaultMaxTiles = getResources().getInteger(R.integer.quick_qs_panel_max_columns);
applyBottomMargin((View) mRegularTileLayout);
}
@@ -89,17 +74,12 @@ public class QuickQSPanel extends QSPanel {
}
@Override
- protected void addSecurityFooter() {
- // No footer needed
- }
-
- @Override
protected void addViewsAboveTiles() {
// Nothing to add above the tiles
}
@Override
- protected TileLayout createRegularTileLayout() {
+ public TileLayout createRegularTileLayout() {
return new QuickQSPanel.HeaderTileLayout(mContext, mUiEventLogger);
}
@@ -133,18 +113,6 @@ public class QuickQSPanel extends QSPanel {
}
@Override
- protected void onAttachedToWindow() {
- super.onAttachedToWindow();
- Dependency.get(TunerService.class).addTunable(mNumTiles, NUM_QUICK_TILES);
- }
-
- @Override
- protected void onDetachedFromWindow() {
- super.onDetachedFromWindow();
- Dependency.get(TunerService.class).removeTunable(mNumTiles);
- }
-
- @Override
protected String getDumpableTag() {
return TAG;
}
@@ -159,7 +127,7 @@ public class QuickQSPanel extends QSPanel {
}
@Override
- protected void drawTile(TileRecord r, State state) {
+ protected void drawTile(QSPanelControllerBase.TileRecord r, State state) {
if (state instanceof SignalState) {
SignalState copy = new SignalState();
state.copyTo(copy);
@@ -171,17 +139,8 @@ public class QuickQSPanel extends QSPanel {
super.drawTile(r, state);
}
- @Override
- public void setHost(QSTileHost host, QSCustomizer customizer) {
- super.setHost(host, customizer);
- setTiles(mHost.getTiles());
- }
-
public void setMaxTiles(int maxTiles) {
mMaxTiles = maxTiles;
- if (mHost != null) {
- setTiles(mHost.getTiles());
- }
}
@Override
@@ -192,25 +151,6 @@ public class QuickQSPanel extends QSPanel {
}
}
- @Override
- public void setTiles(Collection<QSTile> tiles) {
- ArrayList<QSTile> quickTiles = new ArrayList<>();
- for (QSTile tile : tiles) {
- quickTiles.add(tile);
- if (quickTiles.size() == mMaxTiles) {
- break;
- }
- }
- super.setTiles(quickTiles, true);
- }
-
- private final Tunable mNumTiles = new Tunable() {
- @Override
- public void onTuningChanged(String key, String newValue) {
- setMaxTiles(parseNumTiles(newValue));
- }
- };
-
public int getNumQuickTiles() {
return mMaxTiles;
}
@@ -308,7 +248,7 @@ public class QuickQSPanel extends QSPanel {
}
@Override
- protected void addTileView(TileRecord tile) {
+ protected void addTileView(QSPanelControllerBase.TileRecord tile) {
addView(tile.tileView, getChildCount(), generateTileLayoutParams());
}
@@ -371,7 +311,7 @@ public class QuickQSPanel extends QSPanel {
private void setAccessibilityOrder() {
if (mRecords != null && mRecords.size() > 0) {
View previousView = this;
- for (TileRecord record : mRecords) {
+ for (QSPanelControllerBase.TileRecord record : mRecords) {
if (record.tileView.getVisibility() == GONE) continue;
previousView = record.tileView.updateAccessibilityOrder(previousView);
}
@@ -383,7 +323,7 @@ public class QuickQSPanel extends QSPanel {
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// Measure each QS tile.
- for (TileRecord record : mRecords) {
+ for (QSPanelControllerBase.TileRecord record : mRecords) {
if (record.tileView.getVisibility() == GONE) continue;
record.tileView.measure(exactly(mCellWidth), exactly(mCellHeight));
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanelController.java b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanelController.java
new file mode 100644
index 000000000000..97b6e99a0390
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanelController.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs;
+
+import static com.android.systemui.qs.QuickQSPanel.NUM_QUICK_TILES;
+import static com.android.systemui.qs.QuickQSPanel.parseNumTiles;
+
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.UiEventLogger;
+import com.android.systemui.dump.DumpManager;
+import com.android.systemui.plugins.qs.QSTile;
+import com.android.systemui.qs.dagger.QSScope;
+import com.android.systemui.tuner.TunerService;
+import com.android.systemui.tuner.TunerService.Tunable;
+
+import java.util.ArrayList;
+
+import javax.inject.Inject;
+
+/** Controller for {@link QuickQSPanel}. */
+@QSScope
+public class QuickQSPanelController extends QSPanelControllerBase<QuickQSPanel> {
+ private final Tunable mNumTiles =
+ (key, newValue) -> setMaxTiles(parseNumTiles(newValue));
+
+ private final TunerService mTunerService;
+
+ @Inject
+ QuickQSPanelController(QuickQSPanel view, TunerService tunerService, QSTileHost qsTileHost,
+ MetricsLogger metricsLogger, UiEventLogger uiEventLogger,
+ DumpManager dumpManager) {
+ super(view, qsTileHost, metricsLogger, uiEventLogger, dumpManager);
+ mTunerService = tunerService;
+ }
+
+ @Override
+ protected void onViewAttached() {
+ super.onViewAttached();
+ mTunerService.addTunable(mNumTiles, NUM_QUICK_TILES);
+
+ }
+
+ @Override
+ protected void onViewDetached() {
+ super.onViewDetached();
+ mTunerService.removeTunable(mNumTiles);
+ }
+
+ public boolean isListening() {
+ return mView.isListening();
+ }
+
+ private void setMaxTiles(int parseNumTiles) {
+ mView.setMaxTiles(parseNumTiles);
+ setTiles();
+ }
+
+ @Override
+ public void setTiles() {
+ ArrayList<QSTile> quickTiles = new ArrayList<>();
+ for (QSTile tile : mHost.getTiles()) {
+ quickTiles.add(tile);
+ if (quickTiles.size() == mView.getNumQuickTiles()) {
+ break;
+ }
+ }
+ super.setTiles(quickTiles, true);
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
index a9fbc744b38e..5757602b9d0f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
@@ -353,11 +353,7 @@ public class QuickStatusBarHeader extends RelativeLayout implements LifecycleOwn
mPrivacyChip.setExpanded(expansionFraction > 0.5);
mPrivacyChipAlphaAnimator.setPosition(keyguardExpansionFraction);
}
- if (expansionFraction < 1 && expansionFraction > 0.99) {
- if (mHeaderQsPanel.switchTileLayout()) {
- updateResources();
- }
- }
+
mKeyguardExpansionFraction = keyguardExpansionFraction;
}
@@ -446,7 +442,6 @@ public class QuickStatusBarHeader extends RelativeLayout implements LifecycleOwn
public void setQSPanel(final QSPanel qsPanel) {
//host.setHeaderView(mExpandIndicator);
mHeaderQsPanel.setQSPanelAndHeader(qsPanel, this);
- mHeaderQsPanel.setHost(qsPanel.getHost(), null /* No customization in header */);
Rect tintArea = new Rect(0, 0, 0, 0);
int colorForeground = Utils.getColorAttrDefaultColor(getContext(),
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java
index 398edd7002ee..febb71c3223b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java
@@ -44,6 +44,7 @@ import com.android.systemui.privacy.PrivacyChipEvent;
import com.android.systemui.privacy.PrivacyItem;
import com.android.systemui.privacy.PrivacyItemController;
import com.android.systemui.qs.carrier.QSCarrierGroupController;
+import com.android.systemui.qs.dagger.QSScope;
import com.android.systemui.settings.UserTracker;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.phone.StatusBarIconController;
@@ -64,6 +65,7 @@ import javax.inject.Inject;
/**
* Controller for {@link QuickStatusBarHeader}.
*/
+@QSScope
class QuickStatusBarHeaderController extends ViewController<QuickStatusBarHeader> {
private static final String TAG = "QuickStatusBarHeader";
@@ -74,7 +76,7 @@ class QuickStatusBarHeaderController extends ViewController<QuickStatusBarHeader
private final ActivityStarter mActivityStarter;
private final UiEventLogger mUiEventLogger;
private final QSCarrierGroupController mQSCarrierGroupController;
- private final QuickQSPanel mHeaderQsPanel;
+ private final QuickQSPanelController mHeaderQsPanelController;
private final LifecycleRegistry mLifecycle;
private final OngoingPrivacyChip mPrivacyChip;
private final Clock mClockView;
@@ -203,13 +205,14 @@ class QuickStatusBarHeaderController extends ViewController<QuickStatusBarHeader
}
};
- private QuickStatusBarHeaderController(QuickStatusBarHeader view,
+ @Inject
+ QuickStatusBarHeaderController(QuickStatusBarHeader view,
ZenModeController zenModeController, NextAlarmController nextAlarmController,
PrivacyItemController privacyItemController, RingerModeTracker ringerModeTracker,
ActivityStarter activityStarter, UiEventLogger uiEventLogger,
QSTileHost qsTileHost, StatusBarIconController statusBarIconController,
CommandQueue commandQueue, DemoModeController demoModeController,
- UserTracker userTracker,
+ UserTracker userTracker, QuickQSPanelController quickQSPanelController,
QSCarrierGroupController.Builder qsCarrierGroupControllerBuilder) {
super(view);
mZenModeController = zenModeController;
@@ -224,6 +227,7 @@ class QuickStatusBarHeaderController extends ViewController<QuickStatusBarHeader
mDemoModeController = demoModeController;
mUserTracker = userTracker;
mLifecycle = new LifecycleRegistry(mLifecycleOwner);
+ mHeaderQsPanelController = quickQSPanelController;
mQSCarrierGroupController = qsCarrierGroupControllerBuilder
.setQSCarrierGroup(mView.findViewById(R.id.carrier_group))
@@ -231,7 +235,6 @@ class QuickStatusBarHeaderController extends ViewController<QuickStatusBarHeader
mPrivacyChip = mView.findViewById(R.id.privacy_chip);
- mHeaderQsPanel = mView.findViewById(R.id.quick_qs_panel);
mNextAlarmContainer = mView.findViewById(R.id.alarm_container);
mClockView = mView.findViewById(R.id.clock);
mRingerContainer = mView.findViewById(R.id.ringer_container);
@@ -290,8 +293,12 @@ class QuickStatusBarHeaderController extends ViewController<QuickStatusBarHeader
}
mListening = listening;
- mHeaderQsPanel.setListening(listening);
- if (mHeaderQsPanel.switchTileLayout()) {
+ mHeaderQsPanelController.setListening(listening);
+ if (mHeaderQsPanelController.isListening()) {
+ mHeaderQsPanelController.refreshAllTiles();
+ }
+
+ if (mHeaderQsPanelController.switchTileLayout(false)) {
mView.updateResources();
}
@@ -380,55 +387,4 @@ class QuickStatusBarHeaderController extends ViewController<QuickStatusBarHeader
mClockView.onDemoModeFinished();
}
}
-
- static class Builder {
- private final ZenModeController mZenModeController;
- private final NextAlarmController mNextAlarmController;
- private final PrivacyItemController mPrivacyItemController;
- private final RingerModeTracker mRingerModeTracker;
- private final ActivityStarter mActivityStarter;
- private final UiEventLogger mUiEventLogger;
- private final QSTileHost mQsTileHost;
- private final StatusBarIconController mStatusBarIconController;
- private final CommandQueue mCommandQueue;
- private final DemoModeController mDemoModeController;
- private final UserTracker mUserTracker;
- private final QSCarrierGroupController.Builder mQSCarrierGroupControllerBuilder;
- private QuickStatusBarHeader mView;
-
- @Inject
- Builder(ZenModeController zenModeController, NextAlarmController nextAlarmController,
- PrivacyItemController privacyItemController, RingerModeTracker ringerModeTracker,
- ActivityStarter activityStarter, UiEventLogger uiEventLogger, QSTileHost qsTileHost,
- StatusBarIconController statusBarIconController, CommandQueue commandQueue,
- DemoModeController demoModeController, UserTracker userTracker,
- QSCarrierGroupController.Builder qsCarrierGroupControllerBuilder) {
- mZenModeController = zenModeController;
- mNextAlarmController = nextAlarmController;
- mPrivacyItemController = privacyItemController;
- mRingerModeTracker = ringerModeTracker;
- mActivityStarter = activityStarter;
- mUiEventLogger = uiEventLogger;
- mQsTileHost = qsTileHost;
- mStatusBarIconController = statusBarIconController;
- mCommandQueue = commandQueue;
- mDemoModeController = demoModeController;
- mUserTracker = userTracker;
- mQSCarrierGroupControllerBuilder = qsCarrierGroupControllerBuilder;
- }
-
- public Builder setQuickStatusBarHeader(QuickStatusBarHeader view) {
- mView = view;
- return this;
- }
-
-
- QuickStatusBarHeaderController build() {
- return new QuickStatusBarHeaderController(mView, mZenModeController,
- mNextAlarmController, mPrivacyItemController, mRingerModeTracker,
- mActivityStarter, mUiEventLogger, mQsTileHost, mStatusBarIconController,
- mCommandQueue, mDemoModeController, mUserTracker,
- mQSCarrierGroupControllerBuilder);
- }
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java
index 694492a33524..4ab7afd46602 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java
@@ -11,7 +11,7 @@ import android.view.ViewGroup;
import com.android.systemui.R;
import com.android.systemui.qs.QSPanel.QSTileLayout;
-import com.android.systemui.qs.QSPanel.TileRecord;
+import com.android.systemui.qs.QSPanelControllerBase.TileRecord;
import java.util.ArrayList;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
index 55b67e061c13..8097958fac39 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
@@ -74,9 +74,9 @@ public class QSCustomizer extends LinearLayout implements OnMenuItemClickListene
private final ScreenLifecycle mScreenLifecycle;
private final TileQueryHelper mTileQueryHelper;
private final View mTransparentView;
+ private final QSTileHost mHost;
private boolean isShown;
- private QSTileHost mHost;
private RecyclerView mRecyclerView;
private TileAdapter mTileAdapter;
private Toolbar mToolbar;
@@ -95,6 +95,7 @@ public class QSCustomizer extends LinearLayout implements OnMenuItemClickListene
KeyguardStateController keyguardStateController,
ScreenLifecycle screenLifecycle,
TileQueryHelper tileQueryHelper,
+ QSTileHost qsTileHost,
UiEventLogger uiEventLogger) {
super(new ContextThemeWrapper(context, R.style.edit_theme), attrs);
@@ -139,6 +140,8 @@ public class QSCustomizer extends LinearLayout implements OnMenuItemClickListene
mLightBarController = lightBarController;
mKeyguardStateController = keyguardStateController;
mScreenLifecycle = screenLifecycle;
+ mHost = qsTileHost;
+ mTileAdapter.setHost(mHost);
updateNavBackDrop(getResources().getConfiguration());
}
@@ -170,11 +173,6 @@ public class QSCustomizer extends LinearLayout implements OnMenuItemClickListene
mLightBarController.setQsCustomizing(mIsShowingNavBackdrop && isShown);
}
- public void setHost(QSTileHost host) {
- mHost = host;
- mTileAdapter.setHost(host);
- }
-
public void setContainer(NotificationsQuickSettingsContainer notificationsQsContainer) {
mNotifQsContainer = notificationsQsContainer;
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSFragmentComponent.java b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSFragmentComponent.java
new file mode 100644
index 000000000000..7ba3563f3b20
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSFragmentComponent.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs.dagger;
+
+import com.android.systemui.qs.QSAnimator;
+import com.android.systemui.qs.QSContainerImplController;
+import com.android.systemui.qs.QSFragment;
+import com.android.systemui.qs.QSPanelController;
+import com.android.systemui.qs.QuickQSPanelController;
+
+import dagger.BindsInstance;
+import dagger.Subcomponent;
+
+/**
+ * Dagger Subcomponent for {@link QSFragment}.
+ */
+@Subcomponent(modules = {QSFragmentModule.class})
+@QSScope
+public interface QSFragmentComponent {
+ /** Factory for building a {@link QSFragmentComponent}. */
+ @Subcomponent.Factory
+ interface Factory {
+ QSFragmentComponent create(@BindsInstance QSFragment qsFragment);
+ }
+
+ /** Construct a {@link QSPanelController}. */
+ QSPanelController getQSPanelController();
+
+ /** Construct a {@link QuickQSPanelController}. */
+ QuickQSPanelController getQuickQSPanelController();
+
+ /** Construct a {@link QSAnimator}. */
+ QSAnimator getQSAnimator();
+
+ /** Construct a {@link QSContainerImplController}. */
+ QSContainerImplController getQSContainerImplController();
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSFragmentModule.java b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSFragmentModule.java
new file mode 100644
index 000000000000..ee3f2f60fccc
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSFragmentModule.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs.dagger;
+
+import android.view.View;
+
+import com.android.systemui.R;
+import com.android.systemui.dagger.qualifiers.RootView;
+import com.android.systemui.plugins.qs.QS;
+import com.android.systemui.qs.QSContainerImpl;
+import com.android.systemui.qs.QSFragment;
+import com.android.systemui.qs.QSPanel;
+import com.android.systemui.qs.QuickQSPanel;
+import com.android.systemui.qs.QuickStatusBarHeader;
+
+import dagger.Binds;
+import dagger.Module;
+import dagger.Provides;
+
+/**
+ * Dagger Module for {@link QSFragmentComponent}.
+ */
+@Module
+public interface QSFragmentModule {
+ /** */
+ @Provides
+ @RootView
+ static View provideRootView(QSFragment qsFragment) {
+ return qsFragment.getView();
+ }
+
+ /** */
+ @Provides
+ static QSPanel provideQSPanel(@RootView View view) {
+ return view.findViewById(R.id.quick_settings_panel);
+ }
+
+ /** */
+ @Provides
+ static QSContainerImpl providesQSContainerImpl(@RootView View view) {
+ return view.findViewById(R.id.quick_settings_container);
+ }
+
+ /** */
+ @Binds
+ QS bindQS(QSFragment qsFragment);
+
+ /** */
+ @Provides
+ static QuickStatusBarHeader providesQuickStatusBarHeader(@RootView View view) {
+ return view.findViewById(R.id.header);
+ }
+
+ /** */
+ @Provides
+ static QuickQSPanel providesQuickQSPanel(QuickStatusBarHeader quickStatusBarHeader) {
+ return quickStatusBarHeader.findViewById(R.id.quick_qs_panel);
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModule.java b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModule.java
index 953de6086ac7..7c799aefe90d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModule.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModule.java
@@ -38,8 +38,8 @@ import dagger.Provides;
/**
* Module for QS dependencies
*/
-// TODO: Add other QS classes
-@Module(includes = {MediaModule.class})
+@Module(subcomponents = {QSFragmentComponent.class},
+ includes = {MediaModule.class})
public interface QSModule {
@Provides
@@ -60,7 +60,6 @@ public interface QSModule {
return manager;
}
-
/** */
@Binds
QSHost provideQsHost(QSTileHost controllerImpl);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSScope.java b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSScope.java
new file mode 100644
index 000000000000..f615eabb67dc
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSScope.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs.dagger;
+
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+
+import javax.inject.Scope;
+
+/**
+ * Scope annotation for singleton items within the {@link QSFragmentComponent}.
+ */
+@Documented
+@Retention(RUNTIME)
+@Scope
+public @interface QSScope {}
diff --git a/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java b/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java
index 1bea72aea2ba..72034f84fd30 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java
@@ -50,6 +50,8 @@ import com.android.systemui.broadcast.BroadcastDispatcher;
import java.util.ArrayList;
+import javax.inject.Inject;
+
public class BrightnessController implements ToggleSlider.Listener {
private static final String TAG = "StatusBar.BrightnessController";
private static final int SLIDER_ANIMATION_DURATION = 3000;
@@ -475,4 +477,20 @@ public class BrightnessController implements ToggleSlider.Listener {
mSliderAnimator.start();
}
+ /** Factory for creating a {@link BrightnessController}. */
+ public static class Factory {
+ private final Context mContext;
+ private final BroadcastDispatcher mBroadcastDispatcher;
+
+ @Inject
+ public Factory(Context context, BroadcastDispatcher broadcastDispatcher) {
+ mContext = context;
+ mBroadcastDispatcher = broadcastDispatcher;
+ }
+
+ /** Create a {@link BrightnessController} */
+ public BrightnessController create(ToggleSlider toggleSlider) {
+ return new BrightnessController(mContext, toggleSlider, mBroadcastDispatcher);
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
index af6ac223ada1..2767b7e1627d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
@@ -38,9 +38,9 @@ import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.keyguard.ViewMediatorCallback;
import com.android.keyguard.dagger.KeyguardBouncerComponent;
-import com.android.keyguard.dagger.RootView;
import com.android.systemui.DejankUtils;
import com.android.systemui.biometrics.AuthController;
+import com.android.systemui.dagger.qualifiers.RootView;
import com.android.systemui.keyguard.DismissCallbackRegistry;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.shared.system.SysUiStatsLog;
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 f55c93580210..c7932bb44cf4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -172,7 +172,7 @@ import com.android.systemui.plugins.qs.QS;
import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper.SnoozeOption;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.qs.QSFragment;
-import com.android.systemui.qs.QSPanel;
+import com.android.systemui.qs.QSPanelController;
import com.android.systemui.recents.ScreenPinningRequest;
import com.android.systemui.shared.plugins.PluginManager;
import com.android.systemui.shared.system.WindowManagerWrapper;
@@ -408,7 +408,7 @@ public class StatusBar extends SystemUI implements DemoMode,
protected NotificationPanelViewController mNotificationPanelViewController;
// settings
- private QSPanel mQSPanel;
+ private QSPanelController mQSPanelController;
KeyguardIndicationController mKeyguardIndicationController;
@@ -1200,8 +1200,8 @@ public class StatusBar extends SystemUI implements DemoMode,
fragmentHostManager.addTagListener(QS.TAG, (tag, f) -> {
QS qs = (QS) f;
if (qs instanceof QSFragment) {
- mQSPanel = ((QSFragment) qs).getQsPanel();
- mQSPanel.setBrightnessMirror(mBrightnessMirrorController);
+ mQSPanelController = ((QSFragment) qs).getQSPanelController();
+ mQSPanelController.setBrightnessMirror(mBrightnessMirrorController);
}
});
}
@@ -1593,19 +1593,19 @@ public class StatusBar extends SystemUI implements DemoMode,
}
public void addQsTile(ComponentName tile) {
- if (mQSPanel != null && mQSPanel.getHost() != null) {
- mQSPanel.getHost().addTile(tile);
+ if (mQSPanelController != null && mQSPanelController.getHost() != null) {
+ mQSPanelController.getHost().addTile(tile);
}
}
public void remQsTile(ComponentName tile) {
- if (mQSPanel != null && mQSPanel.getHost() != null) {
- mQSPanel.getHost().removeTile(tile);
+ if (mQSPanelController != null && mQSPanelController.getHost() != null) {
+ mQSPanelController.getHost().removeTile(tile);
}
}
public void clickTile(ComponentName tile) {
- mQSPanel.clickTile(tile);
+ mQSPanelController.clickTile(tile);
}
/**
@@ -2197,7 +2197,7 @@ public class StatusBar extends SystemUI implements DemoMode,
if (!mUserSetup) return;
if (subPanel != null) {
- mQSPanel.openDetails(subPanel);
+ mQSPanelController.openDetails(subPanel);
}
mNotificationPanelViewController.expandWithQs();
@@ -2845,7 +2845,7 @@ public class StatusBar extends SystemUI implements DemoMode,
resetUserExpandedStates();
}
else if (DevicePolicyManager.ACTION_SHOW_DEVICE_MONITORING_DIALOG.equals(action)) {
- mQSPanel.showDeviceMonitoringDialog();
+ mQSPanelController.showDeviceMonitoringDialog();
}
Trace.endSection();
}
@@ -2936,8 +2936,8 @@ public class StatusBar extends SystemUI implements DemoMode,
*/
void updateResources() {
// Update the quick setting tiles
- if (mQSPanel != null) {
- mQSPanel.updateResources();
+ if (mQSPanelController != null) {
+ mQSPanelController.updateResources();
}
if (mStatusBarWindowController != null) {
@@ -3402,8 +3402,8 @@ public class StatusBar extends SystemUI implements DemoMode,
// Keyguard state has changed, but QS is not listening anymore. Make sure to update the tile
// visibilities so next time we open the panel we know the correct height already.
- if (mQSPanel != null) {
- mQSPanel.refreshAllTiles();
+ if (mQSPanelController != null) {
+ mQSPanelController.refreshAllTiles();
}
mHandler.removeMessages(MSG_LAUNCH_TRANSITION_TIMEOUT);
releaseGestureWakeLock();
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 e472cb22ed6b..90609ccb48d6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
@@ -16,7 +16,9 @@ package com.android.systemui.qs;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
import android.app.Fragment;
import android.content.Context;
@@ -42,6 +44,7 @@ import com.android.systemui.SysuiBaseFragmentTest;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.qs.dagger.QSFragmentComponent;
import com.android.systemui.qs.logging.QSLogger;
import com.android.systemui.qs.tileimpl.QSFactoryImpl;
import com.android.systemui.settings.UserTracker;
@@ -61,6 +64,8 @@ import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
import java.util.Optional;
@@ -71,6 +76,12 @@ import java.util.Optional;
public class QSFragmentTest extends SysuiBaseFragmentTest {
private MetricsLogger mMockMetricsLogger;
+ @Mock
+ private QSFragmentComponent.Factory mQsComponentFactory;
+ @Mock
+ private QSFragmentComponent mQsFragmentComponent;
+ @Mock
+ private QSPanelController mQSPanelController;
public QSFragmentTest() {
super(QSFragment.class);
@@ -80,6 +91,10 @@ public class QSFragmentTest extends SysuiBaseFragmentTest {
@Before
@Ignore("failing")
public void addLeakCheckDependencies() {
+ MockitoAnnotations.initMocks(this);
+ when(mQsComponentFactory.create(any(QSFragment.class))).thenReturn(mQsFragmentComponent);
+ when(mQsFragmentComponent.getQSPanelController()).thenReturn(mQSPanelController);
+
mMockMetricsLogger = mDependency.injectMockDependency(MetricsLogger.class);
mContext.addMockSystemService(Context.LAYOUT_INFLATER_SERVICE,
new LayoutInflaterBuilder(mContext)
@@ -152,6 +167,6 @@ public class QSFragmentTest extends SysuiBaseFragmentTest {
mock(QSTileHost.class),
mock(StatusBarStateController.class),
commandQueue,
- mock(QSContainerImplController.Builder.class));
+ mQsComponentFactory);
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerBaseTest.java
new file mode 100644
index 000000000000..bf0e0841de9a
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerBaseTest.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper.RunWithLooper;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.UiEventLogger;
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.internal.logging.testing.UiEventLoggerFake;
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.dump.DumpManager;
+import com.android.systemui.media.MediaHost;
+import com.android.systemui.plugins.qs.QSTileView;
+import com.android.systemui.qs.tileimpl.QSTileImpl;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.Collections;
+
+@RunWith(AndroidTestingRunner.class)
+@RunWithLooper
+@SmallTest
+public class QSPanelControllerBaseTest extends SysuiTestCase {
+
+ @Mock
+ private QSPanel mQSPanel;
+ @Mock
+ private QSTileHost mQSTileHost;
+ @Mock
+ private MediaHost mMediaHost;
+ @Mock
+ private MetricsLogger mMetricsLogger;
+ private UiEventLoggerFake mUiEventLogger = new UiEventLoggerFake();
+ private DumpManager mDumpManager = new DumpManager();
+ @Mock
+ QSTileImpl mQSTile;
+ @Mock
+ QSTileView mQSTileView;
+
+ private QSPanelControllerBase<QSPanel> mController;
+
+ /** Implementation needed to ensure we have a reflectively-available class name. */
+ private static class TestableQSPanelControllerBase extends QSPanelControllerBase<QSPanel> {
+ protected TestableQSPanelControllerBase(QSPanel view, QSTileHost host,
+ MetricsLogger metricsLogger,
+ UiEventLogger uiEventLogger, DumpManager dumpManager) {
+ super(view, host, metricsLogger, uiEventLogger, dumpManager);
+ }
+ }
+
+ @Before
+ public void setup() throws Exception {
+ MockitoAnnotations.initMocks(this);
+
+ when(mQSPanel.getMediaHost()).thenReturn(mMediaHost);
+ when(mQSPanel.isAttachedToWindow()).thenReturn(true);
+ when(mQSPanel.getDumpableTag()).thenReturn("QSPanel");
+ when(mQSPanel.openPanelEvent()).thenReturn(QSEvent.QS_PANEL_EXPANDED);
+ when(mQSPanel.closePanelEvent()).thenReturn(QSEvent.QS_PANEL_COLLAPSED);
+ when(mQSTileHost.getTiles()).thenReturn(Collections.singleton(mQSTile));
+ when(mQSTileHost.createTileView(eq(mQSTile), anyBoolean())).thenReturn(mQSTileView);
+
+ mController = new TestableQSPanelControllerBase(mQSPanel, mQSTileHost,
+ mMetricsLogger, mUiEventLogger, mDumpManager);
+
+ mController.init();
+ }
+
+ @Test
+ public void testSetExpanded_Metrics() {
+ mController.setExpanded(true);
+ verify(mMetricsLogger).visibility(eq(MetricsEvent.QS_PANEL), eq(true));
+ assertEquals(1, mUiEventLogger.numLogs());
+ assertEquals(QSEvent.QS_PANEL_EXPANDED.getId(), mUiEventLogger.eventId(0));
+ mUiEventLogger.getLogs().clear();
+
+ mController.setExpanded(false);
+ verify(mMetricsLogger).visibility(eq(MetricsEvent.QS_PANEL), eq(false));
+ assertEquals(1, mUiEventLogger.numLogs());
+ assertEquals(QSEvent.QS_PANEL_COLLAPSED.getId(), mUiEventLogger.eventId(0));
+ mUiEventLogger.getLogs().clear();
+
+ }
+
+ @Test
+ public void testDump() {
+ String mockTileViewString = "Mock Tile View";
+ String mockTileString = "Mock Tile";
+ doAnswer(invocation -> {
+ PrintWriter pw = invocation.getArgument(1);
+ pw.println(mockTileString);
+ return null;
+ }).when(mQSTile).dump(any(FileDescriptor.class), any(PrintWriter.class),
+ any(String[].class));
+ when(mQSTileView.toString()).thenReturn(mockTileViewString);
+
+ StringWriter w = new StringWriter();
+ PrintWriter pw = new PrintWriter(w);
+ mController.dump(mock(FileDescriptor.class), pw, new String[]{});
+ String expected = "TestableQSPanelControllerBase:\n"
+ + " Tile records:\n"
+ + " " + mockTileString + "\n"
+ + " " + mockTileViewString + "\n";
+ assertEquals(expected, w.getBuffer().toString());
+ }
+
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.java
new file mode 100644
index 000000000000..0ba0214d2173
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper.RunWithLooper;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.UiEventLogger;
+import com.android.internal.logging.testing.UiEventLoggerFake;
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.dump.DumpManager;
+import com.android.systemui.media.MediaHost;
+import com.android.systemui.plugins.qs.QSTileView;
+import com.android.systemui.qs.tileimpl.QSTileImpl;
+import com.android.systemui.settings.BrightnessController;
+import com.android.systemui.settings.ToggleSlider;
+import com.android.systemui.tuner.TunerService;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.Collections;
+
+@RunWith(AndroidTestingRunner.class)
+@RunWithLooper
+@SmallTest
+public class QSPanelControllerTest extends SysuiTestCase {
+
+ @Mock
+ private QSPanel mQSPanel;
+ @Mock
+ private QSTileHost mQSTileHost;
+ @Mock
+ private MediaHost mMediaHost;
+ @Mock
+ private MetricsLogger mMetricsLogger;
+ private UiEventLogger mUiEventLogger = new UiEventLoggerFake();
+ private DumpManager mDumpManager = new DumpManager();
+ @Mock
+ private TunerService mTunerService;
+ @Mock
+ private QSSecurityFooter mQSSecurityFooter;
+ @Mock
+ private BrightnessController.Factory mBrightnessControllerFactory;
+ @Mock
+ private BrightnessController mBrightnessController;
+ @Mock
+ QSTileImpl mQSTile;
+ @Mock
+ QSTileView mQSTileView;
+
+ private QSPanelController mController;
+
+ @Before
+ public void setup() throws Exception {
+ MockitoAnnotations.initMocks(this);
+
+ when(mQSPanel.getMediaHost()).thenReturn(mMediaHost);
+ when(mQSPanel.isAttachedToWindow()).thenReturn(true);
+ when(mQSPanel.getDumpableTag()).thenReturn("QSPanel");
+ when(mQSTileHost.getTiles()).thenReturn(Collections.singleton(mQSTile));
+ when(mQSTileHost.createTileView(eq(mQSTile), anyBoolean())).thenReturn(mQSTileView);
+ when(mBrightnessControllerFactory.create(any(ToggleSlider.class)))
+ .thenReturn(mBrightnessController);
+
+ mController = new QSPanelController(mQSPanel, mQSSecurityFooter, mTunerService,
+ mQSTileHost, mDumpManager, mMetricsLogger, mUiEventLogger,
+ mBrightnessControllerFactory);
+
+ mController.init();
+ }
+
+ @Test
+ public void testOpenDetailsWithNonExistingTile_NoException() {
+ mController.openDetails("none");
+
+ verify(mQSPanel, never()).openDetails(any());
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java
index 4b7a26870308..e38d54b90f69 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java
@@ -14,12 +14,9 @@
package com.android.systemui.qs;
-import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
@@ -36,19 +33,15 @@ import android.widget.FrameLayout;
import androidx.test.filters.SmallTest;
import com.android.internal.logging.MetricsLogger;
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.logging.testing.UiEventLoggerFake;
import com.android.systemui.Dependency;
import com.android.systemui.SysuiTestCase;
-import com.android.systemui.broadcast.BroadcastDispatcher;
-import com.android.systemui.dump.DumpManager;
import com.android.systemui.media.MediaHost;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.qs.QSTileView;
import com.android.systemui.qs.customize.QSCustomizer;
import com.android.systemui.qs.logging.QSLogger;
import com.android.systemui.qs.tileimpl.QSTileImpl;
-import com.android.systemui.settings.UserTracker;
import com.android.systemui.statusbar.policy.SecurityController;
import com.android.systemui.util.animation.DisappearParameters;
import com.android.systemui.util.animation.UniqueObjectHostView;
@@ -59,9 +52,6 @@ import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.io.StringWriter;
import java.util.Collections;
@RunWith(AndroidTestingRunner.class)
@@ -79,9 +69,9 @@ public class QSPanelTest extends SysuiTestCase {
@Mock
private QSTileImpl dndTile;
@Mock
- private BroadcastDispatcher mBroadcastDispatcher;
+ private QSTileImpl mNonTile;
@Mock
- private DumpManager mDumpManager;
+ private QSPanelControllerBase.TileRecord mDndTileRecord;
@Mock
private QSLogger mQSLogger;
private ViewGroup mParentView;
@@ -93,9 +83,8 @@ public class QSPanelTest extends SysuiTestCase {
private MediaHost mMediaHost;
@Mock
private ActivityStarter mActivityStarter;
- @Mock(stubOnly = true)
- private UserTracker mUserTracker;
private UiEventLoggerFake mUiEventLogger;
+ private String mCachedSpecs = "";
@Before
public void setup() throws Exception {
@@ -109,12 +98,13 @@ public class QSPanelTest extends SysuiTestCase {
mContext.addMockSystemService(Context.USER_SERVICE, mock(UserManager.class));
when(mMediaHost.getHostView()).thenReturn(new UniqueObjectHostView(getContext()));
when(mMediaHost.getDisappearParameters()).thenReturn(new DisappearParameters());
+ mDndTileRecord.tile = dndTile;
+ mDndTileRecord.tileView = mQSTileView;
mUiEventLogger = new UiEventLoggerFake();
mTestableLooper.runWithLooper(() -> {
mMetricsLogger = mDependency.injectMockDependency(MetricsLogger.class);
- mQsPanel = new QSPanel(mContext, null, mDumpManager, mBroadcastDispatcher,
- mQSLogger, mMediaHost, mUiEventLogger, mUserTracker);
+ mQsPanel = new QSPanel(mContext, null, mQSLogger, mMediaHost, mUiEventLogger);
mQsPanel.onFinishInflate();
// Provides a parent with non-zero size for QSPanel
mParentView = new FrameLayout(mContext);
@@ -124,8 +114,8 @@ public class QSPanelTest extends SysuiTestCase {
when(mHost.getTiles()).thenReturn(Collections.emptyList());
when(mHost.createTileView(any(), anyBoolean())).thenReturn(mQSTileView);
- mQsPanel.setHost(mHost, mCustomizer);
- mQsPanel.addTile(dndTile, true);
+ mQsPanel.setCustomizer(mCustomizer);
+ mQsPanel.addTile(mDndTileRecord);
mQsPanel.setCallback(mCallback);
});
}
@@ -133,25 +123,16 @@ public class QSPanelTest extends SysuiTestCase {
@Test
public void testSetExpanded_Metrics() {
mQsPanel.setExpanded(true);
- verify(mMetricsLogger).visibility(eq(MetricsEvent.QS_PANEL), eq(true));
verify(mQSLogger).logPanelExpanded(true, mQsPanel.getDumpableTag());
- assertEquals(1, mUiEventLogger.numLogs());
- assertEquals(QSEvent.QS_PANEL_EXPANDED.getId(), mUiEventLogger.eventId(0));
- mUiEventLogger.getLogs().clear();
mQsPanel.setExpanded(false);
- verify(mMetricsLogger).visibility(eq(MetricsEvent.QS_PANEL), eq(false));
verify(mQSLogger).logPanelExpanded(false, mQsPanel.getDumpableTag());
- assertEquals(1, mUiEventLogger.numLogs());
- assertEquals(QSEvent.QS_PANEL_COLLAPSED.getId(), mUiEventLogger.eventId(0));
- mUiEventLogger.getLogs().clear();
-
}
@Test
public void testOpenDetailsWithExistingTile_NoException() {
mTestableLooper.processAllMessages();
- mQsPanel.openDetails("dnd");
+ mQsPanel.openDetails(dndTile);
mTestableLooper.processAllMessages();
verify(mCallback).onShowingDetail(any(), anyInt(), anyInt());
@@ -159,53 +140,19 @@ public class QSPanelTest extends SysuiTestCase {
@Test
public void setListening() {
- when(dndTile.getTileSpec()).thenReturn("dnd");
-
- mQsPanel.setListening(true);
+ mQsPanel.setListening(true, "dnd");
verify(mQSLogger).logAllTilesChangeListening(true, mQsPanel.getDumpableTag(), "dnd");
- mQsPanel.setListening(false);
+ mQsPanel.setListening(false, "dnd");
verify(mQSLogger).logAllTilesChangeListening(false, mQsPanel.getDumpableTag(), "dnd");
}
-/* @Test
+ @Test
public void testOpenDetailsWithNullParameter_NoException() {
mTestableLooper.processAllMessages();
mQsPanel.openDetails(null);
mTestableLooper.processAllMessages();
verify(mCallback, never()).onShowingDetail(any(), anyInt(), anyInt());
- }*/
-
- @Test
- public void testOpenDetailsWithNonExistingTile_NoException() {
- mTestableLooper.processAllMessages();
- mQsPanel.openDetails("invalid-name");
- mTestableLooper.processAllMessages();
-
- verify(mCallback, never()).onShowingDetail(any(), anyInt(), anyInt());
- }
-
- @Test
- public void testDump() {
- String mockTileViewString = "Mock Tile View";
- String mockTileString = "Mock Tile";
- doAnswer(invocation -> {
- PrintWriter pw = invocation.getArgument(1);
- pw.println(mockTileString);
- return null;
- }).when(dndTile).dump(any(FileDescriptor.class), any(PrintWriter.class),
- any(String[].class));
- when(mQSTileView.toString()).thenReturn(mockTileViewString);
-
- StringWriter w = new StringWriter();
- PrintWriter pw = new PrintWriter(w);
- mQsPanel.dump(mock(FileDescriptor.class), pw, new String[]{});
- String expected = "QSPanel:\n"
- + " Tile records:\n"
- + " " + mockTileString + "\n"
- + " " + mockTileViewString + "\n";
- assertEquals(expected, w.getBuffer().toString());
}
-
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/TileLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/TileLayoutTest.java
index fef47bd6a392..6c7c20a15140 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/TileLayoutTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/TileLayoutTest.java
@@ -57,8 +57,8 @@ public class TileLayoutTest extends SysuiTestCase {
mContext.getResources().getDimensionPixelSize(R.dimen.qs_tile_margin_horizontal) * 3;
}
- private QSPanel.TileRecord createTileRecord() {
- QSPanel.TileRecord tileRecord = new QSPanel.TileRecord();
+ private QSPanelControllerBase.TileRecord createTileRecord() {
+ QSPanelControllerBase.TileRecord tileRecord = new QSPanelControllerBase.TileRecord();
tileRecord.tile = mock(QSTile.class);
tileRecord.tileView = spy(new QSTileView(mContext, new QSIconViewImpl(mContext)));
return tileRecord;
@@ -66,14 +66,14 @@ public class TileLayoutTest extends SysuiTestCase {
@Test
public void testAddTile_CallsSetListeningOnTile() {
- QSPanel.TileRecord tileRecord = createTileRecord();
+ QSPanelControllerBase.TileRecord tileRecord = createTileRecord();
mTileLayout.addTile(tileRecord);
verify(tileRecord.tile, times(1)).setListening(mTileLayout, false);
}
@Test
public void testSetListening_CallsSetListeningOnTile() {
- QSPanel.TileRecord tileRecord = createTileRecord();
+ QSPanelControllerBase.TileRecord tileRecord = createTileRecord();
mTileLayout.addTile(tileRecord);
mTileLayout.setListening(true);
verify(tileRecord.tile, times(1)).setListening(mTileLayout, true);
@@ -81,7 +81,7 @@ public class TileLayoutTest extends SysuiTestCase {
@Test
public void testSetListening_SameValueIsNoOp() {
- QSPanel.TileRecord tileRecord = createTileRecord();
+ QSPanelControllerBase.TileRecord tileRecord = createTileRecord();
mTileLayout.addTile(tileRecord);
mTileLayout.setListening(false);
verify(tileRecord.tile, times(1)).setListening(any(), anyBoolean());
@@ -89,7 +89,7 @@ public class TileLayoutTest extends SysuiTestCase {
@Test
public void testSetListening_ChangesValueForAddingFutureTiles() {
- QSPanel.TileRecord tileRecord = createTileRecord();
+ QSPanelControllerBase.TileRecord tileRecord = createTileRecord();
mTileLayout.setListening(true);
mTileLayout.addTile(tileRecord);
verify(tileRecord.tile, times(1)).setListening(mTileLayout, true);
@@ -97,7 +97,7 @@ public class TileLayoutTest extends SysuiTestCase {
@Test
public void testRemoveTile_CallsSetListeningFalseOnTile() {
- QSPanel.TileRecord tileRecord = createTileRecord();
+ QSPanelControllerBase.TileRecord tileRecord = createTileRecord();
mTileLayout.setListening(true);
mTileLayout.addTile(tileRecord);
mTileLayout.removeTile(tileRecord);
@@ -106,8 +106,8 @@ public class TileLayoutTest extends SysuiTestCase {
@Test
public void testRemoveAllViews_CallsSetListeningFalseOnAllTiles() {
- QSPanel.TileRecord tileRecord1 = createTileRecord();
- QSPanel.TileRecord tileRecord2 = createTileRecord();
+ QSPanelControllerBase.TileRecord tileRecord1 = createTileRecord();
+ QSPanelControllerBase.TileRecord tileRecord2 = createTileRecord();
mTileLayout.setListening(true);
mTileLayout.addTile(tileRecord1);
mTileLayout.addTile(tileRecord2);
@@ -118,7 +118,7 @@ public class TileLayoutTest extends SysuiTestCase {
@Test
public void testMeasureLayout_CallsLayoutOnTile() {
- QSPanel.TileRecord tileRecord = createTileRecord();
+ QSPanelControllerBase.TileRecord tileRecord = createTileRecord();
mTileLayout.addTile(tileRecord);
mTileLayout.measure(mLayoutSizeForOneTile, mLayoutSizeForOneTile);
mTileLayout.layout(0, 0, mLayoutSizeForOneTile, mLayoutSizeForOneTile);
@@ -127,8 +127,8 @@ public class TileLayoutTest extends SysuiTestCase {
@Test
public void testMeasureLayout_CallsLayoutOnTilesWithNeighboredBounds() {
- QSPanel.TileRecord tileRecord1 = createTileRecord();
- QSPanel.TileRecord tileRecord2 = createTileRecord();
+ QSPanelControllerBase.TileRecord tileRecord1 = createTileRecord();
+ QSPanelControllerBase.TileRecord tileRecord2 = createTileRecord();
mTileLayout.addTile(tileRecord1);
mTileLayout.addTile(tileRecord2);
mTileLayout.measure(mLayoutSizeForOneTile * 2, mLayoutSizeForOneTile * 2);