OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 package org.chromium.chrome.browser.compositor.bottombar.contextualsearch; | 5 package org.chromium.chrome.browser.compositor.bottombar.contextualsearch; |
6 | 6 |
7 import org.chromium.chrome.browser.compositor.bottombar.OverlayPanel.PanelState; | 7 import org.chromium.chrome.browser.compositor.bottombar.OverlayPanel.PanelState; |
8 import org.chromium.chrome.browser.compositor.bottombar.OverlayPanel.StateChange
Reason; | 8 import org.chromium.chrome.browser.compositor.bottombar.OverlayPanel.StateChange
Reason; |
9 import org.chromium.chrome.browser.contextualsearch.ContextualSearchHeuristics; | 9 import org.chromium.chrome.browser.contextualsearch.ContextualSearchHeuristics; |
10 import org.chromium.chrome.browser.contextualsearch.ContextualSearchRankerLogger
; | 10 import org.chromium.chrome.browser.contextualsearch.ContextualSearchRankerLogger
; |
11 import org.chromium.chrome.browser.contextualsearch.ContextualSearchRankerLogger
Impl; | |
12 import org.chromium.chrome.browser.contextualsearch.ContextualSearchUma; | 11 import org.chromium.chrome.browser.contextualsearch.ContextualSearchUma; |
13 import org.chromium.chrome.browser.contextualsearch.QuickActionCategory; | 12 import org.chromium.chrome.browser.contextualsearch.QuickActionCategory; |
14 | 13 |
15 import java.net.URL; | |
16 | |
17 /** | 14 /** |
18 * This class is responsible for all the logging related to Contextual Search. | 15 * This class is responsible for all the logging related to Contextual Search. |
19 */ | 16 */ |
20 public class ContextualSearchPanelMetrics { | 17 public class ContextualSearchPanelMetrics { |
21 private static final int MILLISECONDS_TO_NANOSECONDS = 1000000; | 18 private static final int MILLISECONDS_TO_NANOSECONDS = 1000000; |
22 | 19 |
23 // The Ranker logger to use to write Tap Suppression Ranker logs to UMA. | |
24 private final ContextualSearchRankerLogger mTapSuppressionRankerLogger; | |
25 | |
26 // Flags for logging. | 20 // Flags for logging. |
27 private boolean mDidSearchInvolvePromo; | 21 private boolean mDidSearchInvolvePromo; |
28 private boolean mWasSearchContentViewSeen; | 22 private boolean mWasSearchContentViewSeen; |
29 private boolean mIsPromoActive; | 23 private boolean mIsPromoActive; |
30 private boolean mHasExpanded; | 24 private boolean mHasExpanded; |
31 private boolean mHasMaximized; | 25 private boolean mHasMaximized; |
32 private boolean mHasExitedPeeking; | 26 private boolean mHasExitedPeeking; |
33 private boolean mHasExitedExpanded; | 27 private boolean mHasExitedExpanded; |
34 private boolean mHasExitedMaximized; | 28 private boolean mHasExitedMaximized; |
35 private boolean mIsSerpNavigation; | 29 private boolean mIsSerpNavigation; |
(...skipping 15 matching lines...) Expand all Loading... |
51 // Time when a search request was started. Reset by chained searches. | 45 // Time when a search request was started. Reset by chained searches. |
52 // Used to log the time it takes for a Search Result to become available. | 46 // Used to log the time it takes for a Search Result to become available. |
53 private long mSearchRequestStartTimeNs; | 47 private long mSearchRequestStartTimeNs; |
54 // Time when the panel was opened beyond peeked. Reset when the panel is clo
sed. | 48 // Time when the panel was opened beyond peeked. Reset when the panel is clo
sed. |
55 // Used to log how long the panel was open. | 49 // Used to log how long the panel was open. |
56 private long mPanelOpenedBeyondPeekTimeNs; | 50 private long mPanelOpenedBeyondPeekTimeNs; |
57 // The current set of heuristics that should be logged with results seen whe
n the panel closes. | 51 // The current set of heuristics that should be logged with results seen whe
n the panel closes. |
58 private ContextualSearchHeuristics mResultsSeenExperiments; | 52 private ContextualSearchHeuristics mResultsSeenExperiments; |
59 // The current set of heuristics to be logged through ranker with results se
en when the panel | 53 // The current set of heuristics to be logged through ranker with results se
en when the panel |
60 // closes. | 54 // closes. |
61 private ContextualSearchHeuristics mRankerLogExperiments; | 55 private ContextualSearchRankerLogger mRankerLogger; |
62 | |
63 /** | |
64 * Constructs an object to track metrics for the Contextual Search Overlay P
anel. | |
65 */ | |
66 ContextualSearchPanelMetrics() { | |
67 mTapSuppressionRankerLogger = new ContextualSearchRankerLoggerImpl(); | |
68 } | |
69 | 56 |
70 /** | 57 /** |
71 * Log information when the panel's state has changed. | 58 * Log information when the panel's state has changed. |
72 * @param fromState The state the panel is transitioning from. | 59 * @param fromState The state the panel is transitioning from. |
73 * @param toState The state that the panel is transitioning to. | 60 * @param toState The state that the panel is transitioning to. |
74 * @param reason The reason for the state change. | 61 * @param reason The reason for the state change. |
75 */ | 62 */ |
76 public void onPanelStateChanged(PanelState fromState, PanelState toState, | 63 public void onPanelStateChanged(PanelState fromState, PanelState toState, |
77 StateChangeReason reason) { | 64 StateChangeReason reason) { |
78 // Note: the logging within this function includes the promo, unless spe
cifically | 65 // Note: the logging within this function includes the promo, unless spe
cifically |
(...skipping 11 matching lines...) Expand all Loading... |
90 boolean isContentVisible = | 77 boolean isContentVisible = |
91 toState == PanelState.MAXIMIZED || toState == PanelState.EXPANDE
D; | 78 toState == PanelState.MAXIMIZED || toState == PanelState.EXPANDE
D; |
92 boolean isExitingPanelOpenedBeyondPeeked = mWasPanelOpenedBeyondPeek &&
!isContentVisible; | 79 boolean isExitingPanelOpenedBeyondPeeked = mWasPanelOpenedBeyondPeek &&
!isContentVisible; |
93 | 80 |
94 if (toState == PanelState.CLOSED && mPanelTriggerTimeFromTapNs != 0 | 81 if (toState == PanelState.CLOSED && mPanelTriggerTimeFromTapNs != 0 |
95 && reason == StateChangeReason.BASE_PAGE_SCROLL) { | 82 && reason == StateChangeReason.BASE_PAGE_SCROLL) { |
96 long durationMs = | 83 long durationMs = |
97 (System.nanoTime() - mPanelTriggerTimeFromTapNs) / MILLISECO
NDS_TO_NANOSECONDS; | 84 (System.nanoTime() - mPanelTriggerTimeFromTapNs) / MILLISECO
NDS_TO_NANOSECONDS; |
98 ContextualSearchUma.logDurationBetweenTriggerAndScroll( | 85 ContextualSearchUma.logDurationBetweenTriggerAndScroll( |
99 durationMs, mWasSearchContentViewSeen); | 86 durationMs, mWasSearchContentViewSeen); |
100 mTapSuppressionRankerLogger.log( | |
101 ContextualSearchRankerLogger.Feature.DURATION_BEFORE_SCROLL_
MS, durationMs); | |
102 } | 87 } |
103 | 88 |
104 if (isEndingSearch) { | 89 if (isEndingSearch) { |
105 long durationMs = (System.nanoTime() - mFirstPeekTimeNs) / MILLISECO
NDS_TO_NANOSECONDS; | 90 long durationMs = (System.nanoTime() - mFirstPeekTimeNs) / MILLISECO
NDS_TO_NANOSECONDS; |
106 ContextualSearchUma.logPanelViewDurationAction(durationMs); | 91 ContextualSearchUma.logPanelViewDurationAction(durationMs); |
107 if (!mDidSearchInvolvePromo) { | 92 if (!mDidSearchInvolvePromo) { |
108 // Measure duration only when the promo is not involved. | 93 // Measure duration only when the promo is not involved. |
109 ContextualSearchUma.logDuration(mWasSearchContentViewSeen, isCha
ined, durationMs); | 94 ContextualSearchUma.logDuration(mWasSearchContentViewSeen, isCha
ined, durationMs); |
110 } | 95 } |
111 if (mIsPromoActive) { | 96 if (mIsPromoActive) { |
112 // The user is exiting still in the promo, without choosing an o
ption. | 97 // The user is exiting still in the promo, without choosing an o
ption. |
113 ContextualSearchUma.logPromoSeen(mWasSearchContentViewSeen, mWas
ActivatedByTap); | 98 ContextualSearchUma.logPromoSeen(mWasSearchContentViewSeen, mWas
ActivatedByTap); |
114 } else { | 99 } else { |
115 ContextualSearchUma.logResultsSeen(mWasSearchContentViewSeen, mW
asActivatedByTap); | 100 ContextualSearchUma.logResultsSeen(mWasSearchContentViewSeen, mW
asActivatedByTap); |
116 } | 101 } |
117 | 102 |
118 if (mWasContextualCardsDataShown) { | 103 if (mWasContextualCardsDataShown) { |
119 ContextualSearchUma.logContextualCardsResultsSeen(mWasSearchCont
entViewSeen); | 104 ContextualSearchUma.logContextualCardsResultsSeen(mWasSearchCont
entViewSeen); |
120 } | 105 } |
121 if (mWasQuickActionShown) { | 106 if (mWasQuickActionShown) { |
122 ContextualSearchUma.logQuickActionResultsSeen(mWasSearchContentV
iewSeen, | 107 ContextualSearchUma.logQuickActionResultsSeen(mWasSearchContentV
iewSeen, |
123 mQuickActionCategory); | 108 mQuickActionCategory); |
124 ContextualSearchUma.logQuickActionClicked(mWasQuickActionClicked
, | 109 ContextualSearchUma.logQuickActionClicked(mWasQuickActionClicked
, |
125 mQuickActionCategory); | 110 mQuickActionCategory); |
126 mTapSuppressionRankerLogger.logOutcome( | 111 if (mRankerLogger != null) { |
127 ContextualSearchRankerLogger.Feature.OUTCOME_WAS_QUICK_A
CTION_CLICKED, | 112 mRankerLogger.logOutcome( |
128 mWasQuickActionClicked); | 113 ContextualSearchRankerLogger.Feature.OUTCOME_WAS_QUI
CK_ACTION_CLICKED, |
| 114 mWasQuickActionClicked); |
| 115 } |
129 } | 116 } |
130 | 117 |
131 if (mResultsSeenExperiments != null) { | 118 if (mResultsSeenExperiments != null) { |
132 mResultsSeenExperiments.logResultsSeen( | 119 mResultsSeenExperiments.logResultsSeen( |
133 mWasSearchContentViewSeen, mWasActivatedByTap); | 120 mWasSearchContentViewSeen, mWasActivatedByTap); |
| 121 if (mRankerLogger != null) { |
| 122 mResultsSeenExperiments.logRankerTapSuppressionOutcome(mRank
erLogger); |
| 123 } |
134 mResultsSeenExperiments = null; | 124 mResultsSeenExperiments = null; |
135 } | 125 } |
136 | 126 |
137 if (mWasActivatedByTap) { | 127 if (mWasActivatedByTap) { |
138 boolean wasAnySuppressionHeuristicSatisfied = mWasAnyHeuristicSa
tisfiedOnPanelShow; | 128 boolean wasAnySuppressionHeuristicSatisfied = mWasAnyHeuristicSa
tisfiedOnPanelShow; |
139 ContextualSearchUma.logAnyTapSuppressionHeuristicSatisfied( | 129 ContextualSearchUma.logAnyTapSuppressionHeuristicSatisfied( |
140 mWasSearchContentViewSeen, wasAnySuppressionHeuristicSat
isfied); | 130 mWasSearchContentViewSeen, wasAnySuppressionHeuristicSat
isfied); |
141 // Log all the experiments to the Ranker logger. | 131 // Update The Ranker logger. |
142 if (mRankerLogExperiments != null) { | 132 if (mRankerLogger != null) { |
143 mTapSuppressionRankerLogger.logOutcome( | 133 // Tell Ranker about the primary outcome. |
| 134 mRankerLogger.logOutcome( |
144 ContextualSearchRankerLogger.Feature.OUTCOME_WAS_PAN
EL_OPENED, | 135 ContextualSearchRankerLogger.Feature.OUTCOME_WAS_PAN
EL_OPENED, |
145 mWasSearchContentViewSeen); | 136 mWasSearchContentViewSeen); |
146 mRankerLogExperiments.logRankerTapSuppression(mTapSuppressio
nRankerLogger); | 137 // TODO(donnd): UMA-Log the Ranker inference signal once we'
re running a model. |
147 mRankerLogExperiments = null; | |
148 } | 138 } |
149 // Reset writing to Ranker so whatever interactions occurred are
recorded as a | |
150 // complete record. | |
151 mTapSuppressionRankerLogger.writeLogAndReset(); | |
152 | |
153 ContextualSearchUma.logSelectionLengthResultsSeen( | 139 ContextualSearchUma.logSelectionLengthResultsSeen( |
154 mWasSearchContentViewSeen, mSelectionLength); | 140 mWasSearchContentViewSeen, mSelectionLength); |
155 } | 141 } |
| 142 |
| 143 // Reset writing to Ranker so whatever interactions occurred are rec
orded as a |
| 144 // complete record. |
| 145 if (mRankerLogger != null) mRankerLogger.writeLogAndReset(); |
| 146 mRankerLogger = null; |
156 } | 147 } |
157 | 148 |
158 if (isExitingPanelOpenedBeyondPeeked) { | 149 if (isExitingPanelOpenedBeyondPeeked) { |
159 assert mPanelOpenedBeyondPeekTimeNs != 0; | 150 assert mPanelOpenedBeyondPeekTimeNs != 0; |
160 long durationPanelOpen = (System.nanoTime() - mPanelOpenedBeyondPeek
TimeNs) | 151 long durationPanelOpen = (System.nanoTime() - mPanelOpenedBeyondPeek
TimeNs) |
161 / MILLISECONDS_TO_NANOSECONDS; | 152 / MILLISECONDS_TO_NANOSECONDS; |
162 ContextualSearchUma.logPanelOpenDuration(durationPanelOpen); | 153 ContextualSearchUma.logPanelOpenDuration(durationPanelOpen); |
163 mPanelOpenedBeyondPeekTimeNs = 0; | 154 mPanelOpenedBeyondPeekTimeNs = 0; |
164 mWasPanelOpenedBeyondPeek = false; | 155 mWasPanelOpenedBeyondPeek = false; |
165 } | 156 } |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
322 | 313 |
323 /** | 314 /** |
324 * Sets the experiments to log with results seen. | 315 * Sets the experiments to log with results seen. |
325 * @param resultsSeenExperiments The experiments to log when the panel resul
ts are known. | 316 * @param resultsSeenExperiments The experiments to log when the panel resul
ts are known. |
326 */ | 317 */ |
327 public void setResultsSeenExperiments(ContextualSearchHeuristics resultsSeen
Experiments) { | 318 public void setResultsSeenExperiments(ContextualSearchHeuristics resultsSeen
Experiments) { |
328 mResultsSeenExperiments = resultsSeenExperiments; | 319 mResultsSeenExperiments = resultsSeenExperiments; |
329 } | 320 } |
330 | 321 |
331 /** | 322 /** |
332 * Sets the experiments to log through Ranker with results seen. | 323 * Sets up logging through Ranker for outcomes. |
333 * @param rankerLogExperiments The experiments to log through Ranker when th
e panel results | 324 * @param rankerLogger The {@link ContextualSearchRankerLogger} currently be
ing used to measure |
334 * are known. | 325 * or suppress the UI by Ranker. |
335 * @param basePageUrl The URL of the base page to log along with Ranker data
. | |
336 */ | 326 */ |
337 public void setRankerLogExperiments( | 327 public void setRankerLogger(ContextualSearchRankerLogger rankerLogger) { |
338 ContextualSearchHeuristics rankerLogExperiments, URL basePageUrl) { | 328 mRankerLogger = rankerLogger; |
339 mRankerLogExperiments = rankerLogExperiments; | |
340 mTapSuppressionRankerLogger.setupLoggingForPage(basePageUrl); | |
341 } | 329 } |
342 | 330 |
343 /** | 331 /** |
344 * Determine whether a new contextual search is starting. | 332 * Determine whether a new contextual search is starting. |
345 * @param toState The contextual search state that will be transitioned to. | 333 * @param toState The contextual search state that will be transitioned to. |
346 * @param reason The reason for the search state transition. | 334 * @param reason The reason for the search state transition. |
347 * @return Whether a new contextual search is starting. | 335 * @return Whether a new contextual search is starting. |
348 */ | 336 */ |
349 private boolean isStartingNewContextualSearch(PanelState toState, StateChang
eReason reason) { | 337 private boolean isStartingNewContextualSearch(PanelState toState, StateChang
eReason reason) { |
350 return toState == PanelState.PEEKED | 338 return toState == PanelState.PEEKED |
(...skipping 16 matching lines...) Expand all Loading... |
367 | 355 |
368 /** | 356 /** |
369 * @param fromState The state the panel is transitioning from. | 357 * @param fromState The state the panel is transitioning from. |
370 * @return Whether there is an ongoing contextual search. | 358 * @return Whether there is an ongoing contextual search. |
371 */ | 359 */ |
372 private boolean isOngoingContextualSearch(PanelState fromState) { | 360 private boolean isOngoingContextualSearch(PanelState fromState) { |
373 return fromState != PanelState.UNDEFINED && fromState != PanelState.CLOS
ED; | 361 return fromState != PanelState.UNDEFINED && fromState != PanelState.CLOS
ED; |
374 } | 362 } |
375 } | 363 } |
376 | 364 |
OLD | NEW |