summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/DetailAdapter.java15
-rw-r--r--packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java13
-rw-r--r--packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/DoubleLineTileLayout.kt13
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java21
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSDetail.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSEvents.kt124
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSHost.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSPanel.java20
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java21
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java46
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/TileLayout.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/customize/QSEditEvent.kt38
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java23
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailView.java13
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateEvent.java69
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java23
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingManagerProxyTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/BrightLineFalsingManagerTest.java3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/QSDetailTest.java37
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java13
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/QSTileHostTest.java11
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/customize/TileAdapterTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTest.java6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileImplTest.java25
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/tiles/UserDetailViewAdapterTest.kt18
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarStateControllerImplTest.kt60
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarStateEventTest.kt50
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java3
36 files changed, 650 insertions, 86 deletions
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/DetailAdapter.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/DetailAdapter.java
index f6f8f53c07f2..d43aaf07c6be 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/DetailAdapter.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/DetailAdapter.java
@@ -19,6 +19,7 @@ import android.content.Intent;
import android.view.View;
import android.view.ViewGroup;
+import com.android.internal.logging.UiEventLogger;
import com.android.systemui.plugins.annotations.ProvidesInterface;
@ProvidesInterface(version = DetailAdapter.VERSION)
@@ -44,4 +45,18 @@ public interface DetailAdapter {
default boolean hasHeader() {
return true;
}
+
+ default UiEventLogger.UiEventEnum openDetailEvent() {
+ return INVALID;
+ }
+
+ default UiEventLogger.UiEventEnum closeDetailEvent() {
+ return INVALID;
+ }
+
+ default UiEventLogger.UiEventEnum moreSettingsEvent() {
+ return INVALID;
+ }
+
+ UiEventLogger.UiEventEnum INVALID = () -> 0;
}
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java
index e586c38a286a..aeedc16ffbd4 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java
@@ -20,6 +20,7 @@ import android.graphics.drawable.Drawable;
import android.metrics.LogMaker;
import android.service.quicksettings.Tile;
+import com.android.internal.logging.InstanceId;
import com.android.systemui.plugins.annotations.DependsOn;
import com.android.systemui.plugins.annotations.ProvidesInterface;
import com.android.systemui.plugins.qs.QSTile.Callback;
@@ -81,6 +82,18 @@ public interface QSTile {
return logMaker;
}
+ /**
+ * Return a string to be used to identify the tile in UiEvents.
+ */
+ default String getMetricsSpec() {
+ return getClass().getSimpleName();
+ }
+
+ /**
+ * Return an {@link InstanceId} to be used to identify the tile in UiEvents.
+ */
+ InstanceId getInstanceId();
+
@ProvidesInterface(version = Callback.VERSION)
public interface Callback {
public static final int VERSION = 1;
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java b/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java
index 3a4b273e1c98..23bcb29923d8 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java
@@ -33,6 +33,8 @@ import android.view.LayoutInflater;
import android.view.WindowManager;
import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.UiEventLogger;
+import com.android.internal.logging.UiEventLoggerImpl;
import com.android.internal.util.NotificationMessagingUtil;
import com.android.internal.widget.LockPatternUtils;
import com.android.keyguard.ViewMediatorCallback;
@@ -218,4 +220,11 @@ public class DependencyProvider {
public Choreographer providesChoreographer() {
return Choreographer.getInstance();
}
+
+ /** Provides an instance of {@link com.android.internal.logging.UiEventLogger} */
+ @Singleton
+ @Provides
+ static UiEventLogger provideUiEventLogger() {
+ return new UiEventLoggerImpl();
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/DoubleLineTileLayout.kt b/packages/SystemUI/src/com/android/systemui/qs/DoubleLineTileLayout.kt
index 448531a132df..c5ae3ab2c9fb 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/DoubleLineTileLayout.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/DoubleLineTileLayout.kt
@@ -20,10 +20,14 @@ import android.content.Context
import android.content.res.Configuration
import android.view.View
import android.view.ViewGroup
+import com.android.internal.logging.UiEventLogger
import com.android.systemui.R
import com.android.systemui.qs.TileLayout.exactly
-class DoubleLineTileLayout(context: Context) : ViewGroup(context), QSPanel.QSTileLayout {
+class DoubleLineTileLayout(
+ context: Context,
+ private val uiEventLogger: UiEventLogger
+) : ViewGroup(context), QSPanel.QSTileLayout {
companion object {
private const val NUM_LINES = 2
@@ -86,6 +90,13 @@ class DoubleLineTileLayout(context: Context) : ViewGroup(context), QSPanel.QSTil
for (record in mRecords) {
record.tile.setListening(this, listening)
}
+ if (listening) {
+ for (i in 0 until numVisibleTiles) {
+ val tile = mRecords[i].tile
+ uiEventLogger.logWithInstanceId(
+ QSEvent.QQS_TILE_VISIBLE, 0, tile.metricsSpec, tile.instanceId)
+ }
+ }
}
override fun getNumVisibleTiles() = tilesToShow
diff --git a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
index cd737217b84a..b157f4b3c5ed 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
@@ -22,7 +22,9 @@ import android.widget.Scroller;
import androidx.viewpager.widget.PagerAdapter;
import androidx.viewpager.widget.ViewPager;
+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;
@@ -63,7 +65,7 @@ public class PagedTileLayout extends ViewPager implements QSTileLayout {
private int mLayoutDirection;
private int mHorizontalClipBound;
private final Rect mClippingRect;
- private int mLastMaxHeight = -1;
+ private final UiEventLogger mUiEventLogger = QSEvents.INSTANCE.getQsUiEventsLogger();
public PagedTileLayout(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -75,6 +77,7 @@ public class PagedTileLayout extends ViewPager implements QSTileLayout {
mLayoutDirection = getLayoutDirection();
mClippingRect = new Rect();
}
+ private int mLastMaxHeight = -1;
public void saveInstanceState(Bundle outState) {
outState.putInt(CURRENT_PAGE, getCurrentItem());
@@ -126,6 +129,15 @@ public class PagedTileLayout extends ViewPager implements QSTileLayout {
return page;
}
+ // This will dump to the ui log all the tiles that are visible in this page
+ private void logVisibleTiles(TilePage page) {
+ for (int i = 0; i < page.mRecords.size(); i++) {
+ QSTile t = page.mRecords.get(i).tile;
+ mUiEventLogger.logWithInstanceId(QSEvent.QS_TILE_VISIBLE, 0, t.getMetricsSpec(),
+ t.getInstanceId());
+ }
+ }
+
@Override
public void setListening(boolean listening) {
if (mListening == listening) return;
@@ -218,7 +230,11 @@ public class PagedTileLayout extends ViewPager implements QSTileLayout {
setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS);
int currentItem = getCurrentPageNumber();
for (int i = 0; i < mPages.size(); i++) {
- mPages.get(i).setSelected(i == currentItem ? selected : false);
+ TilePage page = mPages.get(i);
+ page.setSelected(i == currentItem ? selected : false);
+ if (page.isSelected()) {
+ logVisibleTiles(page);
+ }
}
setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_AUTO);
}
@@ -419,6 +435,7 @@ public class PagedTileLayout extends ViewPager implements QSTileLayout {
mPageListener.onPageChanged(isLayoutRtl() ? position == mPages.size() - 1
: position == 0);
}
+
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java b/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java
index 17aaff1f7383..ee3b499edfb7 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java
@@ -39,6 +39,7 @@ import android.widget.Switch;
import android.widget.TextView;
import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.UiEventLogger;
import com.android.systemui.Dependency;
import com.android.systemui.FontSizeUtils;
import com.android.systemui.R;
@@ -53,6 +54,7 @@ public class QSDetail extends LinearLayout {
private static final long FADE_DURATION = 300;
private final SparseArray<View> mDetailViews = new SparseArray<>();
+ private final UiEventLogger mUiEventLogger = QSEvents.INSTANCE.getQsUiEventsLogger();
private ViewGroup mDetailContent;
protected TextView mDetailSettingsButton;
@@ -205,6 +207,7 @@ public class QSDetail extends LinearLayout {
mDetailContent.addView(detailView);
mDetailViews.put(viewCacheIndex, detailView);
Dependency.get(MetricsLogger.class).visible(adapter.getMetricsCategory());
+ mUiEventLogger.log(adapter.openDetailEvent());
announceForAccessibility(mContext.getString(
R.string.accessibility_quick_settings_detail,
adapter.getTitle()));
@@ -214,6 +217,7 @@ public class QSDetail extends LinearLayout {
} else {
if (mDetailAdapter != null) {
Dependency.get(MetricsLogger.class).hidden(mDetailAdapter.getMetricsCategory());
+ mUiEventLogger.log(mDetailAdapter.closeDetailEvent());
}
mClosingDetail = true;
mDetailAdapter = null;
@@ -249,6 +253,7 @@ public class QSDetail extends LinearLayout {
mDetailSettingsButton.setOnClickListener(v -> {
Dependency.get(MetricsLogger.class).action(ACTION_QS_MORE_SETTINGS,
adapter.getMetricsCategory());
+ mUiEventLogger.log(adapter.moreSettingsEvent());
Dependency.get(ActivityStarter.class)
.postStartActivityDismissingKeyguard(settingsIntent, 0);
});
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSEvents.kt b/packages/SystemUI/src/com/android/systemui/qs/QSEvents.kt
new file mode 100644
index 000000000000..54e8a2be0d2a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSEvents.kt
@@ -0,0 +1,124 @@
+/*
+ * 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 com.android.internal.logging.UiEvent
+import com.android.internal.logging.UiEventLogger
+import com.android.internal.logging.UiEventLoggerImpl
+import com.android.internal.logging.testing.UiEventLoggerFake
+
+object QSEvents {
+
+ var qsUiEventsLogger: UiEventLogger = UiEventLoggerImpl()
+ private set
+
+ fun setLoggerForTesting(): UiEventLoggerFake {
+ return UiEventLoggerFake().also {
+ qsUiEventsLogger = it
+ }
+ }
+
+ fun resetLogger() {
+ qsUiEventsLogger = UiEventLoggerImpl()
+ }
+}
+
+enum class QSEvent(private val _id: Int) : UiEventLogger.UiEventEnum {
+ @UiEvent(doc = "Tile clicked. It has an instance id and a spec (or packageName)")
+ QS_ACTION_CLICK(387),
+
+ @UiEvent(doc = "Tile secondary button clicked. " +
+ "It has an instance id and a spec (or packageName)")
+ QS_ACTION_SECONDARY_CLICK(388),
+
+ @UiEvent(doc = "Tile long clicked. It has an instance id and a spec (or packageName)")
+ QS_ACTION_LONG_PRESS(389),
+
+ @UiEvent(doc = "Quick Settings panel expanded")
+ QS_PANEL_EXPANDED(390),
+
+ @UiEvent(doc = "Quick Settings panel collapsed")
+ QS_PANEL_COLLAPSED(391),
+
+ @UiEvent(doc = "Tile visible in Quick Settings panel. The tile may be in a different page. " +
+ "It has an instance id and a spec (or packageName)")
+ QS_TILE_VISIBLE(392),
+
+ @UiEvent(doc = "Quick Quick Settings panel expanded")
+ QQS_PANEL_EXPANDED(393),
+
+ @UiEvent(doc = "Quick Quick Settings panel collapsed")
+ QQS_PANEL_COLLAPSED(394),
+
+ @UiEvent(doc = "Tile visible in Quick Quick Settings panel. " +
+ "It has an instance id and a spec (or packageName)")
+ QQS_TILE_VISIBLE(395);
+
+ override fun getId() = _id
+}
+
+enum class QSEditEvent(private val _id: Int) : UiEventLogger.UiEventEnum {
+
+ @UiEvent(doc = "Tile removed from current tiles")
+ QS_EDIT_REMOVE(210),
+
+ @UiEvent(doc = "Tile added to current tiles")
+ QS_EDIT_ADD(211),
+
+ @UiEvent(doc = "Tile moved")
+ QS_EDIT_MOVE(212),
+
+ @UiEvent(doc = "QS customizer open")
+ QS_EDIT_OPEN(213),
+
+ @UiEvent(doc = "QS customizer closed")
+ QS_EDIT_CLOSED(214),
+
+ @UiEvent(doc = "QS tiles reset")
+ QS_EDIT_RESET(215);
+
+ override fun getId() = _id
+}
+
+enum class QSDndEvent(private val _id: Int) : UiEventLogger.UiEventEnum {
+ @UiEvent(doc = "TODO(beverlyt)")
+ QS_DND_CONDITION_SELECT(420),
+
+ @UiEvent(doc = "TODO(beverlyt)")
+ QS_DND_TIME_UP(422),
+
+ @UiEvent(doc = "TODO(beverlyt)")
+ QS_DND_TIME_DOWN(423);
+
+ override fun getId() = _id
+}
+
+enum class QSUserSwitcherEvent(private val _id: Int) : UiEventLogger.UiEventEnum {
+ @UiEvent(doc = "The current user has been switched in the detail panel")
+ QS_USER_SWITCH(424),
+
+ @UiEvent(doc = "User switcher QS detail panel open")
+ QS_USER_DETAIL_OPEN(425),
+
+ @UiEvent(doc = "User switcher QS detail panel closed")
+ QS_USER_DETAIL_CLOSE(426),
+
+ @UiEvent(doc = "User switcher QS detail panel more settings pressed")
+ QS_USER_MORE_SETTINGS(427);
+
+ override fun getId() = _id
+} \ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSHost.java b/packages/SystemUI/src/com/android/systemui/qs/QSHost.java
index ece1ce8bb4d0..1e8c4d86da36 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSHost.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSHost.java
@@ -16,6 +16,8 @@ package com.android.systemui.qs;
import android.content.Context;
+import com.android.internal.logging.InstanceId;
+import com.android.internal.logging.UiEventLogger;
import com.android.systemui.plugins.qs.QSTile;
import com.android.systemui.qs.external.TileServices;
import com.android.systemui.qs.logging.QSLogger;
@@ -30,6 +32,7 @@ public interface QSHost {
Context getContext();
Context getUserContext();
QSLogger getQSLogger();
+ UiEventLogger getUiEventLogger();
Collection<QSTile> getTiles();
void addCallback(Callback callback);
void removeCallback(Callback callback);
@@ -39,6 +42,8 @@ public interface QSHost {
int indexOf(String tileSpec);
+ InstanceId getNewInstanceId();
+
interface Callback {
void onTilesChanged();
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index 121e2aa94954..a3004bdc004d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -52,6 +52,7 @@ import android.widget.HorizontalScrollView;
import android.widget.LinearLayout;
import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.UiEventLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.statusbar.NotificationVisibility;
import com.android.settingslib.Utils;
@@ -129,6 +130,7 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
private BrightnessController mBrightnessController;
private final DumpManager mDumpManager;
private final QSLogger mQSLogger;
+ protected final UiEventLogger mUiEventLogger;
protected QSTileHost mHost;
protected QSSecurityFooter mFooter;
@@ -176,7 +178,8 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
@Background DelayableExecutor backgroundExecutor,
@Nullable LocalBluetoothManager localBluetoothManager,
ActivityStarter activityStarter,
- NotificationEntryManager entryManager
+ NotificationEntryManager entryManager,
+ UiEventLogger uiEventLogger
) {
super(context, attrs);
mContext = context;
@@ -188,6 +191,7 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
mBroadcastDispatcher = broadcastDispatcher;
mActivityStarter = activityStarter;
mNotificationEntryManager = entryManager;
+ mUiEventLogger = uiEventLogger;
setOrientation(VERTICAL);
@@ -678,8 +682,10 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
}
mMetricsLogger.visibility(MetricsEvent.QS_PANEL, mExpanded);
if (!mExpanded) {
+ mUiEventLogger.log(closePanelEvent());
closeDetail();
} else {
+ mUiEventLogger.log(openPanelEvent());
logTiles();
}
}
@@ -786,6 +792,18 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
return mHost.createTileView(tile, collapsedView);
}
+ protected QSEvent openPanelEvent() {
+ return QSEvent.QS_PANEL_EXPANDED;
+ }
+
+ protected QSEvent closePanelEvent() {
+ return QSEvent.QS_PANEL_COLLAPSED;
+ }
+
+ protected QSEvent tileVisibleEvent() {
+ return QSEvent.QS_TILE_VISIBLE;
+ }
+
protected boolean shouldShowDetail() {
return mExpanded;
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java b/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
index 9e8eb3a28781..8835e5db50c0 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
@@ -31,6 +31,9 @@ import android.text.TextUtils;
import android.util.ArraySet;
import android.util.Log;
+import com.android.internal.logging.InstanceId;
+import com.android.internal.logging.InstanceIdSequence;
+import com.android.internal.logging.UiEventLogger;
import com.android.systemui.Dumpable;
import com.android.systemui.R;
import com.android.systemui.broadcast.BroadcastDispatcher;
@@ -73,6 +76,7 @@ import javax.inject.Singleton;
public class QSTileHost implements QSHost, Tunable, PluginListener<QSFactory>, Dumpable {
private static final String TAG = "QSTileHost";
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+ private static final int MAX_QS_INSTANCE_ID = 1 << 20;
public static final String TILES_SETTING = Secure.QS_TILES;
@@ -85,6 +89,8 @@ public class QSTileHost implements QSHost, Tunable, PluginListener<QSFactory>, D
private final DumpManager mDumpManager;
private final BroadcastDispatcher mBroadcastDispatcher;
private final QSLogger mQSLogger;
+ private final UiEventLogger mUiEventLogger;
+ private final InstanceIdSequence mInstanceIdSequence;
private final List<Callback> mCallbacks = new ArrayList<>();
private AutoTileManager mAutoTiles;
@@ -106,7 +112,8 @@ public class QSTileHost implements QSHost, Tunable, PluginListener<QSFactory>, D
DumpManager dumpManager,
BroadcastDispatcher broadcastDispatcher,
Optional<StatusBar> statusBarOptional,
- QSLogger qsLogger) {
+ QSLogger qsLogger,
+ UiEventLogger uiEventLogger) {
mIconController = iconController;
mContext = context;
mUserContext = context;
@@ -114,8 +121,10 @@ public class QSTileHost implements QSHost, Tunable, PluginListener<QSFactory>, D
mPluginManager = pluginManager;
mDumpManager = dumpManager;
mQSLogger = qsLogger;
+ mUiEventLogger = uiEventLogger;
mBroadcastDispatcher = broadcastDispatcher;
+ mInstanceIdSequence = new InstanceIdSequence(MAX_QS_INSTANCE_ID);
mServices = new TileServices(this, bgLooper, mBroadcastDispatcher);
mStatusBarOptional = statusBarOptional;
@@ -137,6 +146,11 @@ public class QSTileHost implements QSHost, Tunable, PluginListener<QSFactory>, D
return mIconController;
}
+ @Override
+ public InstanceId getNewInstanceId() {
+ return mInstanceIdSequence.newInstanceId();
+ }
+
public void destroy() {
mTiles.values().forEach(tile -> tile.destroy());
mAutoTiles.destroy();
@@ -170,6 +184,11 @@ public class QSTileHost implements QSHost, Tunable, PluginListener<QSFactory>, D
}
@Override
+ public UiEventLogger getUiEventLogger() {
+ return mUiEventLogger;
+ }
+
+ @Override
public void addCallback(Callback callback) {
mCallbacks.add(callback);
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
index 38dea657242d..6683a1ce4f4f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
@@ -27,6 +27,7 @@ import android.view.Gravity;
import android.view.View;
import android.widget.LinearLayout;
+import com.android.internal.logging.UiEventLogger;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.systemui.Dependency;
import com.android.systemui.R;
@@ -88,11 +89,12 @@ public class QuickQSPanel extends QSPanel {
@Background DelayableExecutor backgroundExecutor,
@Nullable LocalBluetoothManager localBluetoothManager,
ActivityStarter activityStarter,
- NotificationEntryManager entryManager
+ NotificationEntryManager entryManager,
+ UiEventLogger uiEventLogger
) {
super(context, attrs, dumpManager, broadcastDispatcher, qsLogger,
foregroundExecutor, backgroundExecutor, localBluetoothManager, activityStarter,
- entryManager);
+ entryManager, uiEventLogger);
if (mFooter != null) {
removeView(mFooter.getView());
}
@@ -118,9 +120,9 @@ public class QuickQSPanel extends QSPanel {
lp2.setMarginStart(0);
mHorizontalLinearLayout.addView(mMediaPlayer.getView(), lp2);
- mTileLayout = new DoubleLineTileLayout(context);
+ mTileLayout = new DoubleLineTileLayout(context, mUiEventLogger);
mMediaTileLayout = mTileLayout;
- mRegularTileLayout = new HeaderTileLayout(context);
+ mRegularTileLayout = new HeaderTileLayout(context, mUiEventLogger);
LayoutParams lp = new LayoutParams(0, LayoutParams.MATCH_PARENT, 1);
lp.setMarginEnd(0);
lp.setMarginStart(marginSize);
@@ -135,7 +137,7 @@ public class QuickQSPanel extends QSPanel {
super.setPadding(0, 0, 0, 0);
} else {
sDefaultMaxTiles = getResources().getInteger(R.integer.quick_qs_panel_max_columns);
- mTileLayout = new HeaderTileLayout(context);
+ mTileLayout = new HeaderTileLayout(context, mUiEventLogger);
mTileLayout.setListening(mListening);
addView((View) mTileLayout, 0 /* Between brightness and footer */);
super.setPadding(0, 0, 0, 0);
@@ -312,13 +314,30 @@ public class QuickQSPanel extends QSPanel {
super.setVisibility(visibility);
}
+ @Override
+ protected QSEvent openPanelEvent() {
+ return QSEvent.QQS_PANEL_EXPANDED;
+ }
+
+ @Override
+ protected QSEvent closePanelEvent() {
+ return QSEvent.QQS_PANEL_COLLAPSED;
+ }
+
+ @Override
+ protected QSEvent tileVisibleEvent() {
+ return QSEvent.QQS_TILE_VISIBLE;
+ }
+
private static class HeaderTileLayout extends TileLayout {
- private boolean mListening;
+ private final UiEventLogger mUiEventLogger;
+
private Rect mClippingBounds = new Rect();
- public HeaderTileLayout(Context context) {
+ public HeaderTileLayout(Context context, UiEventLogger uiEventLogger) {
super(context);
+ mUiEventLogger = uiEventLogger;
setClipChildren(false);
setClipToPadding(false);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT,
@@ -443,5 +462,18 @@ public class QuickQSPanel extends QSPanel {
}
return getPaddingStart() + column * (mCellWidth + mCellMarginHorizontal);
}
+
+ @Override
+ public void setListening(boolean listening) {
+ boolean startedListening = !mListening && listening;
+ super.setListening(listening);
+ if (startedListening) {
+ for (int i = 0; i < getNumVisibleTiles(); i++) {
+ QSTile tile = mRecords.get(i).tile;
+ mUiEventLogger.logWithInstanceId(QSEvent.QQS_TILE_VISIBLE, 0,
+ tile.getMetricsSpec(), tile.getInstanceId());
+ }
+ }
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java
index 9f59277c918a..098431658e6a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java
@@ -31,7 +31,7 @@ public class TileLayout extends ViewGroup implements QSTileLayout {
protected final ArrayList<TileRecord> mRecords = new ArrayList<>();
private int mCellMarginTop;
- private boolean mListening;
+ protected boolean mListening;
protected int mMaxAllowedRows = 3;
// Prototyping with less rows
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 bfac85bd4c10..3e2f9dec5807 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
@@ -44,6 +44,7 @@ import com.android.systemui.keyguard.ScreenLifecycle;
import com.android.systemui.plugins.qs.QS;
import com.android.systemui.plugins.qs.QSTile;
import com.android.systemui.qs.QSDetailClipper;
+import com.android.systemui.qs.QSEditEvent;
import com.android.systemui.qs.QSTileHost;
import com.android.systemui.statusbar.phone.LightBarController;
import com.android.systemui.statusbar.phone.NotificationsQuickSettingsContainer;
@@ -93,7 +94,8 @@ public class QSCustomizer extends LinearLayout implements OnMenuItemClickListene
LightBarController lightBarController,
KeyguardStateController keyguardStateController,
ScreenLifecycle screenLifecycle,
- TileQueryHelper tileQueryHelper) {
+ TileQueryHelper tileQueryHelper,
+ UiEventLogger uiEventLogger) {
super(new ContextThemeWrapper(context, R.style.edit_theme), attrs);
LayoutInflater.from(getContext()).inflate(R.layout.qs_customize_panel_content, this);
@@ -115,7 +117,7 @@ public class QSCustomizer extends LinearLayout implements OnMenuItemClickListene
mToolbar.setTitle(R.string.qs_edit);
mRecyclerView = findViewById(android.R.id.list);
mTransparentView = findViewById(R.id.customizer_transparent_view);
- mTileAdapter = new TileAdapter(getContext());
+ mTileAdapter = new TileAdapter(getContext(), uiEventLogger);
mTileQueryHelper = tileQueryHelper;
mTileQueryHelper.setListener(mTileAdapter);
mRecyclerView.setAdapter(mTileAdapter);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/QSEditEvent.kt b/packages/SystemUI/src/com/android/systemui/qs/customize/QSEditEvent.kt
deleted file mode 100644
index ff8ddec8397a..000000000000
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/QSEditEvent.kt
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * 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.customize
-
-import com.android.internal.logging.UiEvent
-import com.android.internal.logging.UiEventLogger
-
-enum class QSEditEvent(private val _id: Int) : UiEventLogger.UiEventEnum {
-
- @UiEvent(doc = "Tile removed from current tiles")
- QS_EDIT_REMOVE(210),
- @UiEvent(doc = "Tile added to current tiles")
- QS_EDIT_ADD(211),
- @UiEvent(doc = "Tile moved")
- QS_EDIT_MOVE(212),
- @UiEvent(doc = "QS customizer open")
- QS_EDIT_OPEN(213),
- @UiEvent(doc = "QS customizer closed")
- QS_EDIT_CLOSED(214),
- @UiEvent(doc = "QS tiles reset")
- QS_EDIT_RESET(215);
-
- override fun getId() = _id
-} \ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
index 58de95d7ed6d..e738cec4962a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
@@ -41,8 +41,8 @@ import androidx.recyclerview.widget.RecyclerView.State;
import androidx.recyclerview.widget.RecyclerView.ViewHolder;
import com.android.internal.logging.UiEventLogger;
-import com.android.internal.logging.UiEventLoggerImpl;
import com.android.systemui.R;
+import com.android.systemui.qs.QSEditEvent;
import com.android.systemui.qs.QSTileHost;
import com.android.systemui.qs.customize.TileAdapter.Holder;
import com.android.systemui.qs.customize.TileQueryHelper.TileInfo;
@@ -92,10 +92,11 @@ public class TileAdapter extends RecyclerView.Adapter<Holder> implements TileSta
private int mAccessibilityFromIndex;
private CharSequence mAccessibilityFromLabel;
private QSTileHost mHost;
- private UiEventLogger mUiEventLogger = new UiEventLoggerImpl();
+ private final UiEventLogger mUiEventLogger;
- public TileAdapter(Context context) {
+ public TileAdapter(Context context, UiEventLogger uiEventLogger) {
mContext = context;
+ mUiEventLogger = uiEventLogger;
mAccessibilityManager = context.getSystemService(AccessibilityManager.class);
mItemTouchHelper = new ItemTouchHelper(mCallbacks);
mDecoration = new TileItemDecoration(context);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java b/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
index 08c8f86c1125..30e0a766de37 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
@@ -371,6 +371,11 @@ public class CustomTile extends QSTileImpl<State> implements TileChangeListener
return MetricsEvent.QS_CUSTOM;
}
+ @Override
+ public final String getMetricsSpec() {
+ return mComponent.getPackageName();
+ }
+
public void startUnlockAndRun() {
Dependency.get(ActivityStarter.class).postQSRunnableDismissingKeyguard(() -> {
try {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
index 60f6647743d2..7e5f2e1961e1 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
@@ -48,7 +48,9 @@ import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.LifecycleRegistry;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.logging.InstanceId;
import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.UiEventLogger;
import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.settingslib.Utils;
@@ -62,6 +64,7 @@ import com.android.systemui.plugins.qs.QSTile;
import com.android.systemui.plugins.qs.QSTile.State;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.qs.PagedTileLayout.TilePage;
+import com.android.systemui.qs.QSEvent;
import com.android.systemui.qs.QSHost;
import com.android.systemui.qs.QuickStatusBarHeader;
import com.android.systemui.qs.logging.QSLogger;
@@ -97,12 +100,14 @@ public abstract class QSTileImpl<TState extends State> implements QSTile, Lifecy
private final MetricsLogger mMetricsLogger = Dependency.get(MetricsLogger.class);
private final StatusBarStateController
mStatusBarStateController = Dependency.get(StatusBarStateController.class);
+ private final UiEventLogger mUiEventLogger;
private final QSLogger mQSLogger;
private final ArrayList<Callback> mCallbacks = new ArrayList<>();
private final Object mStaleListener = new Object();
protected TState mState;
private TState mTmpState;
+ private final InstanceId mInstanceId;
private boolean mAnnounceNextStateChange;
private String mTileSpec;
@@ -156,10 +161,12 @@ public abstract class QSTileImpl<TState extends State> implements QSTile, Lifecy
protected QSTileImpl(QSHost host) {
mHost = host;
mContext = host.getContext();
+ mInstanceId = host.getNewInstanceId();
mState = newTileState();
mTmpState = newTileState();
mQSSettingsPanelOption = QSSettingsControllerKt.getQSSettingsPanelOption();
mQSLogger = host.getQSLogger();
+ mUiEventLogger = host.getUiEventLogger();
}
protected final void resetStates() {
@@ -173,6 +180,11 @@ public abstract class QSTileImpl<TState extends State> implements QSTile, Lifecy
return mLifecycle;
}
+ @Override
+ public InstanceId getInstanceId() {
+ return mInstanceId;
+ }
+
/**
* Adds or removes a listening client for the tile. If the tile has one or more
* listening client it will go into the listening state.
@@ -247,6 +259,8 @@ public abstract class QSTileImpl<TState extends State> implements QSTile, Lifecy
mMetricsLogger.write(populate(new LogMaker(ACTION_QS_CLICK).setType(TYPE_ACTION)
.addTaggedData(FIELD_STATUS_BAR_STATE,
mStatusBarStateController.getState())));
+ mUiEventLogger.logWithInstanceId(QSEvent.QS_ACTION_CLICK, 0, getMetricsSpec(),
+ getInstanceId());
mQSLogger.logTileClick(mTileSpec, mStatusBarStateController.getState(), mState.state);
mHandler.sendEmptyMessage(H.CLICK);
}
@@ -255,6 +269,8 @@ public abstract class QSTileImpl<TState extends State> implements QSTile, Lifecy
mMetricsLogger.write(populate(new LogMaker(ACTION_QS_SECONDARY_CLICK).setType(TYPE_ACTION)
.addTaggedData(FIELD_STATUS_BAR_STATE,
mStatusBarStateController.getState())));
+ mUiEventLogger.logWithInstanceId(QSEvent.QS_ACTION_SECONDARY_CLICK, 0, getMetricsSpec(),
+ getInstanceId());
mQSLogger.logTileSecondaryClick(mTileSpec, mStatusBarStateController.getState(),
mState.state);
mHandler.sendEmptyMessage(H.SECONDARY_CLICK);
@@ -264,6 +280,8 @@ public abstract class QSTileImpl<TState extends State> implements QSTile, Lifecy
mMetricsLogger.write(populate(new LogMaker(ACTION_QS_LONG_PRESS).setType(TYPE_ACTION)
.addTaggedData(FIELD_STATUS_BAR_STATE,
mStatusBarStateController.getState())));
+ mUiEventLogger.logWithInstanceId(QSEvent.QS_ACTION_LONG_PRESS, 0, getMetricsSpec(),
+ getInstanceId());
mQSLogger.logTileLongClick(mTileSpec, mStatusBarStateController.getState(), mState.state);
mHandler.sendEmptyMessage(H.LONG_CLICK);
@@ -483,6 +501,11 @@ public abstract class QSTileImpl<TState extends State> implements QSTile, Lifecy
}
}
+ @Override
+ public String getMetricsSpec() {
+ return mTileSpec;
+ }
+
/**
* Provides a default label for the tile.
* @return default label for the tile.
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailView.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailView.java
index 447f48b5db94..89ce125ae985 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailView.java
@@ -26,10 +26,12 @@ import android.view.View;
import android.view.ViewGroup;
import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.UiEventLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settingslib.RestrictedLockUtils;
import com.android.systemui.R;
import com.android.systemui.qs.PseudoGridView;
+import com.android.systemui.qs.QSUserSwitcherEvent;
import com.android.systemui.statusbar.policy.UserSwitcherController;
/**
@@ -48,8 +50,9 @@ public class UserDetailView extends PseudoGridView {
R.layout.qs_user_detail, parent, attach);
}
- public void createAndSetAdapter(UserSwitcherController controller) {
- mAdapter = new Adapter(mContext, controller);
+ public void createAndSetAdapter(UserSwitcherController controller,
+ UiEventLogger uiEventLogger) {
+ mAdapter = new Adapter(mContext, controller, uiEventLogger);
ViewGroupAdapterBridge.link(this, mAdapter);
}
@@ -63,11 +66,14 @@ public class UserDetailView extends PseudoGridView {
private final Context mContext;
protected UserSwitcherController mController;
private View mCurrentUserView;
+ private final UiEventLogger mUiEventLogger;
- public Adapter(Context context, UserSwitcherController controller) {
+ public Adapter(Context context, UserSwitcherController controller,
+ UiEventLogger uiEventLogger) {
super(controller);
mContext = context;
mController = controller;
+ mUiEventLogger = uiEventLogger;
}
@Override
@@ -127,6 +133,7 @@ public class UserDetailView extends PseudoGridView {
mController.startActivity(intent);
} else if (tag.isSwitchToEnabled) {
MetricsLogger.action(mContext, MetricsEvent.QS_SWITCH_USER);
+ mUiEventLogger.log(QSUserSwitcherEvent.QS_USER_SWITCH);
if (!tag.isAddUser && !tag.isRestricted && !tag.isDisabledByAdmin) {
if (mCurrentUserView != null) {
mCurrentUserView.setActivated(false);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
index e81e5cae5bfc..229aa6d98e0a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
@@ -24,6 +24,7 @@ import android.util.Log;
import android.view.animation.Interpolator;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.logging.UiEventLogger;
import com.android.systemui.DejankUtils;
import com.android.systemui.Dumpable;
import com.android.systemui.Interpolators;
@@ -69,6 +70,7 @@ public class StatusBarStateControllerImpl implements SysuiStatusBarStateControll
};
private final ArrayList<RankedListener> mListeners = new ArrayList<>();
+ private final UiEventLogger mUiEventLogger;
private int mState;
private int mLastState;
private boolean mLeaveOpenOnKeyguardHide;
@@ -119,7 +121,8 @@ public class StatusBarStateControllerImpl implements SysuiStatusBarStateControll
private Interpolator mDozeInterpolator = Interpolators.FAST_OUT_SLOW_IN;
@Inject
- public StatusBarStateControllerImpl() {
+ public StatusBarStateControllerImpl(UiEventLogger uiEventLogger) {
+ mUiEventLogger = uiEventLogger;
for (int i = 0; i < HISTORY_SIZE; i++) {
mHistoricalRecords[i] = new HistoricalState();
}
@@ -155,6 +158,7 @@ public class StatusBarStateControllerImpl implements SysuiStatusBarStateControll
}
mLastState = mState;
mState = state;
+ mUiEventLogger.log(StatusBarStateEvent.fromState(mState));
for (RankedListener rl : new ArrayList<>(mListeners)) {
rl.mListener.onStateChanged(mState);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateEvent.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateEvent.java
new file mode 100644
index 000000000000..8330169980d4
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateEvent.java
@@ -0,0 +1,69 @@
+/*
+ * 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.statusbar;
+
+import com.android.internal.logging.UiEvent;
+import com.android.internal.logging.UiEventLogger;
+
+/**
+ * Events for changes in the {@link StatusBarState}.
+ */
+public enum StatusBarStateEvent implements UiEventLogger.UiEventEnum {
+
+ @UiEvent(doc = "StatusBarState changed to unknown state")
+ STATUS_BAR_STATE_UNKNOWN(428),
+
+ @UiEvent(doc = "StatusBarState changed to SHADE state")
+ STATUS_BAR_STATE_SHADE(429),
+
+ @UiEvent(doc = "StatusBarState changed to KEYGUARD state")
+ STATUS_BAR_STATE_KEYGUARD(430),
+
+ @UiEvent(doc = "StatusBarState changed to SHADE_LOCKED state")
+ STATUS_BAR_STATE_SHADE_LOCKED(431),
+
+ @UiEvent(doc = "StatusBarState changed to FULLSCREEN_USER_SWITCHER state")
+ STATUS_BAR_STATE_FULLSCREEN_USER_SWITCHER(432);
+
+ private int mId;
+ StatusBarStateEvent(int id) {
+ mId = id;
+ }
+
+ @Override
+ public int getId() {
+ return mId;
+ }
+
+ /**
+ * Return the event associated with the state.
+ */
+ public static StatusBarStateEvent fromState(int state) {
+ switch(state) {
+ case StatusBarState.SHADE:
+ return STATUS_BAR_STATE_SHADE;
+ case StatusBarState.KEYGUARD:
+ return STATUS_BAR_STATE_KEYGUARD;
+ case StatusBarState.SHADE_LOCKED:
+ return STATUS_BAR_STATE_SHADE_LOCKED;
+ case StatusBarState.FULLSCREEN_USER_SWITCHER:
+ return STATUS_BAR_STATE_FULLSCREEN_USER_SWITCHER;
+ default:
+ return STATUS_BAR_STATE_UNKNOWN;
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
index 78ee5f25b111..1dbfa32cdf41 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
@@ -24,8 +24,6 @@ import android.os.Handler;
import android.view.accessibility.AccessibilityManager;
import com.android.internal.logging.MetricsLogger;
-import com.android.internal.logging.UiEventLogger;
-import com.android.internal.logging.UiEventLoggerImpl;
import com.android.systemui.R;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dagger.qualifiers.UiBackground;
@@ -161,13 +159,6 @@ public interface NotificationsModule {
return new NotificationPanelLoggerImpl();
}
- /** Provides an instance of {@link com.android.internal.logging.UiEventLogger} */
- @Singleton
- @Provides
- static UiEventLogger provideUiEventLogger() {
- return new UiEventLoggerImpl();
- }
-
/** Provides an instance of {@link NotificationBlockingHelperManager} */
@Singleton
@Provides
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
index bb0b5e00ff67..412962cc797a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
@@ -48,6 +48,7 @@ import android.view.ViewGroup;
import android.widget.BaseAdapter;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.logging.UiEventLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.util.UserIcons;
import com.android.settingslib.RestrictedLockUtilsInternal;
@@ -61,6 +62,7 @@ import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.qs.DetailAdapter;
+import com.android.systemui.qs.QSUserSwitcherEvent;
import com.android.systemui.qs.tiles.UserDetailView;
import com.android.systemui.statusbar.phone.SystemUIDialog;
@@ -108,13 +110,15 @@ public class UserSwitcherController implements Dumpable {
private int mSecondaryUser = UserHandle.USER_NULL;
private Intent mSecondaryUserServiceIntent;
private SparseBooleanArray mForcePictureLoadForUserId = new SparseBooleanArray(2);
+ private final UiEventLogger mUiEventLogger;
@Inject
public UserSwitcherController(Context context, KeyguardStateController keyguardStateController,
@Main Handler handler, ActivityStarter activityStarter,
- BroadcastDispatcher broadcastDispatcher) {
+ BroadcastDispatcher broadcastDispatcher, UiEventLogger uiEventLogger) {
mContext = context;
mBroadcastDispatcher = broadcastDispatcher;
+ mUiEventLogger = uiEventLogger;
if (!UserManager.isGuestUserEphemeral()) {
mGuestResumeSessionReceiver.register(mBroadcastDispatcher);
}
@@ -801,7 +805,7 @@ public class UserSwitcherController implements Dumpable {
UserDetailView v;
if (!(convertView instanceof UserDetailView)) {
v = UserDetailView.inflate(context, parent, false);
- v.createAndSetAdapter(UserSwitcherController.this);
+ v.createAndSetAdapter(UserSwitcherController.this, mUiEventLogger);
} else {
v = (UserDetailView) convertView;
}
@@ -827,6 +831,21 @@ public class UserSwitcherController implements Dumpable {
public int getMetricsCategory() {
return MetricsEvent.QS_USERDETAIL;
}
+
+ @Override
+ public UiEventLogger.UiEventEnum openDetailEvent() {
+ return QSUserSwitcherEvent.QS_USER_DETAIL_OPEN;
+ }
+
+ @Override
+ public UiEventLogger.UiEventEnum closeDetailEvent() {
+ return QSUserSwitcherEvent.QS_USER_DETAIL_CLOSE;
+ }
+
+ @Override
+ public UiEventLogger.UiEventEnum moreSettingsEvent() {
+ return QSUserSwitcherEvent.QS_USER_MORE_SETTINGS;
+ }
};
private final KeyguardStateController.Callback mCallback =
diff --git a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
index 7bb987ca7cf0..0cd4fb9578ff 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
@@ -56,9 +56,12 @@ import android.widget.TextView;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.UiEventLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.systemui.Prefs;
import com.android.systemui.R;
+import com.android.systemui.qs.QSDndEvent;
+import com.android.systemui.qs.QSEvents;
import com.android.systemui.statusbar.policy.ZenModeController;
import java.io.FileDescriptor;
@@ -103,6 +106,7 @@ public class ZenModePanel extends FrameLayout {
private final TransitionHelper mTransitionHelper = new TransitionHelper();
private final Uri mForeverId;
private final ConfigurableTexts mConfigurableTexts;
+ private final UiEventLogger mUiEventLogger = QSEvents.INSTANCE.getQsUiEventsLogger();
private String mTag = TAG + "/" + Integer.toHexString(System.identityHashCode(this));
@@ -662,6 +666,7 @@ public class ZenModePanel extends FrameLayout {
tag.rb.setChecked(true);
if (DEBUG) Log.d(mTag, "onCheckedChanged " + conditionId);
MetricsLogger.action(mContext, MetricsEvent.QS_DND_CONDITION_SELECT);
+ mUiEventLogger.log(QSDndEvent.QS_DND_CONDITION_SELECT);
select(tag.condition);
announceConditionSelection(tag);
}
@@ -767,6 +772,7 @@ public class ZenModePanel extends FrameLayout {
private void onClickTimeButton(View row, ConditionTag tag, boolean up, int rowId) {
MetricsLogger.action(mContext, MetricsEvent.QS_DND_TIME, up);
+ mUiEventLogger.log(up ? QSDndEvent.QS_DND_TIME_UP : QSDndEvent.QS_DND_TIME_DOWN);
Condition newCondition = null;
final int N = MINUTE_BUCKETS.length;
if (mBucketIndex == -1) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingManagerProxyTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingManagerProxyTest.java
index 5b78067ef81a..ae7387996322 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingManagerProxyTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingManagerProxyTest.java
@@ -27,6 +27,7 @@ import android.util.DisplayMetrics;
import androidx.test.filters.SmallTest;
+import com.android.internal.logging.testing.UiEventLoggerFake;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.classifier.brightline.BrightLineFalsingManager;
@@ -65,7 +66,8 @@ public class FalsingManagerProxyTest extends SysuiTestCase {
private FakeExecutor mExecutor = new FakeExecutor(new FakeSystemClock());
private FakeExecutor mUiBgExecutor = new FakeExecutor(new FakeSystemClock());
private DockManager mDockManager = new DockManagerFake();
- private StatusBarStateController mStatusBarStateController = new StatusBarStateControllerImpl();
+ private StatusBarStateController mStatusBarStateController =
+ new StatusBarStateControllerImpl(new UiEventLoggerFake());
@Before
public void setup() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/BrightLineFalsingManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/BrightLineFalsingManagerTest.java
index 8b5cc9abb777..b9cb499420ee 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/BrightLineFalsingManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/BrightLineFalsingManagerTest.java
@@ -25,6 +25,7 @@ import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.util.DisplayMetrics;
+import com.android.internal.logging.testing.UiEventLoggerFake;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.dock.DockManager;
@@ -67,7 +68,7 @@ public class BrightLineFalsingManagerTest extends SysuiTestCase {
FalsingDataProvider falsingDataProvider = new FalsingDataProvider(dm);
DeviceConfigProxy deviceConfigProxy = new DeviceConfigProxyFake();
DockManager dockManager = new DockManagerFake();
- mStatusBarStateController = new StatusBarStateControllerImpl();
+ mStatusBarStateController = new StatusBarStateControllerImpl(new UiEventLoggerFake());
mStatusBarStateController.setState(StatusBarState.KEYGUARD);
mFalsingManager = new BrightLineFalsingManager(falsingDataProvider,
mKeyguardUpdateMonitor, mProximitySensor, deviceConfigProxy, dockManager,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSDetailTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSDetailTest.java
index 8879e83b4d0e..353efeeb21f6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSDetailTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSDetailTest.java
@@ -16,6 +16,7 @@ package com.android.systemui.qs;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_QS_MORE_SETTINGS;
+import static org.junit.Assert.assertEquals;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.eq;
@@ -33,11 +34,13 @@ import android.view.View;
import androidx.test.filters.SmallTest;
import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.testing.UiEventLoggerFake;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.qs.DetailAdapter;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -54,10 +57,13 @@ public class QSDetailTest extends SysuiTestCase {
private ActivityStarter mActivityStarter;
private DetailAdapter mMockDetailAdapter;
private TestableLooper mTestableLooper;
+ private UiEventLoggerFake mUiEventLogger;
@Before
public void setup() throws Exception {
mTestableLooper = TestableLooper.get(this);
+ mUiEventLogger = QSEvents.INSTANCE.setLoggerForTesting();
+
mTestableLooper.runWithLooper(() -> {
mMetricsLogger = mDependency.injectMockDependency(MetricsLogger.class);
mActivityStarter = mDependency.injectMockDependency(ActivityStarter.class);
@@ -70,6 +76,19 @@ public class QSDetailTest extends SysuiTestCase {
when(mMockDetailAdapter.createDetailView(any(), any(), any()))
.thenReturn(mock(View.class));
});
+
+ // Only detail in use is the user detail
+ when(mMockDetailAdapter.openDetailEvent())
+ .thenReturn(QSUserSwitcherEvent.QS_USER_DETAIL_OPEN);
+ when(mMockDetailAdapter.closeDetailEvent())
+ .thenReturn(QSUserSwitcherEvent.QS_USER_DETAIL_CLOSE);
+ when(mMockDetailAdapter.moreSettingsEvent())
+ .thenReturn(QSUserSwitcherEvent.QS_USER_MORE_SETTINGS);
+ }
+
+ @After
+ public void tearDown() {
+ QSEvents.INSTANCE.resetLogger();
}
@Test
@@ -79,9 +98,16 @@ public class QSDetailTest extends SysuiTestCase {
mQsDetail.handleShowingDetail(mMockDetailAdapter, 0, 0, false);
verify(mMetricsLogger).visible(eq(mMockDetailAdapter.getMetricsCategory()));
+ assertEquals(1, mUiEventLogger.numLogs());
+ assertEquals(QSUserSwitcherEvent.QS_USER_DETAIL_OPEN.getId(), mUiEventLogger.eventId(0));
+ mUiEventLogger.getLogs().clear();
+
mQsDetail.handleShowingDetail(null, 0, 0, false);
verify(mMetricsLogger).hidden(eq(mMockDetailAdapter.getMetricsCategory()));
+ assertEquals(1, mUiEventLogger.numLogs());
+ assertEquals(QSUserSwitcherEvent.QS_USER_DETAIL_CLOSE.getId(), mUiEventLogger.eventId(0));
+
ViewUtils.detachView(mQsDetail);
mTestableLooper.processAllMessages();
}
@@ -92,10 +118,13 @@ public class QSDetailTest extends SysuiTestCase {
mTestableLooper.processAllMessages();
mQsDetail.handleShowingDetail(mMockDetailAdapter, 0, 0, false);
- mQsDetail.findViewById(android.R.id.button2).performClick();
+ mUiEventLogger.getLogs().clear();
+ mQsDetail.requireViewById(android.R.id.button2).performClick();
int metricsCategory = mMockDetailAdapter.getMetricsCategory();
verify(mMetricsLogger).action(eq(ACTION_QS_MORE_SETTINGS), eq(metricsCategory));
+ assertEquals(1, mUiEventLogger.numLogs());
+ assertEquals(QSUserSwitcherEvent.QS_USER_MORE_SETTINGS.getId(), mUiEventLogger.eventId(0));
verify(mActivityStarter).postStartActivityDismissingKeyguard(any(), anyInt());
@@ -105,7 +134,9 @@ public class QSDetailTest extends SysuiTestCase {
@Test
public void testNullAdapterClick() {
- mQsDetail.setupDetailFooter(mock(DetailAdapter.class));
- mQsDetail.findViewById(android.R.id.button2).performClick();
+ DetailAdapter mock = mock(DetailAdapter.class);
+ when(mock.moreSettingsEvent()).thenReturn(DetailAdapter.INVALID);
+ mQsDetail.setupDetailFooter(mock);
+ mQsDetail.requireViewById(android.R.id.button2).performClick();
}
}
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 1f494a69f953..d338cbf51fb5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
@@ -34,6 +34,7 @@ import androidx.test.filters.SmallTest;
import androidx.test.filters.Suppress;
import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.UiEventLogger;
import com.android.keyguard.CarrierText;
import com.android.systemui.Dependency;
import com.android.systemui.R;
@@ -106,7 +107,7 @@ public class QSFragmentTest extends SysuiBaseFragmentTest {
mock(PluginManager.class), mock(TunerService.class),
() -> mock(AutoTileManager.class), mock(DumpManager.class),
mock(BroadcastDispatcher.class), Optional.of(mock(StatusBar.class)),
- mock(QSLogger.class));
+ mock(QSLogger.class), mock(UiEventLogger.class));
qs.setHost(host);
qs.setListening(true);
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 392adf99e511..9d35e53e7421 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java
@@ -35,6 +35,7 @@ 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.settingslib.bluetooth.LocalBluetoothManager;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.broadcast.BroadcastDispatcher;
@@ -94,17 +95,19 @@ public class QSPanelTest extends SysuiTestCase {
private ActivityStarter mActivityStarter;
@Mock
private NotificationEntryManager mEntryManager;
+ private UiEventLoggerFake mUiEventLogger;
@Before
public void setup() throws Exception {
MockitoAnnotations.initMocks(this);
mTestableLooper = TestableLooper.get(this);
+ mUiEventLogger = new UiEventLoggerFake();
mTestableLooper.runWithLooper(() -> {
mMetricsLogger = mDependency.injectMockDependency(MetricsLogger.class);
mQsPanel = new QSPanel(mContext, null, mDumpManager, mBroadcastDispatcher,
mQSLogger, mForegroundExecutor, mBackgroundExecutor,
- mLocalBluetoothManager, mActivityStarter, mEntryManager);
+ mLocalBluetoothManager, mActivityStarter, mEntryManager, mUiEventLogger);
// Provides a parent with non-zero size for QSPanel
mParentView = new FrameLayout(mContext);
mParentView.addView(mQsPanel);
@@ -124,9 +127,17 @@ public class QSPanelTest extends SysuiTestCase {
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
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSTileHostTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSTileHostTest.java
index 95c3e5aee870..966fa88653bf 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSTileHostTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSTileHostTest.java
@@ -41,6 +41,7 @@ import android.testing.TestableLooper.RunWithLooper;
import androidx.test.filters.SmallTest;
+import com.android.internal.logging.UiEventLogger;
import com.android.internal.util.CollectionUtils;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
@@ -50,7 +51,6 @@ import com.android.systemui.plugins.qs.QSFactory;
import com.android.systemui.plugins.qs.QSTile;
import com.android.systemui.qs.external.CustomTile;
import com.android.systemui.qs.logging.QSLogger;
-import com.android.systemui.qs.tileimpl.QSFactoryImpl;
import com.android.systemui.qs.tileimpl.QSTileImpl;
import com.android.systemui.shared.plugins.PluginManager;
import com.android.systemui.statusbar.phone.AutoTileManager;
@@ -105,6 +105,8 @@ public class QSTileHostTest extends SysuiTestCase {
private QSLogger mQSLogger;
@Mock
private CustomTile mCustomTile;
+ @Mock
+ private UiEventLogger mUiEventLogger;
private Handler mHandler;
private TestableLooper mLooper;
@@ -117,7 +119,7 @@ public class QSTileHostTest extends SysuiTestCase {
mHandler = new Handler(mLooper.getLooper());
mQSTileHost = new TestQSTileHost(mContext, mIconController, mDefaultFactory, mHandler,
mLooper.getLooper(), mPluginManager, mTunerService, mAutoTiles, mDumpManager,
- mBroadcastDispatcher, mStatusBar, mQSLogger);
+ mBroadcastDispatcher, mStatusBar, mQSLogger, mUiEventLogger);
setUpTileFactory();
// Override this config so there are no unexpected tiles
@@ -298,10 +300,11 @@ public class QSTileHostTest extends SysuiTestCase {
QSFactory defaultFactory, Handler mainHandler, Looper bgLooper,
PluginManager pluginManager, TunerService tunerService,
Provider<AutoTileManager> autoTiles, DumpManager dumpManager,
- BroadcastDispatcher broadcastDispatcher, StatusBar statusBar, QSLogger qsLogger) {
+ BroadcastDispatcher broadcastDispatcher, StatusBar statusBar, QSLogger qsLogger,
+ UiEventLogger uiEventLogger) {
super(context, iconController, defaultFactory, mainHandler, bgLooper, pluginManager,
tunerService, autoTiles, dumpManager, broadcastDispatcher,
- Optional.of(statusBar), qsLogger);
+ Optional.of(statusBar), qsLogger, uiEventLogger);
}
@Override
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/customize/TileAdapterTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/customize/TileAdapterTest.java
index 25bac7ae4117..204de929e331 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/customize/TileAdapterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/customize/TileAdapterTest.java
@@ -24,6 +24,7 @@ import android.testing.TestableLooper.RunWithLooper;
import androidx.test.filters.SmallTest;
+import com.android.internal.logging.testing.UiEventLoggerFake;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.qs.QSTileHost;
@@ -42,7 +43,8 @@ public class TileAdapterTest extends SysuiTestCase {
@Before
public void setup() throws Exception {
- TestableLooper.get(this).runWithLooper(() -> mTileAdapter = new TileAdapter(mContext));
+ TestableLooper.get(this).runWithLooper(() -> mTileAdapter =
+ new TileAdapter(mContext, new UiEventLoggerFake()));
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTest.java
index 884e4c0f5205..2fc3d72c2672 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTest.java
@@ -30,6 +30,7 @@ import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.testing.TestableLooper.RunWithLooper;
+import com.android.internal.logging.UiEventLogger;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dump.DumpManager;
@@ -81,6 +82,8 @@ public class TileServicesTest extends SysuiTestCase {
private StatusBar mStatusBar;
@Mock
private QSLogger mQSLogger;
+ @Mock
+ private UiEventLogger mUiEventLogger;
@Before
public void setUp() throws Exception {
@@ -98,7 +101,8 @@ public class TileServicesTest extends SysuiTestCase {
mDumpManager,
mBroadcastDispatcher,
Optional.of(mStatusBar),
- mQSLogger);
+ mQSLogger,
+ mUiEventLogger);
mTileService = new TestTileServices(host, Looper.getMainLooper(), mBroadcastDispatcher);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileImplTest.java
index 4fada336fb94..1c0d451e064a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileImplTest.java
@@ -46,12 +46,16 @@ import android.testing.TestableLooper.RunWithLooper;
import androidx.test.filters.SmallTest;
+import com.android.internal.logging.InstanceId;
import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.UiEventLogger;
+import com.android.internal.logging.testing.UiEventLoggerFake;
import com.android.systemui.Dependency;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.qs.QSTile;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.qs.QSEvent;
import com.android.systemui.qs.QSHost;
import com.android.systemui.qs.QSTileHost;
import com.android.systemui.qs.logging.QSLogger;
@@ -83,6 +87,8 @@ public class QSTileImplTest extends SysuiTestCase {
private QSTileHost mHost;
private MetricsLogger mMetricsLogger;
private StatusBarStateController mStatusBarStateController;
+ private UiEventLoggerFake mUiEventLoggerFake;
+ private InstanceId mInstanceId = InstanceId.fakeInstanceId(5);
@Captor
private ArgumentCaptor<LogMaker> mLogCaptor;
@@ -94,12 +100,15 @@ public class QSTileImplTest extends SysuiTestCase {
mDependency.injectTestDependency(Dependency.BG_LOOPER, mTestableLooper.getLooper());
mDependency.injectMockDependency(ActivityStarter.class);
mMetricsLogger = mDependency.injectMockDependency(MetricsLogger.class);
+ mUiEventLoggerFake = new UiEventLoggerFake();
mStatusBarStateController =
mDependency.injectMockDependency(StatusBarStateController.class);
mHost = mock(QSTileHost.class);
when(mHost.indexOf(SPEC)).thenReturn(POSITION);
when(mHost.getContext()).thenReturn(mContext.getBaseContext());
when(mHost.getQSLogger()).thenReturn(mQsLogger);
+ when(mHost.getUiEventLogger()).thenReturn(mUiEventLoggerFake);
+ when(mHost.getNewInstanceId()).thenReturn(mInstanceId);
mTile = spy(new TileImpl(mHost));
mTile.mHandler = mTile.new H(mTestableLooper.getLooper());
@@ -110,6 +119,9 @@ public class QSTileImplTest extends SysuiTestCase {
public void testClick_Metrics() {
mTile.click();
verify(mMetricsLogger).write(argThat(new TileLogMatcher(ACTION_QS_CLICK)));
+ assertEquals(1, mUiEventLoggerFake.numLogs());
+ UiEventLoggerFake.FakeUiEvent event = mUiEventLoggerFake.get(0);
+ assertEvent(QSEvent.QS_ACTION_CLICK, event);
}
@Test
@@ -133,6 +145,9 @@ public class QSTileImplTest extends SysuiTestCase {
public void testSecondaryClick_Metrics() {
mTile.secondaryClick();
verify(mMetricsLogger).write(argThat(new TileLogMatcher(ACTION_QS_SECONDARY_CLICK)));
+ assertEquals(1, mUiEventLoggerFake.numLogs());
+ UiEventLoggerFake.FakeUiEvent event = mUiEventLoggerFake.get(0);
+ assertEvent(QSEvent.QS_ACTION_SECONDARY_CLICK, event);
}
@Test
@@ -156,6 +171,9 @@ public class QSTileImplTest extends SysuiTestCase {
public void testLongClick_Metrics() {
mTile.longClick();
verify(mMetricsLogger).write(argThat(new TileLogMatcher(ACTION_QS_LONG_PRESS)));
+ assertEquals(1, mUiEventLoggerFake.numLogs());
+ UiEventLoggerFake.FakeUiEvent event = mUiEventLoggerFake.get(0);
+ assertEvent(QSEvent.QS_ACTION_LONG_PRESS, event);
}
@@ -249,6 +267,13 @@ public class QSTileImplTest extends SysuiTestCase {
verify(mQsLogger).logTileChangeListening(SPEC, false);
}
+ private void assertEvent(UiEventLogger.UiEventEnum eventType,
+ UiEventLoggerFake.FakeUiEvent fakeEvent) {
+ assertEquals(eventType.getId(), fakeEvent.eventId);
+ assertEquals(SPEC, fakeEvent.packageName);
+ assertEquals(mInstanceId, fakeEvent.instanceId);
+ }
+
private class TileLogMatcher implements ArgumentMatcher<LogMaker> {
private final int mCategory;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/UserDetailViewAdapterTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/UserDetailViewAdapterTest.kt
index b51e716591fe..6d6a4d8f6b7d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/UserDetailViewAdapterTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/UserDetailViewAdapterTest.kt
@@ -24,8 +24,11 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.test.filters.SmallTest
+import com.android.internal.logging.testing.UiEventLoggerFake
import com.android.systemui.SysuiTestCase
+import com.android.systemui.qs.QSUserSwitcherEvent
import com.android.systemui.statusbar.policy.UserSwitcherController
+import org.junit.Assert.assertEquals
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -50,15 +53,17 @@ class UserDetailViewAdapterTest : SysuiTestCase() {
@Mock private lateinit var mPicture: Bitmap
@Mock private lateinit var mLayoutInflater: LayoutInflater
private lateinit var adapter: UserDetailView.Adapter
+ private lateinit var uiEventLogger: UiEventLoggerFake
@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
+ uiEventLogger = UiEventLoggerFake()
mContext.addMockSystemService(Context.LAYOUT_INFLATER_SERVICE, mLayoutInflater)
`when`(mLayoutInflater.inflate(anyInt(), any(ViewGroup::class.java), anyBoolean()))
.thenReturn(mInflatedUserDetailItemView)
- adapter = UserDetailView.Adapter(mContext, mUserSwitcherController)
+ adapter = UserDetailView.Adapter(mContext, mUserSwitcherController, uiEventLogger)
}
private fun clickableTest(
@@ -77,6 +82,17 @@ class UserDetailViewAdapterTest : SysuiTestCase() {
}
@Test
+ fun testUserSwitchLog() {
+ val user = createUserRecord(false /* current */, false /* guest */)
+ val v = adapter.createUserDetailItemView(View(mContext), mParent, user)
+ `when`(v.tag).thenReturn(user)
+ adapter.onClick(v)
+
+ assertEquals(1, uiEventLogger.numLogs())
+ assertEquals(QSUserSwitcherEvent.QS_USER_SWITCH.id, uiEventLogger.eventId(0))
+ }
+
+ @Test
fun testGuestIsClickable_differentViews_notCurrent() {
clickableTest(false, true, mOtherView, true)
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarStateControllerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarStateControllerImplTest.kt
new file mode 100644
index 000000000000..fca6bc50f6e2
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarStateControllerImplTest.kt
@@ -0,0 +1,60 @@
+/*
+ * 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.statusbar
+
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import androidx.test.filters.SmallTest
+import com.android.internal.logging.testing.UiEventLoggerFake
+import com.android.systemui.SysuiTestCase
+import org.junit.Assert.assertEquals
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+@TestableLooper.RunWithLooper
+class StatusBarStateControllerImplTest : SysuiTestCase() {
+
+ private lateinit var controller: StatusBarStateControllerImpl
+ private lateinit var uiEventLogger: UiEventLoggerFake
+
+ @Before
+ fun setUp() {
+ uiEventLogger = UiEventLoggerFake()
+ controller = StatusBarStateControllerImpl(uiEventLogger)
+ }
+
+ @Test
+ fun testChangeState_logged() {
+ TestableLooper.get(this).runWithLooper {
+ controller.state = StatusBarState.FULLSCREEN_USER_SWITCHER
+ controller.state = StatusBarState.KEYGUARD
+ controller.state = StatusBarState.SHADE
+ controller.state = StatusBarState.SHADE_LOCKED
+ }
+
+ val logs = uiEventLogger.logs
+ assertEquals(4, logs.size)
+ val ids = logs.map(UiEventLoggerFake.FakeUiEvent::eventId)
+ assertEquals(StatusBarStateEvent.STATUS_BAR_STATE_FULLSCREEN_USER_SWITCHER.id, ids[0])
+ assertEquals(StatusBarStateEvent.STATUS_BAR_STATE_KEYGUARD.id, ids[1])
+ assertEquals(StatusBarStateEvent.STATUS_BAR_STATE_SHADE.id, ids[2])
+ assertEquals(StatusBarStateEvent.STATUS_BAR_STATE_SHADE_LOCKED.id, ids[3])
+ }
+} \ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarStateEventTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarStateEventTest.kt
new file mode 100644
index 000000000000..b5b2f1fc0484
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarStateEventTest.kt
@@ -0,0 +1,50 @@
+/*
+ * 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.statusbar
+
+import android.testing.AndroidTestingRunner
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import org.junit.Assert.assertEquals
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class StatusBarStateEventTest : SysuiTestCase() {
+
+ @Test
+ fun testFromState() {
+ val events = listOf(
+ StatusBarStateEvent.STATUS_BAR_STATE_SHADE,
+ StatusBarStateEvent.STATUS_BAR_STATE_SHADE_LOCKED,
+ StatusBarStateEvent.STATUS_BAR_STATE_KEYGUARD,
+ StatusBarStateEvent.STATUS_BAR_STATE_FULLSCREEN_USER_SWITCHER,
+ StatusBarStateEvent.STATUS_BAR_STATE_UNKNOWN
+ )
+ val states = listOf(
+ StatusBarState.SHADE,
+ StatusBarState.SHADE_LOCKED,
+ StatusBarState.KEYGUARD,
+ StatusBarState.FULLSCREEN_USER_SWITCHER,
+ -1
+ )
+ events.zip(states).forEach { (event, state) ->
+ assertEquals(event, StatusBarStateEvent.fromState(state))
+ }
+ }
+} \ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
index 4b09aa687073..57ef05544e7e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
@@ -47,6 +47,7 @@ import android.view.accessibility.AccessibilityManager;
import androidx.test.filters.SmallTest;
import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.testing.UiEventLoggerFake;
import com.android.internal.util.LatencyTracker;
import com.android.keyguard.KeyguardClockSwitch;
import com.android.keyguard.KeyguardUpdateMonitor;
@@ -207,7 +208,7 @@ public class NotificationPanelViewTest extends SysuiTestCase {
NotificationWakeUpCoordinator coordinator =
new NotificationWakeUpCoordinator(
mock(HeadsUpManagerPhone.class),
- new StatusBarStateControllerImpl(),
+ new StatusBarStateControllerImpl(new UiEventLoggerFake()),
mKeyguardBypassController,
mDozeParameters);
PulseExpansionHandler expansionHandler = new PulseExpansionHandler(