Commit dcc60951 authored by Shakti Sahu's avatar Shakti Sahu Committed by Commit Bot

Query Tiles : Several fixes for UMA

This CL
1 - Adds TileUmaLogger to omnibox which was missing earlier.
2 - Fixes a bug in TileUmaLogger which wasn't recording top level tiles correctly.
3 - Added tests for TileUmaLogger.

Bug: 1091130
Change-Id: Ie556640c6b301cb26915462973d26c373667ab16
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2230318Reviewed-by: default avatarMin Qin <qinmin@chromium.org>
Reviewed-by: default avatarTed Choc <tedchoc@chromium.org>
Reviewed-by: default avatarDavid Trainor <dtrainor@chromium.org>
Commit-Queue: Shakti Sahu <shaktisahu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#775287}
parent 550c901a
...@@ -990,6 +990,7 @@ android_library("chrome_test_java") { ...@@ -990,6 +990,7 @@ android_library("chrome_test_java") {
"//components/policy/android:policy_java", "//components/policy/android:policy_java",
"//components/policy/android:policy_java_test_support", "//components/policy/android:policy_java_test_support",
"//components/query_tiles:public_java", "//components/query_tiles:public_java",
"//components/query_tiles:test_support_java",
"//components/safe_browsing/android:safe_browsing_java", "//components/safe_browsing/android:safe_browsing_java",
"//components/schema_org/common:mojom_java", "//components/schema_org/common:mojom_java",
"//components/search_engines/android:java", "//components/search_engines/android:java",
......
...@@ -437,7 +437,6 @@ chrome_test_java_sources = [ ...@@ -437,7 +437,6 @@ chrome_test_java_sources = [
"javatests/src/org/chromium/chrome/browser/query_tiles/OmniboxQueryTileSuggestionTest.java", "javatests/src/org/chromium/chrome/browser/query_tiles/OmniboxQueryTileSuggestionTest.java",
"javatests/src/org/chromium/chrome/browser/query_tiles/QueryTileSectionTest.java", "javatests/src/org/chromium/chrome/browser/query_tiles/QueryTileSectionTest.java",
"javatests/src/org/chromium/chrome/browser/query_tiles/QueryTileSectionToOmniboxTest.java", "javatests/src/org/chromium/chrome/browser/query_tiles/QueryTileSectionToOmniboxTest.java",
"javatests/src/org/chromium/chrome/browser/query_tiles/TestTileProvider.java",
"javatests/src/org/chromium/chrome/browser/query_tiles/TileMatchers.java", "javatests/src/org/chromium/chrome/browser/query_tiles/TileMatchers.java",
"javatests/src/org/chromium/chrome/browser/query_tiles/ViewActions.java", "javatests/src/org/chromium/chrome/browser/query_tiles/ViewActions.java",
"javatests/src/org/chromium/chrome/browser/search_engines/TemplateUrlServiceTest.java", "javatests/src/org/chromium/chrome/browser/search_engines/TemplateUrlServiceTest.java",
......
...@@ -23,6 +23,7 @@ import org.chromium.components.browser_ui.widget.image_tiles.ImageTileCoordinato ...@@ -23,6 +23,7 @@ import org.chromium.components.browser_ui.widget.image_tiles.ImageTileCoordinato
import org.chromium.components.browser_ui.widget.image_tiles.TileConfig; import org.chromium.components.browser_ui.widget.image_tiles.TileConfig;
import org.chromium.components.query_tiles.QueryTile; import org.chromium.components.query_tiles.QueryTile;
import org.chromium.components.query_tiles.QueryTileConstants; import org.chromium.components.query_tiles.QueryTileConstants;
import org.chromium.components.query_tiles.TileUmaLogger;
import org.chromium.content_public.browser.UiThreadTaskTraits; import org.chromium.content_public.browser.UiThreadTaskTraits;
import org.chromium.ui.UiUtils; import org.chromium.ui.UiUtils;
...@@ -40,6 +41,7 @@ public class OmniboxQueryTileCoordinator { ...@@ -40,6 +41,7 @@ public class OmniboxQueryTileCoordinator {
private final Context mContext; private final Context mContext;
private final Callback<QueryTile> mSelectionCallback; private final Callback<QueryTile> mSelectionCallback;
private final TileUmaLogger mTileUmaLogger;
private ImageTileCoordinator mTileCoordinator; private ImageTileCoordinator mTileCoordinator;
private ImageFetcher mImageFetcher; private ImageFetcher mImageFetcher;
private Integer mTileWidth; private Integer mTileWidth;
...@@ -52,10 +54,12 @@ public class OmniboxQueryTileCoordinator { ...@@ -52,10 +54,12 @@ public class OmniboxQueryTileCoordinator {
public OmniboxQueryTileCoordinator(Context context, Callback<QueryTile> selectionCallback) { public OmniboxQueryTileCoordinator(Context context, Callback<QueryTile> selectionCallback) {
mContext = context; mContext = context;
mSelectionCallback = selectionCallback; mSelectionCallback = selectionCallback;
mTileUmaLogger = new TileUmaLogger(UMA_PREFIX);
} }
/** Called to set the list of query tiles to be displayed in the suggestion. */ /** Called to set the list of query tiles to be displayed in the suggestion. */
public void setTiles(List<QueryTile> tiles) { public void setTiles(List<QueryTile> tiles) {
mTileUmaLogger.recordTilesLoaded(tiles);
getTileCoordinator().setTiles(tiles == null ? new ArrayList<>() : new ArrayList<>(tiles)); getTileCoordinator().setTiles(tiles == null ? new ArrayList<>() : new ArrayList<>(tiles));
} }
...@@ -123,6 +127,7 @@ public class OmniboxQueryTileCoordinator { ...@@ -123,6 +127,7 @@ public class OmniboxQueryTileCoordinator {
private void onTileClicked(ImageTile tile) { private void onTileClicked(ImageTile tile) {
QueryTile queryTile = (QueryTile) tile; QueryTile queryTile = (QueryTile) tile;
mTileUmaLogger.recordTileClicked(queryTile);
mSelectionCallback.onResult(queryTile); mSelectionCallback.onResult(queryTile);
} }
} }
...@@ -49,6 +49,7 @@ import org.chromium.chrome.test.util.OmniboxTestUtils; ...@@ -49,6 +49,7 @@ import org.chromium.chrome.test.util.OmniboxTestUtils;
import org.chromium.chrome.test.util.browser.Features; import org.chromium.chrome.test.util.browser.Features;
import org.chromium.components.embedder_support.util.UrlConstants; import org.chromium.components.embedder_support.util.UrlConstants;
import org.chromium.components.query_tiles.QueryTile; import org.chromium.components.query_tiles.QueryTile;
import org.chromium.components.query_tiles.TestTileProvider;
import org.chromium.components.query_tiles.TileProvider; import org.chromium.components.query_tiles.TileProvider;
import org.chromium.content_public.browser.UiThreadTaskTraits; import org.chromium.content_public.browser.UiThreadTaskTraits;
import org.chromium.content_public.browser.test.util.Criteria; import org.chromium.content_public.browser.test.util.Criteria;
......
...@@ -43,6 +43,7 @@ import org.chromium.chrome.test.util.OmniboxTestUtils; ...@@ -43,6 +43,7 @@ import org.chromium.chrome.test.util.OmniboxTestUtils;
import org.chromium.chrome.test.util.browser.Features; import org.chromium.chrome.test.util.browser.Features;
import org.chromium.components.embedder_support.util.UrlConstants; import org.chromium.components.embedder_support.util.UrlConstants;
import org.chromium.components.query_tiles.QueryTile; import org.chromium.components.query_tiles.QueryTile;
import org.chromium.components.query_tiles.TestTileProvider;
import org.chromium.content_public.browser.test.util.Criteria; import org.chromium.content_public.browser.test.util.Criteria;
import org.chromium.content_public.browser.test.util.CriteriaHelper; import org.chromium.content_public.browser.test.util.CriteriaHelper;
import org.chromium.content_public.browser.test.util.TestThreadUtils; import org.chromium.content_public.browser.test.util.TestThreadUtils;
......
...@@ -43,6 +43,7 @@ import org.chromium.chrome.test.util.OmniboxTestUtils; ...@@ -43,6 +43,7 @@ import org.chromium.chrome.test.util.OmniboxTestUtils;
import org.chromium.chrome.test.util.browser.Features; import org.chromium.chrome.test.util.browser.Features;
import org.chromium.components.embedder_support.util.UrlConstants; import org.chromium.components.embedder_support.util.UrlConstants;
import org.chromium.components.query_tiles.QueryTile; import org.chromium.components.query_tiles.QueryTile;
import org.chromium.components.query_tiles.TestTileProvider;
/** /**
* Provides a set of tests to validate that QueryTiles works properly in the NTP given the following * Provides a set of tests to validate that QueryTiles works properly in the NTP given the following
......
...@@ -752,6 +752,7 @@ if (is_android) { ...@@ -752,6 +752,7 @@ if (is_android) {
"//components/gcm_driver/android:components_gcm_driver_junit_tests", "//components/gcm_driver/android:components_gcm_driver_junit_tests",
"//components/permissions/android:components_permissions_junit_tests", "//components/permissions/android:components_permissions_junit_tests",
"//components/policy/android:components_policy_junit_tests", "//components/policy/android:components_policy_junit_tests",
"//components/query_tiles:query_tiles_junit_tests",
"//components/signin/core/browser/android:components_signin_junit_tests", "//components/signin/core/browser/android:components_signin_junit_tests",
"//components/variations/android:components_variations_junit_tests", "//components/variations/android:components_variations_junit_tests",
] ]
......
...@@ -99,6 +99,29 @@ if (is_android) { ...@@ -99,6 +99,29 @@ if (is_android) {
"android/java/src/org/chromium/components/query_tiles/bridges/TileProviderBridge.java", "android/java/src/org/chromium/components/query_tiles/bridges/TileProviderBridge.java",
] ]
} }
android_library("test_support_java") {
sources = [ "android/java/src/org/chromium/components/query_tiles/TestTileProvider.java" ]
deps = [
":public_java",
"//base:base_java",
]
}
android_library("query_tiles_junit_tests") {
bypass_platform_checks = true
testonly = true
sources = [ "android/java/src/org/chromium/components/query_tiles/TileUmaLoggerTest.java" ]
deps = [
":public_java",
":test_support_java",
"//base:base_java",
"//base:base_junit_test_support",
"//third_party/junit",
]
}
} }
group("unit_tests") { group("unit_tests") {
......
...@@ -2,11 +2,9 @@ ...@@ -2,11 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
package org.chromium.chrome.browser.query_tiles; package org.chromium.components.query_tiles;
import org.chromium.base.Callback; import org.chromium.base.Callback;
import org.chromium.components.query_tiles.QueryTile;
import org.chromium.components.query_tiles.TileProvider;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
...@@ -14,7 +12,7 @@ import java.util.List; ...@@ -14,7 +12,7 @@ import java.util.List;
/** /**
* Helper implementation of {@link TileProvider} for tests. * Helper implementation of {@link TileProvider} for tests.
*/ */
class TestTileProvider implements TileProvider { public class TestTileProvider implements TileProvider {
private List<QueryTile> mTiles = new ArrayList<>(); private List<QueryTile> mTiles = new ArrayList<>();
/** /**
......
...@@ -16,16 +16,27 @@ import java.util.List; ...@@ -16,16 +16,27 @@ import java.util.List;
*/ */
public class TileUmaLogger { public class TileUmaLogger {
private final String mHistogramPrefix; private final String mHistogramPrefix;
private List<QueryTile> mTiles; private List<QueryTile> mTopLevelTiles;
public TileUmaLogger(String histogramPrefix) { public TileUmaLogger(String histogramPrefix) {
mHistogramPrefix = histogramPrefix; mHistogramPrefix = histogramPrefix;
} }
/**
* Called when a new set of tiles are loaded.
* @param tiles The tiles loaded in the UI.
*/
public void recordTilesLoaded(List<QueryTile> tiles) { public void recordTilesLoaded(List<QueryTile> tiles) {
mTiles = tiles; if (tiles == null || tiles.isEmpty()) return;
// We only care about the first time tiles are loaded. The subsequent calls to this function
// are ignored as they might be called for sub-level tiles and we already have the tree
// information.
if (mTopLevelTiles != null) return;
mTopLevelTiles = tiles;
RecordHistogram.recordCountHistogram( RecordHistogram.recordCountHistogram(
"Search." + mHistogramPrefix + ".TileCount", mTiles.size()); "Search." + mHistogramPrefix + ".TileCount", mTopLevelTiles.size());
} }
public void recordTileClicked(QueryTile tile) { public void recordTileClicked(QueryTile tile) {
...@@ -51,7 +62,7 @@ public class TileUmaLogger { ...@@ -51,7 +62,7 @@ public class TileUmaLogger {
} }
private boolean isTopLevelTile(String id) { private boolean isTopLevelTile(String id) {
for (QueryTile tile : mTiles) { for (QueryTile tile : mTopLevelTiles) {
if (tile.id.equals(id)) return true; if (tile.id.equals(id)) return true;
} }
return false; return false;
...@@ -60,14 +71,14 @@ public class TileUmaLogger { ...@@ -60,14 +71,14 @@ public class TileUmaLogger {
/** /**
* Returns a UMA ID for the tile which will be used to identify the tile for metrics purposes. * Returns a UMA ID for the tile which will be used to identify the tile for metrics purposes.
* The UMA ID is generated from the position of the tile in the query tile tree. * The UMA ID is generated from the position of the tile in the query tile tree.
* Top level tiles will be numbered 1,2,3... while the next level tile start * Top level tiles will be numbered 0,1,2... while the next level tile start
* from 101 (101, 102, ... etc), 201 (201, 202, ... etc), and so on. * from 100 (100, 101, ... etc), 200 (200, 201, ... etc), and so on.
*/ */
private int getTileUmaId(String tileId) { private int getTileUmaId(String tileId) {
assert !TextUtils.isEmpty(tileId); assert !TextUtils.isEmpty(tileId);
for (int i = 0; i < mTiles.size(); i++) { for (int i = 0; i < mTopLevelTiles.size(); i++) {
int found = search(mTiles.get(i), tileId, i + 1); int found = search(mTopLevelTiles.get(i), tileId, i);
if (found != -1) return found; if (found != -1) return found;
} }
...@@ -75,10 +86,11 @@ public class TileUmaLogger { ...@@ -75,10 +86,11 @@ public class TileUmaLogger {
} }
private int search(QueryTile tile, String id, int startPosition) { private int search(QueryTile tile, String id, int startPosition) {
if (id.equals(tile.id)) return startPosition;
startPosition = (startPosition + 1) * 100;
for (int i = 0; i < tile.children.size(); i++) { for (int i = 0; i < tile.children.size(); i++) {
QueryTile child = tile.children.get(i); QueryTile child = tile.children.get(i);
if (id.equals(child.id)) return startPosition + i; int found = search(child, id, startPosition + i);
int found = search(child, id, startPosition * 100);
if (found != -1) return found; if (found != -1) return found;
} }
return -1; return -1;
......
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.components.query_tiles;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.annotation.Config;
import org.chromium.base.metrics.RecordHistogram;
import org.chromium.base.metrics.test.ShadowRecordHistogram;
import org.chromium.base.test.BaseRobolectricTestRunner;
@RunWith(BaseRobolectricTestRunner.class)
@Config(manifest = Config.NONE, shadows = {ShadowRecordHistogram.class})
public class TileUmaLoggerTest {
private TileUmaLogger mTileUmaLogger;
private TestTileProvider mTileProvider;
@Before
public void setUp() {
ShadowRecordHistogram.reset();
mTileProvider = new TestTileProvider(2, 12);
mTileUmaLogger = new TileUmaLogger("TestUiSurface");
}
@After
public void tearDown() {}
@Test
public void testTileClicked() {
mTileProvider.getQueryTiles(tiles -> {
mTileUmaLogger.recordTilesLoaded(tiles);
// Click top level tiles.
mTileUmaLogger.recordTileClicked(mTileProvider.getTileAt(0));
mTileUmaLogger.recordTileClicked(mTileProvider.getTileAt(11));
assertHistogramClicked(0, 1);
assertHistogramClicked(1, 0);
assertHistogramClicked(11, 1);
assertHistogramClicked(100, 0);
assertHistogramClicked(111, 0);
assertHistogramClicked(1200, 0);
// Click next level tiles.
mTileUmaLogger.recordTileClicked(mTileProvider.getTileAt(2, 3));
mTileUmaLogger.recordTileClicked(mTileProvider.getTileAt(2, 3));
assertHistogramClicked(0, 1);
assertHistogramClicked(303, 2);
assertHistogramClicked(11, 1);
// Click on the chip on fakebox.
mTileUmaLogger.recordSearchButtonClicked(mTileProvider.getTileAt(0, 2));
Assert.assertEquals(1,
RecordHistogram.getHistogramValueCountForTesting(
"Search.QueryTiles.NTP.Chip.SearchClicked", 102));
});
}
private void assertHistogramClicked(int tileHistogramIndex, int expected) {
int actual = RecordHistogram.getHistogramValueCountForTesting(
"Search.TestUiSurface.Tile.Clicked", tileHistogramIndex);
Assert.assertEquals(expected, actual);
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment