OLD | NEW |
---|---|
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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.contextualsearch; | 5 package org.chromium.chrome.browser.contextualsearch; |
6 | 6 |
7 import org.chromium.base.Log; | |
8 | |
9 import java.net.URL; | 7 import java.net.URL; |
8 import java.util.HashMap; | |
9 import java.util.Map; | |
10 | 10 |
11 /** | 11 /** |
12 * Implements the UMA logging for Ranker that's used for Contextual Search Tap S uppression. | 12 * Implements the UMA logging for Ranker that's used for Contextual Search Tap S uppression. |
13 */ | 13 */ |
14 public class ContextualSearchRankerLoggerImpl implements ContextualSearchRankerL ogger { | 14 public class ContextualSearchRankerLoggerImpl implements ContextualSearchRankerL ogger { |
15 private static final String TAG = "ContextualSearch"; | 15 private static final String TAG = "ContextualSearch"; |
16 | 16 |
17 // Pointer to the native instance of this class. | 17 // Pointer to the native instance of this class. |
18 private long mNativePointer; | 18 private long mNativePointer; |
19 | 19 |
20 // Whether logging for the current URL is currently setup. | 20 // Whether logging for the current URL has been setup. |
21 private boolean mIsLoggingSetup; | 21 private boolean mIsLoggingReadyForUrl; |
22 | 22 |
23 // Whether the service is ready to actually record log data. | 23 // URL of the base page that the log data is associated with. |
24 private boolean mCanServiceActuallyRecord; | 24 private URL mBasePageUrl; |
25 | 25 |
26 // Whether any data has been written to the log since calling setupLoggingFo rPage(). | 26 // Whether inference has already been done for this interaction (and calling #logFeature is no |
27 private boolean mDidLog; | 27 // longer allowed). |
28 private boolean mIsPastInference; | |
Theresa
2017/05/30 20:25:25
nit: "Past" is a bit ambiguous here. Maybe this co
Donn Denman
2017/05/30 23:13:25
Done, I like your suggestion.
| |
29 | |
30 // Whether the UI was suppressed. | |
31 private boolean mWasUiSuppressionInfered; | |
32 | |
33 // Map that accumulates all of the Features to log for a specific user-inter action. | |
34 private Map<Feature, Object> mFeaturesToLog; | |
28 | 35 |
29 /** | 36 /** |
30 * Constructs a Ranker Logger and associated native implementation to write Contextual Search | 37 * Constructs a Ranker Logger and associated native implementation to write Contextual Search |
31 * ML data to Ranker. | 38 * ML data to Ranker. |
32 */ | 39 */ |
33 public ContextualSearchRankerLoggerImpl() { | 40 public ContextualSearchRankerLoggerImpl() { |
34 if (isEnabled()) mNativePointer = nativeInit(); | 41 if (isEnabled()) mNativePointer = nativeInit(); |
35 } | 42 } |
36 | 43 |
37 /** | 44 /** |
38 * This method should be called to clean up storage when an instance of this class is | 45 * This method should be called to clean up storage when an instance of this class is |
39 * no longer in use. The nativeDestroy will call the destructor on the nati ve instance. | 46 * no longer in use. The nativeDestroy will call the destructor on the nati ve instance. |
40 */ | 47 */ |
41 void destroy() { | 48 void destroy() { |
42 if (isEnabled()) { | 49 if (isEnabled()) { |
43 assert mNativePointer != 0; | 50 assert mNativePointer != 0; |
44 writeLogAndReset(); | 51 writeLogAndReset(); |
45 nativeDestroy(mNativePointer); | 52 nativeDestroy(mNativePointer); |
46 mNativePointer = 0; | 53 mNativePointer = 0; |
47 mCanServiceActuallyRecord = false; | |
48 mDidLog = false; | |
49 } | 54 } |
50 mIsLoggingSetup = false; | 55 mIsLoggingReadyForUrl = false; |
51 } | 56 } |
52 | 57 |
53 @Override | 58 @Override |
54 public void setupLoggingForPage(URL basePageUrl) { | 59 public void setupLoggingForPage(URL basePageUrl) { |
55 mIsLoggingSetup = true; | 60 mIsLoggingReadyForUrl = true; |
56 if (isEnabled()) { | 61 mBasePageUrl = basePageUrl; |
57 // The URL may be null for custom Chrome URIs like chrome://flags. | 62 mIsPastInference = false; |
58 if (basePageUrl != null) { | |
59 nativeSetupLoggingAndRanker(mNativePointer, basePageUrl.toString ()); | |
60 mCanServiceActuallyRecord = true; | |
61 } | |
62 } | |
63 } | 63 } |
64 | 64 |
65 @Override | 65 @Override |
66 public void log(Feature feature, Object value) { | 66 public void logFeature(Feature feature, Object value) { |
67 assert mIsLoggingSetup; | 67 assert mIsLoggingReadyForUrl : "mIsLoggingReadyForUrl false."; |
68 if (!isEnabled()) return; | 68 assert !mIsPastInference; |
69 | |
70 // TODO(donnd): Add some enforcement that log() calls are done before in ference time. | |
71 logInternal(feature, value); | |
72 } | |
73 | |
74 @Override | |
75 public void logOutcome(Feature feature, Object value) { | |
76 assert mIsLoggingSetup; | |
77 if (!isEnabled()) return; | 69 if (!isEnabled()) return; |
78 | 70 |
79 logInternal(feature, value); | 71 logInternal(feature, value); |
80 } | 72 } |
81 | 73 |
82 @Override | 74 @Override |
83 public void writeLogAndReset() { | 75 public void logOutcome(Feature feature, Object value) { |
84 if (isEnabled()) { | 76 if (!isEnabled()) return; |
85 if (mDidLog) nativeWriteLogAndReset(mNativePointer); | 77 |
86 mCanServiceActuallyRecord = false; | 78 // Since the panel can be closed at any time, we might try to log that o utcome immediately. |
87 mDidLog = false; | 79 if (!mIsLoggingReadyForUrl) return; |
88 } | 80 |
89 mIsLoggingSetup = false; | 81 logInternal(feature, value); |
90 } | 82 } |
91 | 83 |
92 /** Whether actually writing data is enabled. If not, we may do nothing or print. */ | 84 @Override |
85 public boolean inferUiSuppression() { | |
86 mIsPastInference = true; | |
87 // TODO(donnd): actually run the Ranker model and register its recommend ation here! | |
88 mWasUiSuppressionInfered = false; | |
89 // TODO(donnd): actually return the recommendation so it can be acted up on! | |
90 return false; | |
91 } | |
92 | |
93 @Override | |
94 public boolean wasUiSuppressionInfered() { | |
95 return mWasUiSuppressionInfered; | |
96 } | |
97 | |
98 @Override | |
99 public void reset() { | |
100 mIsLoggingReadyForUrl = false; | |
101 mIsPastInference = false; | |
102 mFeaturesToLog = null; | |
103 mBasePageUrl = null; | |
104 mWasUiSuppressionInfered = false; | |
105 } | |
106 | |
107 @Override | |
108 public void writeLogAndReset() { | |
109 // The URL may be null for custom Chrome URIs like chrome://flags. | |
110 if (isEnabled() && mBasePageUrl != null && mFeaturesToLog != null) { | |
111 assert mIsLoggingReadyForUrl; | |
112 nativeSetupLoggingAndRanker(mNativePointer, mBasePageUrl.toString()) ; | |
113 for (Map.Entry<Feature, Object> entry : mFeaturesToLog.entrySet()) { | |
114 logObject(entry.getKey(), entry.getValue()); | |
115 } | |
116 nativeWriteLogAndReset(mNativePointer); | |
117 } | |
118 reset(); | |
119 } | |
120 | |
121 /** | |
122 * Logs the given feature/value to the internal map that accumulates an enti re record (which can | |
123 * be logged by calling writeLogAndReset). | |
124 * @param feature The feature to log. | |
125 * @param value The value to log. | |
126 */ | |
127 private void logInternal(Feature feature, Object value) { | |
128 if (mFeaturesToLog == null) mFeaturesToLog = new HashMap<Feature, Object >(); | |
129 mFeaturesToLog.put(feature, value); | |
130 } | |
131 | |
132 /** Whether actually writing data is enabled. If not, we may do nothing, or just print. */ | |
93 private boolean isEnabled() { | 133 private boolean isEnabled() { |
94 return ContextualSearchFieldTrial.isRankerLoggingEnabled(); | 134 return ContextualSearchFieldTrial.isRankerLoggingEnabled(); |
95 } | 135 } |
96 | 136 |
97 /** | 137 /** |
98 * Logs the given feature/value after checking that logging has been set up. | 138 * Logs the given {@link ContextualSearchRankerLogger.Feature} with the give n value |
139 * {@link Object}. | |
99 * @param feature The feature to log. | 140 * @param feature The feature to log. |
100 * @param value The value to log. | 141 * @param value An {@link Object} value to log (must be convertible to a {@c ode long}). |
101 */ | 142 */ |
102 private void logInternal(Feature feature, Object value) { | 143 private void logObject(Feature feature, Object value) { |
103 if (value instanceof Boolean) { | 144 if (value instanceof Boolean) { |
104 logToNative(feature.toString(), ((boolean) value ? 1 : 0)); | 145 logToNative(feature, ((boolean) value ? 1 : 0)); |
105 } else if (value instanceof Integer) { | 146 } else if (value instanceof Integer) { |
106 logToNative(feature.toString(), Long.valueOf((int) value)); | 147 logToNative(feature, Long.valueOf((int) value)); |
107 } else if (value instanceof Long) { | 148 } else if (value instanceof Long) { |
108 logToNative(feature.toString(), (long) value); | 149 logToNative(feature, (long) value); |
109 } else if (value instanceof Character) { | 150 } else if (value instanceof Character) { |
110 logToNative(feature.toString(), Character.getNumericValue((char) val ue)); | 151 logToNative(feature, Character.getNumericValue((char) value)); |
111 } else { | 152 } else { |
112 Log.w(TAG, | 153 assert false : "Could not log feature to Ranker: " + feature.toStrin g() + " of class " |
113 "Could not log feature to Ranker: " + feature.toString() + " of class " | 154 + value.getClass(); |
114 + value.getClass()); | |
115 } | 155 } |
116 } | 156 } |
117 | 157 |
118 /** | 158 /** |
119 * Logs to the native instance. All native logging must go through this bot tleneck. | 159 * Logs to the native instance. All native logging must go through this bot tleneck. |
120 * @param feature The feature to log. | 160 * @param feature The feature to log. |
121 * @param value The value to log. | 161 * @param value The value to log. |
122 */ | 162 */ |
123 private void logToNative(String feature, long value) { | 163 private void logToNative(Feature feature, long value) { |
124 if (mCanServiceActuallyRecord) { | 164 nativeLogLong(mNativePointer, feature.toString(), value); |
125 nativeLogLong(mNativePointer, feature, value); | |
126 mDidLog = true; | |
127 } | |
128 } | 165 } |
129 | 166 |
130 // ========================================================================= =================== | 167 // ========================================================================= =================== |
131 // Native methods. | 168 // Native methods. |
132 // ========================================================================= =================== | 169 // ========================================================================= =================== |
133 private native long nativeInit(); | 170 private native long nativeInit(); |
134 private native void nativeDestroy(long nativeContextualSearchRankerLoggerImp l); | 171 private native void nativeDestroy(long nativeContextualSearchRankerLoggerImp l); |
135 private native void nativeLogLong( | 172 private native void nativeLogLong( |
136 long nativeContextualSearchRankerLoggerImpl, String featureString, l ong value); | 173 long nativeContextualSearchRankerLoggerImpl, String featureString, l ong value); |
137 private native void nativeSetupLoggingAndRanker( | 174 private native void nativeSetupLoggingAndRanker( |
138 long nativeContextualSearchRankerLoggerImpl, String basePageUrl); | 175 long nativeContextualSearchRankerLoggerImpl, String basePageUrl); |
139 private native void nativeWriteLogAndReset(long nativeContextualSearchRanker LoggerImpl); | 176 private native void nativeWriteLogAndReset(long nativeContextualSearchRanker LoggerImpl); |
140 } | 177 } |
OLD | NEW |