diff options
35 files changed, 392 insertions, 81 deletions
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 f607cc8f7e15..e586c38a286a 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 @@ -14,6 +14,7 @@ package com.android.systemui.plugins.qs; +import android.annotation.NonNull; import android.content.Context; import android.graphics.drawable.Drawable; import android.metrics.LogMaker; @@ -107,6 +108,12 @@ public interface QSTile { public int getPadding() { return 0; } + + @Override + @NonNull + public String toString() { + return "Icon"; + } } @ProvidesInterface(version = State.VERSION) diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java index e119beff3c6f..4a7469c1bd2d 100644 --- a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java +++ b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java @@ -61,6 +61,18 @@ public class LogModule { return buffer; } + /** Provides a logging buffer for all logs related to Quick Settings. */ + @Provides + @Singleton + @QSLog + public static LogBuffer provideQuickSettingsLogBuffer( + LogcatEchoTracker bufferFilter, + DumpController dumpController) { + LogBuffer buffer = new LogBuffer("QSLog", 500, 10, bufferFilter); + buffer.attach(dumpController); + return buffer; + } + /** Allows logging buffers to be tweaked via adb on debug builds but not on prod builds. */ @Provides @Singleton diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/QSLog.java b/packages/SystemUI/src/com/android/systemui/log/dagger/QSLog.java new file mode 100644 index 000000000000..dd5010cf39a8 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/log/dagger/QSLog.java @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2019 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.log.dagger; + +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import com.android.systemui.log.LogBuffer; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; + +import javax.inject.Qualifier; + +/** A {@link LogBuffer} for QS-related messages. */ +@Qualifier +@Documented +@Retention(RUNTIME) +public @interface QSLog { +} diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSHost.java b/packages/SystemUI/src/com/android/systemui/qs/QSHost.java index 84fa7004f363..3cf0718aa067 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSHost.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSHost.java @@ -18,6 +18,7 @@ import android.content.Context; import com.android.systemui.plugins.qs.QSTile; import com.android.systemui.qs.external.TileServices; +import com.android.systemui.qs.logging.QSLogger; import java.util.Collection; @@ -27,6 +28,7 @@ public interface QSHost { void forceCollapsePanels(); void openPanels(); Context getContext(); + QSLogger getQSLogger(); Collection<QSTile> getTiles(); void addCallback(Callback callback); void removeCallback(Callback callback); diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java index b3d96f8fc29f..53454d6afcd5 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java @@ -57,6 +57,7 @@ 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.statusbar.policy.BrightnessMirrorController; @@ -69,6 +70,7 @@ import java.io.PrintWriter; import java.util.ArrayList; import java.util.Collection; import java.util.List; +import java.util.stream.Collectors; import javax.inject.Inject; import javax.inject.Named; @@ -84,6 +86,7 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne protected final Context mContext; protected final ArrayList<TileRecord> mRecords = new ArrayList<>(); + private String mCachedSpecs = ""; protected final View mBrightnessView; private final H mHandler = new H(); private final MetricsLogger mMetricsLogger = Dependency.get(MetricsLogger.class); @@ -101,6 +104,7 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne private QSDetail.Callback mCallback; private BrightnessController mBrightnessController; private DumpController mDumpController; + private final QSLogger mQSLogger; protected QSTileHost mHost; protected QSSecurityFooter mFooter; @@ -140,23 +144,17 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne } }; - public QSPanel(Context context) { - this(context, null); - } - - public QSPanel(Context context, AttributeSet attrs) { - this(context, attrs, null); - } - - public QSPanel(Context context, AttributeSet attrs, DumpController dumpController) { - this(context, attrs, dumpController, Dependency.get(BroadcastDispatcher.class)); - } - @Inject - public QSPanel(@Named(VIEW_CONTEXT) Context context, AttributeSet attrs, - DumpController dumpController, BroadcastDispatcher broadcastDispatcher) { + public QSPanel( + @Named(VIEW_CONTEXT) Context context, + AttributeSet attrs, + DumpController dumpController, + BroadcastDispatcher broadcastDispatcher, + QSLogger qsLogger + ) { super(context, attrs); mContext = context; + mQSLogger = qsLogger; setOrientation(VERTICAL); @@ -166,6 +164,7 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne mTileLayout = (QSTileLayout) LayoutInflater.from(mContext).inflate( R.layout.qs_paged_tile_layout, this, false); + mQSLogger.logAllTilesChangeListening(mListening, getDumpableTag(), mCachedSpecs); mTileLayout.setListening(mListening); addView((View) mTileLayout); @@ -521,6 +520,7 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne public void setExpanded(boolean expanded) { if (mExpanded == expanded) return; + mQSLogger.logPanelExpanded(expanded, getDumpableTag()); mExpanded = expanded; if (!mExpanded && mTileLayout instanceof PagedTileLayout) { ((PagedTileLayout) mTileLayout).setCurrentItem(0, false); @@ -547,6 +547,7 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne if (mListening == listening) return; mListening = listening; if (mTileLayout != null) { + mQSLogger.logAllTilesChangeListening(listening, getDumpableTag(), mCachedSpecs); mTileLayout.setListening(listening); } if (mListening) { @@ -554,6 +555,12 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne } } + private String getTilesSpecs() { + return mRecords.stream() + .map(tileRecord -> tileRecord.tile.getTileSpec()) + .collect(Collectors.joining(",")); + } + public void setListening(boolean listening, boolean expanded) { setListening(listening && expanded); getFooter().setListening(listening); @@ -611,6 +618,7 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne record.tile.removeCallback(record.callback); } mRecords.clear(); + mCachedSpecs = ""; for (QSTile tile : tiles) { addTile(tile, collapsedView); } @@ -675,6 +683,7 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne r.tileView.init(r.tile); r.tile.refreshState(); mRecords.add(r); + mCachedSpecs = getTilesSpecs(); if (mTileLayout != null) { mTileLayout.addTile(r); diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java b/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java index 00e09f8d4725..73c42d4dae9a 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java @@ -43,6 +43,7 @@ import com.android.systemui.plugins.qs.QSTileView; import com.android.systemui.qs.external.CustomTile; import com.android.systemui.qs.external.TileLifecycleManager; import com.android.systemui.qs.external.TileServices; +import com.android.systemui.qs.logging.QSLogger; import com.android.systemui.qs.tileimpl.QSFactoryImpl; import com.android.systemui.shared.plugins.PluginManager; import com.android.systemui.statusbar.phone.AutoTileManager; @@ -82,6 +83,7 @@ public class QSTileHost implements QSHost, Tunable, PluginListener<QSFactory>, D private final PluginManager mPluginManager; private final DumpController mDumpController; private final BroadcastDispatcher mBroadcastDispatcher; + private final QSLogger mQSLogger; private final List<Callback> mCallbacks = new ArrayList<>(); private AutoTileManager mAutoTiles; @@ -101,12 +103,14 @@ public class QSTileHost implements QSHost, Tunable, PluginListener<QSFactory>, D Provider<AutoTileManager> autoTiles, DumpController dumpController, BroadcastDispatcher broadcastDispatcher, - Optional<StatusBar> statusBarOptional) { + Optional<StatusBar> statusBarOptional, + QSLogger qsLogger) { mIconController = iconController; mContext = context; mTunerService = tunerService; mPluginManager = pluginManager; mDumpController = dumpController; + mQSLogger = qsLogger; mBroadcastDispatcher = broadcastDispatcher; mServices = new TileServices(this, bgLooper, mBroadcastDispatcher); @@ -159,6 +163,10 @@ public class QSTileHost implements QSHost, Tunable, PluginListener<QSFactory>, D onTuningChanged(TILES_SETTING, value); } + public QSLogger getQSLogger() { + return mQSLogger; + } + @Override public void addCallback(Callback callback) { mCallbacks.add(callback); @@ -223,6 +231,7 @@ public class QSTileHost implements QSHost, Tunable, PluginListener<QSFactory>, D mTiles.entrySet().stream().filter(tile -> !tileSpecs.contains(tile.getKey())).forEach( tile -> { Log.d(TAG, "Destroying tile: " + tile.getKey()); + mQSLogger.logTileDestroyed(tile.getKey(), "Tile removed"); tile.getValue().destroy(); }); final LinkedHashMap<String, QSTile> newTiles = new LinkedHashMap<>(); @@ -237,9 +246,11 @@ public class QSTileHost implements QSHost, Tunable, PluginListener<QSFactory>, D tile.userSwitch(currentUser); } newTiles.put(tileSpec, tile); + mQSLogger.logTileAdded(tileSpec); } else { tile.destroy(); Log.d(TAG, "Destroying not available tile: " + tileSpec); + mQSLogger.logTileDestroyed(tileSpec, "Tile not available"); } } else { Log.d(TAG, "Creating tile: " + tileSpec); @@ -249,9 +260,11 @@ public class QSTileHost implements QSHost, Tunable, PluginListener<QSFactory>, D if (tile.isAvailable()) { tile.setTileSpec(tileSpec); newTiles.put(tileSpec, tile); + mQSLogger.logTileAdded(tileSpec); } else { tile.destroy(); Log.d(TAG, "Destroying not available tile: " + tileSpec); + mQSLogger.logTileDestroyed(tileSpec, "Tile not available"); } } } catch (Throwable t) { diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java index e9207016eb68..fda2f6a46f85 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java @@ -29,10 +29,12 @@ import android.widget.LinearLayout; import com.android.systemui.Dependency; import com.android.systemui.DumpController; import com.android.systemui.R; +import com.android.systemui.broadcast.BroadcastDispatcher; 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.tuner.TunerService; import com.android.systemui.tuner.TunerService.Tunable; import com.android.systemui.util.Utils; @@ -65,9 +67,14 @@ public class QuickQSPanel extends QSPanel { private QSTileLayout mRegularTileLayout; @Inject - public QuickQSPanel(@Named(VIEW_CONTEXT) Context context, AttributeSet attrs, - DumpController dumpController) { - super(context, attrs, dumpController); + public QuickQSPanel( + @Named(VIEW_CONTEXT) Context context, + AttributeSet attrs, + DumpController dumpController, + BroadcastDispatcher broadcastDispatcher, + QSLogger qsLogger + ) { + super(context, attrs, dumpController, broadcastDispatcher, qsLogger); if (mFooter != null) { removeView(mFooter.getView()); } 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 c118630fe91a..21a424c77a05 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java @@ -210,8 +210,10 @@ public class CustomTile extends QSTileImpl<State> implements TileChangeListener @Override public void handleSetListening(boolean listening) { + super.handleSetListening(listening); if (mListening == listening) return; mListening = listening; + try { if (listening) { updateDefaultTileAndIcon(); diff --git a/packages/SystemUI/src/com/android/systemui/qs/logging/QSLogger.kt b/packages/SystemUI/src/com/android/systemui/qs/logging/QSLogger.kt new file mode 100644 index 000000000000..ab8de263765e --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/qs/logging/QSLogger.kt @@ -0,0 +1,147 @@ +/* + * Copyright (C) 2019 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.logging + +import android.service.quicksettings.Tile +import com.android.systemui.log.LogBuffer +import com.android.systemui.log.LogLevel +import com.android.systemui.log.LogLevel.DEBUG +import com.android.systemui.log.LogLevel.VERBOSE +import com.android.systemui.log.LogMessage +import com.android.systemui.log.dagger.QSLog +import com.android.systemui.plugins.qs.QSTile +import com.android.systemui.statusbar.StatusBarState +import javax.inject.Inject + +private const val TAG = "QSLog" + +class QSLogger @Inject constructor( + @QSLog private val buffer: LogBuffer +) { + + fun logTileAdded(tileSpec: String) { + log(DEBUG, { + str1 = tileSpec + }, { + "[$str1] Tile added" + }) + } + + fun logTileDestroyed(tileSpec: String, reason: String) { + log(DEBUG, { + str1 = tileSpec + str2 = reason + }, { + "[$str1] Tile destroyed. Reason: $str2" + }) + } + + fun logTileChangeListening(tileSpec: String, listening: Boolean) { + log(VERBOSE, { + bool1 = listening + str1 = tileSpec + }, { + "[$str1] Tile listening=$bool1" + }) + } + + fun logAllTilesChangeListening(listening: Boolean, containerName: String, allSpecs: String) { + log(DEBUG, { + bool1 = listening + str1 = containerName + str2 = allSpecs + }, { + "Tiles listening=$bool1 in $str1. $str2" + }) + } + + fun logTileClick(tileSpec: String, statusBarState: Int, state: Int) { + log(DEBUG, { + str1 = tileSpec + int1 = statusBarState + str2 = StatusBarState.toShortString(statusBarState) + str3 = toStateString(state) + }, { + "[$str1] Tile clicked. StatusBarState=$str2. TileState=$str3" + }) + } + + fun logTileSecondaryClick(tileSpec: String, statusBarState: Int, state: Int) { + log(DEBUG, { + str1 = tileSpec + int1 = statusBarState + str2 = StatusBarState.toShortString(statusBarState) + str3 = toStateString(state) + }, { + "[$str1] Tile long clicked. StatusBarState=$str2. TileState=$str3" + }) + } + + fun logTileLongClick(tileSpec: String, statusBarState: Int, state: Int) { + log(DEBUG, { + str1 = tileSpec + int1 = statusBarState + str2 = StatusBarState.toShortString(statusBarState) + str3 = toStateString(state) + }, { + "[$str1] Tile long clicked. StatusBarState=$str2. TileState=$str3" + }) + } + + fun logTileUpdated(tileSpec: String, state: QSTile.State) { + log(VERBOSE, { + str1 = tileSpec + str2 = state.label.toString() + str3 = state.icon.toString() + int1 = state.state + if (state is QSTile.SignalState) { + bool1 = true + bool2 = state.activityIn + bool3 = state.activityOut + } + }, { + "[$str1] Tile updated. Label=$str2. State=$int1. Icon=$str3." + + if (bool1) " Activity in/out=$bool2/$bool3" else "" + }) + } + + fun logPanelExpanded(expanded: Boolean, containerName: String) { + log(DEBUG, { + str1 = containerName + bool1 = expanded + }, { + "$str1 expanded=$bool1" + }) + } + + private fun toStateString(state: Int): String { + return when (state) { + Tile.STATE_ACTIVE -> "active" + Tile.STATE_INACTIVE -> "inactive" + Tile.STATE_UNAVAILABLE -> "unavailable" + else -> "wrong state" + } + } + + private inline fun log( + logLevel: LogLevel, + initializer: LogMessage.() -> Unit, + noinline printer: LogMessage.() -> String + ) { + buffer.log(TAG, logLevel, initializer, printer) + } +}
\ No newline at end of file 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 e559694df375..60f6647743d2 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java @@ -27,6 +27,8 @@ import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.TYPE_ACTION; import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; +import android.annotation.CallSuper; +import android.annotation.NonNull; import android.app.ActivityManager; import android.content.Context; import android.content.Intent; @@ -41,7 +43,6 @@ import android.util.ArraySet; import android.util.Log; import android.util.SparseArray; -import androidx.annotation.NonNull; import androidx.lifecycle.Lifecycle; import androidx.lifecycle.LifecycleOwner; import androidx.lifecycle.LifecycleRegistry; @@ -63,6 +64,7 @@ import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.qs.PagedTileLayout.TilePage; import com.android.systemui.qs.QSHost; import com.android.systemui.qs.QuickStatusBarHeader; +import com.android.systemui.qs.logging.QSLogger; import com.android.systemui.qs.tiles.QSSettingsControllerKt; import com.android.systemui.qs.tiles.QSSettingsPanel; @@ -95,6 +97,7 @@ 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 QSLogger mQSLogger; private final ArrayList<Callback> mCallbacks = new ArrayList<>(); private final Object mStaleListener = new Object(); @@ -156,6 +159,7 @@ public abstract class QSTileImpl<TState extends State> implements QSTile, Lifecy mState = newTileState(); mTmpState = newTileState(); mQSSettingsPanelOption = QSSettingsControllerKt.getQSSettingsPanelOption(); + mQSLogger = host.getQSLogger(); } protected final void resetStates() { @@ -243,6 +247,7 @@ 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()))); + mQSLogger.logTileClick(mTileSpec, mStatusBarStateController.getState(), mState.state); mHandler.sendEmptyMessage(H.CLICK); } @@ -250,6 +255,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()))); + mQSLogger.logTileSecondaryClick(mTileSpec, mStatusBarStateController.getState(), + mState.state); mHandler.sendEmptyMessage(H.SECONDARY_CLICK); } @@ -257,6 +264,7 @@ 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()))); + mQSLogger.logTileLongClick(mTileSpec, mStatusBarStateController.getState(), mState.state); mHandler.sendEmptyMessage(H.LONG_CLICK); Prefs.putInt( @@ -359,6 +367,7 @@ public abstract class QSTileImpl<TState extends State> implements QSTile, Lifecy handleUpdateState(mTmpState, arg); final boolean changed = mTmpState.copyTo(mState); if (changed) { + mQSLogger.logTileUpdated(mTileSpec, mState); handleStateChanged(); } mHandler.removeMessages(H.STALE); @@ -445,9 +454,15 @@ public abstract class QSTileImpl<TState extends State> implements QSTile, Lifecy mIsFullQs = 0; } - protected abstract void handleSetListening(boolean listening); + @CallSuper + protected void handleSetListening(boolean listening) { + if (mTileSpec != null) { + mQSLogger.logTileChangeListening(mTileSpec, listening); + } + } protected void handleDestroy() { + mQSLogger.logTileDestroyed(mTileSpec, "Handle destroy"); if (mListeners.size() != 0) { handleSetListening(false); } @@ -592,6 +607,12 @@ public abstract class QSTileImpl<TState extends State> implements QSTile, Lifecy public Drawable getInvisibleDrawable(Context context) { return mInvisibleDrawable; } + + @Override + @NonNull + public String toString() { + return "DrawableIcon"; + } } public static class DrawableIconWithRes extends DrawableIcon { @@ -606,6 +627,12 @@ public abstract class QSTileImpl<TState extends State> implements QSTile, Lifecy public boolean equals(Object o) { return o instanceof DrawableIconWithRes && ((DrawableIconWithRes) o).mId == mId; } + + @Override + @NonNull + public String toString() { + return String.format("DrawableIconWithRes[resId=0x%08x]", mId); + } } public static class ResourceIcon extends Icon { @@ -642,6 +669,7 @@ public abstract class QSTileImpl<TState extends State> implements QSTile, Lifecy } @Override + @NonNull public String toString() { return String.format("ResourceIcon[resId=0x%08x]", mResId); } @@ -660,6 +688,12 @@ public abstract class QSTileImpl<TState extends State> implements QSTile, Lifecy // workaround: get a clean state for every new AVD return context.getDrawable(mAnimatedResId).getConstantState().newDrawable(); } + + @Override + @NonNull + public String toString() { + return String.format("AnimationIcon[resId=0x%08x]", mResId); + } } /** diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java index 5e297e21686b..b24fdbfc562f 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java @@ -130,6 +130,7 @@ public class AirplaneModeTile extends QSTileImpl<BooleanState> { } public void handleSetListening(boolean listening) { + super.handleSetListening(listening); if (mListening == listening) return; mListening = listening; if (listening) { diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java index d62f10d312d7..4449d483118b 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java @@ -74,6 +74,7 @@ public class BatterySaverTile extends QSTileImpl<BooleanState> implements @Override public void handleSetListening(boolean listening) { + super.handleSetListening(listening); mSetting.setListening(listening); } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java index 361b6c1b1260..cc7aaea9f38c 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java @@ -82,10 +82,6 @@ public class BluetoothTile extends QSTileImpl<BooleanState> { } @Override - public void handleSetListening(boolean listening) { - } - - @Override protected void handleClick() { // Secondary clicks are header clicks, just toggle. final boolean isEnabled = mState.value; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java index 58de0575fa75..4b53ae2c6379 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java @@ -97,6 +97,7 @@ public class CastTile extends QSTileImpl<BooleanState> { @Override public void handleSetListening(boolean listening) { + super.handleSetListening(listening); if (DEBUG) Log.d(TAG, "handleSetListening " + listening); if (!listening) { mController.setDiscovering(false); diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java index 436869d5ef88..bc03ca617dea 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java @@ -91,10 +91,6 @@ public class CellularTile extends QSTileImpl<SignalState> { } @Override - public void handleSetListening(boolean listening) { - } - - @Override public Intent getLongClickIntent() { if (getState().state == Tile.STATE_UNAVAILABLE) { return new Intent(Settings.ACTION_WIRELESS_SETTINGS); diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java index ecb4048b148d..9c0030d528e7 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java @@ -66,6 +66,7 @@ public class ColorInversionTile extends QSTileImpl<BooleanState> { @Override public void handleSetListening(boolean listening) { + super.handleSetListening(listening); mSetting.setListening(listening); } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java index 79996bcfa808..8ba60840a666 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java @@ -50,10 +50,6 @@ public class DataSaverTile extends QSTileImpl<BooleanState> implements } @Override - public void handleSetListening(boolean listening) { - } - - @Override public Intent getLongClickIntent() { return new Intent(Settings.ACTION_DATA_SAVER_SETTINGS); } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java index 9215da4cda9a..ebf45a66a23a 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java @@ -289,6 +289,7 @@ public class DndTile extends QSTileImpl<BooleanState> { @Override public void handleSetListening(boolean listening) { + super.handleSetListening(listening); if (mListening == listening) return; mListening = listening; if (mListening) { diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java index 792c36477962..27ccd7cab226 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java @@ -58,10 +58,6 @@ public class FlashlightTile extends QSTileImpl<BooleanState> implements } @Override - public void handleSetListening(boolean listening) { - } - - @Override protected void handleUserSwitch(int newUserId) { } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java index 91b3ae480af9..0c861573864d 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java @@ -69,6 +69,7 @@ public class HotspotTile extends QSTileImpl<BooleanState> { @Override public void handleSetListening(boolean listening) { + super.handleSetListening(listening); if (mListening == listening) return; mListening = listening; if (listening) { diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java index e617867eb10e..02f364bd3a7e 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java @@ -61,10 +61,6 @@ public class LocationTile extends QSTileImpl<BooleanState> { } @Override - public void handleSetListening(boolean listening) { - } - - @Override public Intent getLongClickIntent() { return new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS); } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/NfcTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/NfcTile.java index f0140ba0f67c..4bee075ac63b 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/NfcTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/NfcTile.java @@ -57,6 +57,7 @@ public class NfcTile extends QSTileImpl<BooleanState> { @Override public void handleSetListening(boolean listening) { + super.handleSetListening(listening); mListening = listening; if (mListening) { mBroadcastDispatcher.registerReceiver(mNfcReceiver, diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java index 241b375ffeaa..bc1c1e12203e 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java @@ -190,6 +190,7 @@ public class NightDisplayTile extends QSTileImpl<BooleanState> implements @Override protected void handleSetListening(boolean listening) { + super.handleSetListening(listening); mIsListening = listening; if (listening) { mListener.setCallback(this); diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java index 7ca1e44c93cd..2557226d07bd 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java @@ -51,9 +51,6 @@ public class RotationLockTile extends QSTileImpl<BooleanState> { return new BooleanState(); } - public void handleSetListening(boolean listening) { - } - @Override public Intent getLongClickIntent() { return new Intent(Settings.ACTION_DISPLAY_SETTINGS); diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java index 596c3b9af8c2..88a30a166c07 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java @@ -105,10 +105,6 @@ public class ScreenRecordTile extends QSTileImpl<QSTile.BooleanState> { } @Override - protected void handleSetListening(boolean listening) { - } - - @Override public CharSequence getTileLabel() { return mContext.getString(R.string.quick_settings_screen_record_label); } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/UiModeNightTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/UiModeNightTile.java index 8f1769b70d6c..b90ca01df481 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/UiModeNightTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/UiModeNightTile.java @@ -32,10 +32,11 @@ import com.android.systemui.qs.tileimpl.QSTileImpl; import com.android.systemui.statusbar.policy.BatteryController; import com.android.systemui.statusbar.policy.ConfigurationController; -import javax.inject.Inject; import java.time.LocalTime; import java.time.format.DateTimeFormatter; +import javax.inject.Inject; + /** * Quick Settings tile for: Night Mode / Dark Theme / Dark Mode. * @@ -141,10 +142,6 @@ public class UiModeNightTile extends QSTileImpl<QSTile.BooleanState> implements } @Override - protected void handleSetListening(boolean listening) { - } - - @Override public CharSequence getTileLabel() { return getState().label; } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserTile.java index 7c1ffde8f00a..aab30d499e08 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserTile.java @@ -73,10 +73,6 @@ public class UserTile extends QSTileImpl<State> implements UserInfoController.On } @Override - public void handleSetListening(boolean listening) { - } - - @Override public CharSequence getTileLabel() { return getState().label; } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java index 6e8dcf36bacc..39bfd5a8b6db 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java @@ -84,10 +84,6 @@ public class WifiTile extends QSTileImpl<SignalState> { } @Override - public void handleSetListening(boolean listening) { - } - - @Override public void setDetailListening(boolean listening) { if (listening) { mWifiController.addAccessPointCallback(mDetailAdapter); diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java index e54ee51fb9d4..318c0c4660cb 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java @@ -50,10 +50,6 @@ public class WorkModeTile extends QSTileImpl<BooleanState> implements } @Override - public void handleSetListening(boolean listening) { - } - - @Override public Intent getLongClickIntent() { return new Intent(Settings.ACTION_MANAGED_PROFILE_SETTINGS); } diff --git a/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java b/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java index 2c7c52e1c51f..2e0c035b8547 100644 --- a/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java +++ b/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java @@ -434,6 +434,7 @@ public class GarbageMonitor implements Dumpable { @Override public void handleSetListening(boolean listening) { + super.handleSetListening(listening); if (gm != null) gm.setTile(listening ? this : null); final ActivityManager am = mContext.getSystemService(ActivityManager.class); 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 b7e9f074ad9a..d66845837bb7 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java @@ -42,6 +42,7 @@ import com.android.systemui.SystemUIFactory; import com.android.systemui.SysuiBaseFragmentTest; import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.plugins.statusbar.StatusBarStateController; +import com.android.systemui.qs.logging.QSLogger; import com.android.systemui.qs.tileimpl.QSFactoryImpl; import com.android.systemui.shared.plugins.PluginManager; import com.android.systemui.statusbar.CommandQueue; @@ -104,7 +105,8 @@ public class QSFragmentTest extends SysuiBaseFragmentTest { mock(QSFactoryImpl.class), new Handler(), Looper.myLooper(), mock(PluginManager.class), mock(TunerService.class), () -> mock(AutoTileManager.class), mock(DumpController.class), - mock(BroadcastDispatcher.class), Optional.of(mock(StatusBar.class))); + mock(BroadcastDispatcher.class), Optional.of(mock(StatusBar.class)), + mock(QSLogger.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 38cdee4c090b..b126d3643438 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java @@ -35,9 +35,12 @@ import androidx.test.filters.SmallTest; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; +import com.android.systemui.DumpController; import com.android.systemui.SysuiTestCase; +import com.android.systemui.broadcast.BroadcastDispatcher; 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 org.junit.Before; @@ -65,6 +68,12 @@ public class QSPanelTest extends SysuiTestCase { private QSCustomizer mCustomizer; @Mock private QSTileImpl dndTile; + @Mock + private BroadcastDispatcher mBroadcastDispatcher; + @Mock + private DumpController mDumpController; + @Mock + private QSLogger mQSLogger; private ViewGroup mParentView; @Mock private QSDetail.Callback mCallback; @@ -78,7 +87,8 @@ public class QSPanelTest extends SysuiTestCase { mTestableLooper = TestableLooper.get(this); mTestableLooper.runWithLooper(() -> { mMetricsLogger = mDependency.injectMockDependency(MetricsLogger.class); - mQsPanel = new QSPanel(mContext, null); + mQsPanel = new QSPanel(mContext, null, mDumpController, mBroadcastDispatcher, + mQSLogger); // Provides a parent with non-zero size for QSPanel mParentView = new FrameLayout(mContext); mParentView.addView(mQsPanel); @@ -97,8 +107,10 @@ public class QSPanelTest extends SysuiTestCase { public void testSetExpanded_Metrics() { mQsPanel.setExpanded(true); verify(mMetricsLogger).visibility(eq(MetricsEvent.QS_PANEL), eq(true)); + verify(mQSLogger).logPanelExpanded(true, mQsPanel.getDumpableTag()); mQsPanel.setExpanded(false); verify(mMetricsLogger).visibility(eq(MetricsEvent.QS_PANEL), eq(false)); + verify(mQSLogger).logPanelExpanded(false, mQsPanel.getDumpableTag()); } @Test @@ -110,6 +122,14 @@ public class QSPanelTest extends SysuiTestCase { verify(mCallback).onShowingDetail(any(), anyInt(), anyInt()); } + @Test + public void setListening() { + when(dndTile.getTileSpec()).thenReturn("dnd"); + + mQsPanel.setListening(true); + verify(mQSLogger).logAllTilesChangeListening(true, mQsPanel.getDumpableTag(), "dnd"); + } + /* @Test public void testOpenDetailsWithNullParameter_NoException() { mTestableLooper.processAllMessages(); 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 34111e2cba9b..d0c32ce92c55 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSTileHostTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSTileHostTest.java @@ -23,6 +23,7 @@ import static junit.framework.TestCase.assertFalse; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.app.ActivityManager; @@ -45,6 +46,7 @@ import com.android.systemui.broadcast.BroadcastDispatcher; 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; @@ -95,6 +97,8 @@ public class QSTileHostTest extends SysuiTestCase { @Mock private StatusBar mStatusBar; @Mock + private QSLogger mQSLogger; + @Mock private CustomTile mCustomTile; private Handler mHandler; @@ -108,7 +112,7 @@ public class QSTileHostTest extends SysuiTestCase { mHandler = new Handler(mLooper.getLooper()); mQSTileHost = new TestQSTileHost(mContext, mIconController, mDefaultFactory, mHandler, mLooper.getLooper(), mPluginManager, mTunerService, mAutoTiles, mDumpController, - mBroadcastDispatcher, mStatusBar); + mBroadcastDispatcher, mStatusBar, mQSLogger); setUpTileFactory(); Settings.Secure.putStringForUser(mContext.getContentResolver(), QSTileHost.TILES_SETTING, "", ActivityManager.getCurrentUser()); @@ -187,6 +191,7 @@ public class QSTileHostTest extends SysuiTestCase { assertEquals(1, mQSTileHost.getTiles().size()); QSTile element = CollectionUtils.firstOrNull(mQSTileHost.getTiles()); assertTrue(element instanceof TestTile1); + verify(mQSLogger).logTileAdded("spec1"); } @Test @@ -200,6 +205,9 @@ public class QSTileHostTest extends SysuiTestCase { QSTile[] elements = mQSTileHost.getTiles().toArray(new QSTile[0]); assertTrue(elements[0] instanceof TestTile1); assertTrue(elements[1] instanceof TestTile2); + + verify(mQSLogger).logTileAdded("spec1"); + verify(mQSLogger).logTileAdded("spec2"); } @Test @@ -210,6 +218,8 @@ public class QSTileHostTest extends SysuiTestCase { mQSTileHost.onTuningChanged(QSTileHost.TILES_SETTING, "default"); assertEquals(1, mQSTileHost.getTiles().size()); assertEquals(mCustomTile, CollectionUtils.firstOrNull(mQSTileHost.getTiles())); + + verify(mQSLogger).logTileAdded(CUSTOM_TILE_SPEC); } private static class TestQSTileHost extends QSTileHost { @@ -217,10 +227,10 @@ public class QSTileHostTest extends SysuiTestCase { QSFactoryImpl defaultFactory, Handler mainHandler, Looper bgLooper, PluginManager pluginManager, TunerService tunerService, Provider<AutoTileManager> autoTiles, DumpController dumpController, - BroadcastDispatcher broadcastDispatcher, StatusBar statusBar) { + BroadcastDispatcher broadcastDispatcher, StatusBar statusBar, QSLogger qsLogger) { super(context, iconController, defaultFactory, mainHandler, bgLooper, pluginManager, tunerService, autoTiles, dumpController, broadcastDispatcher, - Optional.of(statusBar)); + Optional.of(statusBar), qsLogger); } @Override @@ -280,9 +290,6 @@ public class QSTileHostTest extends SysuiTestCase { } @Override - protected void handleSetListening(boolean listening) {} - - @Override public CharSequence getTileLabel() { return null; } 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 2737b19e62ea..ab6b304033d0 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 @@ -34,6 +34,7 @@ import com.android.systemui.DumpController; import com.android.systemui.SysuiTestCase; import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.qs.QSTileHost; +import com.android.systemui.qs.logging.QSLogger; import com.android.systemui.qs.tileimpl.QSFactoryImpl; import com.android.systemui.shared.plugins.PluginManager; import com.android.systemui.statusbar.phone.AutoTileManager; @@ -78,6 +79,8 @@ public class TileServicesTest extends SysuiTestCase { private DumpController mDumpController; @Mock private StatusBar mStatusBar; + @Mock + private QSLogger mQSLogger; @Before public void setUp() throws Exception { @@ -94,7 +97,8 @@ public class TileServicesTest extends SysuiTestCase { () -> mAutoTileManager, mDumpController, mBroadcastDispatcher, - Optional.of(mStatusBar)); + Optional.of(mStatusBar), + mQSLogger); 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 6bd24b954bda..4fada336fb94 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 @@ -25,6 +25,7 @@ import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.TYPE_A import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Matchers.argThat; import static org.mockito.Mockito.clearInvocations; @@ -38,6 +39,7 @@ import static java.lang.Thread.sleep; import android.content.Intent; import android.metrics.LogMaker; +import android.service.quicksettings.Tile; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.testing.TestableLooper.RunWithLooper; @@ -52,6 +54,7 @@ import com.android.systemui.plugins.qs.QSTile; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.qs.QSHost; import com.android.systemui.qs.QSTileHost; +import com.android.systemui.qs.logging.QSLogger; import com.android.systemui.statusbar.StatusBarState; import org.junit.Before; @@ -61,6 +64,7 @@ import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.ArgumentMatcher; import org.mockito.Captor; +import org.mockito.Mock; import org.mockito.MockitoAnnotations; @RunWith(AndroidTestingRunner.class) @@ -69,6 +73,11 @@ import org.mockito.MockitoAnnotations; public class QSTileImplTest extends SysuiTestCase { public static final int POSITION = 14; + private static final String SPEC = "spec"; + + @Mock + private QSLogger mQsLogger; + private TestableLooper mTestableLooper; private TileImpl mTile; private QSTileHost mHost; @@ -81,7 +90,6 @@ public class QSTileImplTest extends SysuiTestCase { @Before public void setup() throws Exception { MockitoAnnotations.initMocks(this); - String spec = "spec"; mTestableLooper = TestableLooper.get(this); mDependency.injectTestDependency(Dependency.BG_LOOPER, mTestableLooper.getLooper()); mDependency.injectMockDependency(ActivityStarter.class); @@ -89,12 +97,13 @@ public class QSTileImplTest extends SysuiTestCase { mStatusBarStateController = mDependency.injectMockDependency(StatusBarStateController.class); mHost = mock(QSTileHost.class); - when(mHost.indexOf(spec)).thenReturn(POSITION); + when(mHost.indexOf(SPEC)).thenReturn(POSITION); when(mHost.getContext()).thenReturn(mContext.getBaseContext()); + when(mHost.getQSLogger()).thenReturn(mQsLogger); mTile = spy(new TileImpl(mHost)); mTile.mHandler = mTile.new H(mTestableLooper.getLooper()); - mTile.setTileSpec(spec); + mTile.setTileSpec(SPEC); } @Test @@ -104,6 +113,14 @@ public class QSTileImplTest extends SysuiTestCase { } @Test + public void testClick_log() { + when(mStatusBarStateController.getState()).thenReturn(StatusBarState.SHADE); + + mTile.click(); + verify(mQsLogger).logTileClick(SPEC, StatusBarState.SHADE, Tile.STATE_ACTIVE); + } + + @Test public void testClick_Metrics_Status_Bar_Status() { when(mStatusBarStateController.getState()).thenReturn(StatusBarState.SHADE); mTile.click(); @@ -119,6 +136,14 @@ public class QSTileImplTest extends SysuiTestCase { } @Test + public void testSecondaryClick_log() { + when(mStatusBarStateController.getState()).thenReturn(StatusBarState.SHADE); + + mTile.secondaryClick(); + verify(mQsLogger).logTileSecondaryClick(SPEC, StatusBarState.SHADE, Tile.STATE_ACTIVE); + } + + @Test public void testSecondaryClick_Metrics_Status_Bar_Status() { when(mStatusBarStateController.getState()).thenReturn(StatusBarState.KEYGUARD); mTile.secondaryClick(); @@ -133,6 +158,15 @@ public class QSTileImplTest extends SysuiTestCase { verify(mMetricsLogger).write(argThat(new TileLogMatcher(ACTION_QS_LONG_PRESS))); } + + @Test + public void testLongClick_log() { + when(mStatusBarStateController.getState()).thenReturn(StatusBarState.SHADE); + + mTile.longClick(); + verify(mQsLogger).logTileLongClick(SPEC, StatusBarState.SHADE, Tile.STATE_ACTIVE); + } + @Test public void testLongClick_Metrics_Status_Bar_Status() { when(mStatusBarStateController.getState()).thenReturn(StatusBarState.SHADE_LOCKED); @@ -200,6 +234,21 @@ public class QSTileImplTest extends SysuiTestCase { verify(mTile, never()).handleStale(); } + @Test + public void testHandleDestroy_log() { + mTile.handleDestroy(); + verify(mQsLogger).logTileDestroyed(eq(SPEC), anyString()); + } + + @Test + public void testListening_log() { + mTile.handleSetListening(true); + verify(mQsLogger).logTileChangeListening(SPEC, true); + + mTile.handleSetListening(false); + verify(mQsLogger).logTileChangeListening(SPEC, false); + } + private class TileLogMatcher implements ArgumentMatcher<LogMaker> { private final int mCategory; @@ -236,6 +285,7 @@ public class QSTileImplTest extends SysuiTestCase { private static class TileImpl extends QSTileImpl<QSTile.BooleanState> { protected TileImpl(QSHost host) { super(host); + getState().state = Tile.STATE_ACTIVE; } @Override @@ -264,11 +314,6 @@ public class QSTileImplTest extends SysuiTestCase { } @Override - protected void handleSetListening(boolean listening) { - - } - - @Override public CharSequence getTileLabel() { return null; } |