Chromium Code Reviews| 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 |