Commit ef624dfe authored by spdonghao's avatar spdonghao Committed by Chromium LUCI CQ

[Instant Start] Refactor MV tiles metadata caching utils classes.

This CL does some refactoring work:
1. Save existing MV tiles info instead of only SiteSuggestion data.
2. Remove MV tiles favicons saving codes - the cached favicons are not
   always consistent with post-native ones so we show the default grey
   background icon instead.
3. Since favicons are no longer cached, we don't need to keep
   |mUrlToIdMap| and |mUrlsToUpdateFavicon|.
4. SiteSuggestion#faviconId is no longer needed.

Bug: 1067386
Change-Id: I2f05ea32a04c30ef8ed21504a78a77771edb4043
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2611670Reviewed-by: default avatarCathy Li <chili@chromium.org>
Reviewed-by: default avatarTheresa  <twellington@chromium.org>
Reviewed-by: default avatarWei-Yin Chen (陳威尹) <wychen@chromium.org>
Reviewed-by: default avatarXi Han <hanxi@chromium.org>
Commit-Queue: Hao Dong <spdonghao@chromium.org>
Cr-Commit-Position: refs/heads/master@{#845955}
parent ae957034
...@@ -1272,8 +1272,6 @@ chrome_java_sources = [ ...@@ -1272,8 +1272,6 @@ chrome_java_sources = [
"java/src/org/chromium/chrome/browser/suggestions/ThumbnailGradient.java", "java/src/org/chromium/chrome/browser/suggestions/ThumbnailGradient.java",
"java/src/org/chromium/chrome/browser/suggestions/mostvisited/MostVisitedSites.java", "java/src/org/chromium/chrome/browser/suggestions/mostvisited/MostVisitedSites.java",
"java/src/org/chromium/chrome/browser/suggestions/mostvisited/MostVisitedSitesBridge.java", "java/src/org/chromium/chrome/browser/suggestions/mostvisited/MostVisitedSitesBridge.java",
"java/src/org/chromium/chrome/browser/suggestions/mostvisited/MostVisitedSitesFaviconHelper.java",
"java/src/org/chromium/chrome/browser/suggestions/mostvisited/MostVisitedSitesHost.java",
"java/src/org/chromium/chrome/browser/suggestions/mostvisited/MostVisitedSitesMetadataUtils.java", "java/src/org/chromium/chrome/browser/suggestions/mostvisited/MostVisitedSitesMetadataUtils.java",
"java/src/org/chromium/chrome/browser/suggestions/tile/SiteSection.java", "java/src/org/chromium/chrome/browser/suggestions/tile/SiteSection.java",
"java/src/org/chromium/chrome/browser/suggestions/tile/SiteSectionViewHolder.java", "java/src/org/chromium/chrome/browser/suggestions/tile/SiteSectionViewHolder.java",
......
...@@ -520,8 +520,6 @@ chrome_test_java_sources = [ ...@@ -520,8 +520,6 @@ chrome_test_java_sources = [
"javatests/src/org/chromium/chrome/browser/status_indicator/StatusIndicatorTest.java", "javatests/src/org/chromium/chrome/browser/status_indicator/StatusIndicatorTest.java",
"javatests/src/org/chromium/chrome/browser/status_indicator/StatusIndicatorViewBinderTest.java", "javatests/src/org/chromium/chrome/browser/status_indicator/StatusIndicatorViewBinderTest.java",
"javatests/src/org/chromium/chrome/browser/suggestions/NavigationRecorderTest.java", "javatests/src/org/chromium/chrome/browser/suggestions/NavigationRecorderTest.java",
"javatests/src/org/chromium/chrome/browser/suggestions/mostvisited/MostVisitedSitesFaviconHelperTest.java",
"javatests/src/org/chromium/chrome/browser/suggestions/mostvisited/MostVisitedSitesHostTest.java",
"javatests/src/org/chromium/chrome/browser/suggestions/mostvisited/MostVisitedSitesMetadataUtilsTest.java", "javatests/src/org/chromium/chrome/browser/suggestions/mostvisited/MostVisitedSitesMetadataUtilsTest.java",
"javatests/src/org/chromium/chrome/browser/suggestions/tile/TileGridLayoutTest.java", "javatests/src/org/chromium/chrome/browser/suggestions/tile/TileGridLayoutTest.java",
"javatests/src/org/chromium/chrome/browser/suggestions/tile/TileGroupTest.java", "javatests/src/org/chromium/chrome/browser/suggestions/tile/TileGroupTest.java",
......
...@@ -23,9 +23,6 @@ public class SiteSuggestion { ...@@ -23,9 +23,6 @@ public class SiteSuggestion {
/** URL of the suggested site. */ /** URL of the suggested site. */
public final GURL url; public final GURL url;
/** Id of the favicon. It is optional and used when caching the favion on device. */
public int faviconId;
/** The path to the icon image file for allowlisted tile, empty string otherwise. */ /** The path to the icon image file for allowlisted tile, empty string otherwise. */
public final String allowlistIconPath; public final String allowlistIconPath;
...@@ -52,7 +49,6 @@ public class SiteSuggestion { ...@@ -52,7 +49,6 @@ public class SiteSuggestion {
int source, int sectionType, Date dataGenerationTime) { int source, int sectionType, Date dataGenerationTime) {
this.title = title; this.title = title;
this.url = url; this.url = url;
this.faviconId = INVALID_FAVICON_ID;
this.allowlistIconPath = allowlistIconPath; this.allowlistIconPath = allowlistIconPath;
this.source = source; this.source = source;
this.titleSource = titleSource; this.titleSource = titleSource;
......
// 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.chrome.browser.suggestions.mostvisited;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import androidx.core.util.AtomicFile;
import org.chromium.base.ApiCompatibilityUtils;
import org.chromium.base.Log;
import org.chromium.base.task.AsyncTask;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.suggestions.SiteSuggestion;
import org.chromium.components.browser_ui.widget.RoundedIconGenerator;
import org.chromium.components.favicon.IconType;
import org.chromium.components.favicon.LargeIconBridge;
import org.chromium.url.GURL;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
import java.util.Set;
/**
* This class provides methods to fetch/save most visited sites favicon info to devices.
*/
public class MostVisitedSitesFaviconHelper {
private static final String TAG = "TopSitesFavicon";
private final int mMinIconSize;
private final int mDesiredIconSize;
private final LargeIconBridge mLargeIconBridge;
private final RoundedIconGenerator mIconGenerator;
public MostVisitedSitesFaviconHelper(Context context, LargeIconBridge largeIconBridge) {
mLargeIconBridge = largeIconBridge;
Resources resources = context.getResources();
mDesiredIconSize = resources.getDimensionPixelSize(R.dimen.tile_view_icon_size);
int minIconSize = resources.getDimensionPixelSize(R.dimen.tile_view_icon_min_size);
// On ldpi devices, mDesiredIconSize could be even smaller than the global limit.
mMinIconSize = Math.min(mDesiredIconSize, minIconSize);
int iconColor =
ApiCompatibilityUtils.getColor(resources, R.color.default_favicon_background_color);
int iconTextSize = resources.getDimensionPixelSize(R.dimen.tile_view_icon_text_size);
mIconGenerator = new RoundedIconGenerator(
mDesiredIconSize, mDesiredIconSize, mDesiredIconSize / 2, iconColor, iconTextSize);
}
/**
* Save the favicon to the disk.
* @param topSitesInfo SiteSuggestions data updated.
* @param urlsToUpdate The set of urls which need to fetch and save the favicon.
* @param callback The callback function after skipping the existing favicon or saving favicon.
*/
public void saveFaviconsToFile(
List<SiteSuggestion> topSitesInfo, Set<GURL> urlsToUpdate, Runnable callback) {
for (SiteSuggestion siteData : topSitesInfo) {
GURL url = siteData.url;
if (!urlsToUpdate.contains(url)) {
if (callback != null) {
callback.run();
}
continue;
}
LargeIconBridge.LargeIconCallback iconCallback =
(icon, fallbackColor, isFallbackColorDefault, iconType) -> {
saveFaviconToFile(String.valueOf(siteData.faviconId),
MostVisitedSitesMetadataUtils.getOrCreateTopSitesDirectory(), url,
fallbackColor, icon, callback);
};
fetchIcon(siteData, iconCallback);
}
}
/**
* Fetch the favicon for a given site.
* @param siteData SiteSuggestion data which needs to fetch and save the favicon.
* @param iconCallback The callback function after fetching the favicon.
*/
// TODO(https://crbug.com/1067386): Change fetchIcon() to public and static, then reuse it in
// other classes.
private void fetchIcon(
final SiteSuggestion siteData, final LargeIconBridge.LargeIconCallback iconCallback) {
if (siteData.allowlistIconPath.isEmpty()) {
mLargeIconBridge.getLargeIconForUrl(siteData.url, mMinIconSize, iconCallback);
return;
}
AsyncTask<Bitmap> task = new AsyncTask<Bitmap>() {
@Override
protected Bitmap doInBackground() {
Bitmap bitmap = BitmapFactory.decodeFile(siteData.allowlistIconPath);
if (bitmap == null) {
Log.d(TAG, "Image decoding failed: %s.", siteData.allowlistIconPath);
}
return bitmap;
}
@Override
protected void onPostExecute(Bitmap icon) {
if (icon == null) {
mLargeIconBridge.getLargeIconForUrl(siteData.url, mMinIconSize, iconCallback);
} else {
iconCallback.onLargeIconAvailable(icon, Color.BLACK, false, IconType.INVALID);
}
}
};
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
/**
* Save the favicon to the disk.
* @param fileName The file name to save the favicon.
* @param directory The directory to save the favicon.
* @param url The url which the favicon corresponds to.
* @param fallbackColor The color for generating a new icon when favicon is null from native.
* @param icon The favicon fetched from native.
* @param callback The callback function after saving each favicon.
*/
private void saveFaviconToFile(String fileName, File directory, GURL url, int fallbackColor,
Bitmap icon, Runnable callback) {
new AsyncTask<Void>() {
@Override
protected Void doInBackground() {
Bitmap newIcon = icon;
// If icon is null, we need to generate a favicon.
if (newIcon == null) {
Log.i(TAG,
"Favicon is null for " + url.getSpec()
+ ". Generating an icon for it.");
mIconGenerator.setBackgroundColor(fallbackColor);
newIcon = mIconGenerator.generateIconForUrl(url.getSpec());
}
// Save icon to file.
File metadataFile = new File(directory, fileName);
AtomicFile file = new AtomicFile(metadataFile);
FileOutputStream stream;
try {
stream = file.startWrite();
assert newIcon != null;
newIcon.compress(Bitmap.CompressFormat.PNG, 100, stream);
file.finishWrite(stream);
Log.i(TAG,
"Finished saving top sites favicons to file: "
+ metadataFile.getAbsolutePath());
} catch (IOException e) {
Log.e(TAG, "Fail to write file: " + metadataFile.getAbsolutePath());
}
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
if (callback != null) {
callback.run();
}
}
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
}
// 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.chrome.browser.suggestions.mostvisited;
import android.graphics.Bitmap;
import androidx.core.util.AtomicFile;
import androidx.test.filters.MediumTest;
import org.hamcrest.Matchers;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.chromium.base.test.util.CommandLineFlags;
import org.chromium.base.test.util.Criteria;
import org.chromium.base.test.util.CriteriaHelper;
import org.chromium.base.test.util.DisabledTest;
import org.chromium.chrome.browser.flags.ChromeSwitches;
import org.chromium.chrome.browser.profiles.Profile;
import org.chromium.chrome.browser.suggestions.SiteSuggestion;
import org.chromium.chrome.browser.suggestions.tile.TileSectionType;
import org.chromium.chrome.browser.suggestions.tile.TileSource;
import org.chromium.chrome.browser.suggestions.tile.TileTitleSource;
import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
import org.chromium.components.favicon.LargeIconBridge;
import org.chromium.content_public.browser.test.util.TestThreadUtils;
import org.chromium.url.GURL;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
/**
* Instrumentation tests for {@link MostVisitedSitesFaviconHelper}.
*/
@RunWith(ChromeJUnit4ClassRunner.class)
@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE})
public class MostVisitedSitesFaviconHelperTest {
@Rule
public ChromeTabbedActivityTestRule mTestSetupRule = new ChromeTabbedActivityTestRule();
private List<SiteSuggestion> mExpectedSiteSuggestions;
private MostVisitedSitesFaviconHelper mMostVisitedSitesFaviconHelper;
@Before
public void setUp() {
mTestSetupRule.startMainActivityOnBlankPage();
mExpectedSiteSuggestions = createFakeSiteSuggestions();
TestThreadUtils.runOnUiThreadBlocking(() -> {
LargeIconBridge largeIconBridge =
new LargeIconBridge(Profile.getLastUsedRegularProfile());
mMostVisitedSitesFaviconHelper = new MostVisitedSitesFaviconHelper(
mTestSetupRule.getActivity(), largeIconBridge);
});
}
@Test
@MediumTest
@DisabledTest(message = "crbug.com/1149856")
public void testSaveFaviconsToFile() {
// Add sites' URLs into the urlsToUpdate, except the last one.
Set<GURL> urlsToUpdate = new HashSet<>();
for (int i = 0; i < mExpectedSiteSuggestions.size() - 1; i++) {
urlsToUpdate.add(mExpectedSiteSuggestions.get(i).url);
}
// Save file count before saving favicons since there might be other files in the directory.
int originalFilesNum = getStateDirectorySize();
// Call saveFaviconsToFile.
TestThreadUtils.runOnUiThreadBlocking(
()
-> mMostVisitedSitesFaviconHelper.saveFaviconsToFile(
mExpectedSiteSuggestions, urlsToUpdate, null));
// Wait util the file number equals to expected one.
CriteriaHelper.pollInstrumentationThread(() -> {
Criteria.checkThat(
getStateDirectorySize() - originalFilesNum, Matchers.is(urlsToUpdate.size()));
});
// The Favicon File lists in the disk.
File topSitesDirectory = MostVisitedSitesMetadataUtils.getStateDirectory();
Assert.assertNotNull(topSitesDirectory);
String[] faviconFiles = topSitesDirectory.list();
Assert.assertNotNull(faviconFiles);
Set<String> existingIconFiles = new HashSet<>(Arrays.asList(faviconFiles));
// Check whether each URL's favicon exist in the disk.
Assert.assertTrue(existingIconFiles.contains("0"));
Assert.assertTrue(existingIconFiles.contains("1"));
Assert.assertTrue(existingIconFiles.contains("2"));
Assert.assertFalse(existingIconFiles.contains("3"));
}
private static List<SiteSuggestion> createFakeSiteSuggestions() {
List<SiteSuggestion> siteSuggestions = new ArrayList<>();
siteSuggestions.add(new SiteSuggestion("0 TOP_SITES", new GURL("https://www.foo.com"), "",
TileTitleSource.TITLE_TAG, TileSource.TOP_SITES, TileSectionType.PERSONALIZED,
new Date()));
siteSuggestions.add(new SiteSuggestion("1 ALLOWLIST", new GURL("https://www.bar.com"),
"/not_exist.png", TileTitleSource.UNKNOWN, TileSource.ALLOWLIST,
TileSectionType.PERSONALIZED, new Date()));
siteSuggestions.add(new SiteSuggestion("2 TOP_SITES", new GURL("https://www.baz.com"),
createBitmapAndWriteToFile(), TileTitleSource.UNKNOWN, TileSource.ALLOWLIST,
TileSectionType.PERSONALIZED, new Date()));
siteSuggestions.add(new SiteSuggestion("3 TOP_SITES", new GURL("https://www.qux.com"), "",
TileTitleSource.UNKNOWN, TileSource.ALLOWLIST, TileSectionType.PERSONALIZED,
new Date()));
siteSuggestions.get(0).faviconId = 0;
siteSuggestions.get(1).faviconId = 1;
siteSuggestions.get(2).faviconId = 2;
siteSuggestions.get(3).faviconId = 3;
return siteSuggestions;
}
private static String createBitmapAndWriteToFile() {
final Bitmap testBitmap = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
String fileName = "test.png";
// Save bitmap to file.
File metadataFile =
new File(MostVisitedSitesMetadataUtils.getOrCreateTopSitesDirectory(), fileName);
AtomicFile file = new AtomicFile(metadataFile);
FileOutputStream stream;
try {
stream = file.startWrite();
testBitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
file.finishWrite(stream);
} catch (IOException e) {
e.printStackTrace();
}
return metadataFile.getAbsolutePath();
}
private static int getStateDirectorySize() {
return Objects.requireNonNull(MostVisitedSitesMetadataUtils.getStateDirectory().list())
.length;
}
}
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
package org.chromium.chrome.browser.suggestions.mostvisited; package org.chromium.chrome.browser.suggestions.mostvisited;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import androidx.test.filters.SmallTest; import androidx.test.filters.SmallTest;
...@@ -15,13 +17,16 @@ import org.junit.Test; ...@@ -15,13 +17,16 @@ import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.CommandLineFlags;
import org.chromium.base.test.util.CriteriaHelper;
import org.chromium.chrome.browser.flags.ChromeSwitches; import org.chromium.chrome.browser.flags.ChromeSwitches;
import org.chromium.chrome.browser.suggestions.SiteSuggestion; import org.chromium.chrome.browser.suggestions.SiteSuggestion;
import org.chromium.chrome.browser.suggestions.tile.Tile;
import org.chromium.chrome.browser.suggestions.tile.TileSectionType; import org.chromium.chrome.browser.suggestions.tile.TileSectionType;
import org.chromium.chrome.browser.suggestions.tile.TileSource; import org.chromium.chrome.browser.suggestions.tile.TileSource;
import org.chromium.chrome.browser.suggestions.tile.TileTitleSource; import org.chromium.chrome.browser.suggestions.tile.TileTitleSource;
import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
import org.chromium.chrome.test.ChromeTabbedActivityTestRule; import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
import org.chromium.content_public.browser.test.util.TestThreadUtils;
import org.chromium.url.GURL; import org.chromium.url.GURL;
import java.io.File; import java.io.File;
...@@ -30,6 +35,7 @@ import java.util.ArrayList; ...@@ -30,6 +35,7 @@ import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicBoolean;
/** /**
* Instrumentation tests for {@link MostVisitedSitesMetadataUtils}. * Instrumentation tests for {@link MostVisitedSitesMetadataUtils}.
...@@ -40,17 +46,18 @@ public class MostVisitedSitesMetadataUtilsTest { ...@@ -40,17 +46,18 @@ public class MostVisitedSitesMetadataUtilsTest {
@Rule @Rule
public ChromeTabbedActivityTestRule mTestSetupRule = new ChromeTabbedActivityTestRule(); public ChromeTabbedActivityTestRule mTestSetupRule = new ChromeTabbedActivityTestRule();
private List<SiteSuggestion> mExpectedSiteSuggestions; private MostVisitedSitesMetadataUtils mMostVisitedSitesMetadataUtils;
@Before @Before
public void setUp() { public void setUp() {
mTestSetupRule.startMainActivityOnBlankPage(); mTestSetupRule.startMainActivityOnBlankPage();
mMostVisitedSitesMetadataUtils = MostVisitedSitesMetadataUtils.getInstance();
} }
@Test @Test
@SmallTest @SmallTest
public void testSaveRestoreConsistency() throws InterruptedException, IOException { public void testSaveRestoreConsistency() throws InterruptedException, IOException {
mExpectedSiteSuggestions = createFakeSiteSuggestions(); List<Tile> expectedSuggestionTiles = createFakeSiteSuggestionTiles1();
// Get old file and ensure to delete it. // Get old file and ensure to delete it.
File oldFile = MostVisitedSitesMetadataUtils.getOrCreateTopSitesDirectory(); File oldFile = MostVisitedSitesMetadataUtils.getOrCreateTopSitesDirectory();
...@@ -59,17 +66,20 @@ public class MostVisitedSitesMetadataUtilsTest { ...@@ -59,17 +66,20 @@ public class MostVisitedSitesMetadataUtilsTest {
// Save suggestion lists to file. // Save suggestion lists to file.
final CountDownLatch latch = new CountDownLatch(1); final CountDownLatch latch = new CountDownLatch(1);
MostVisitedSitesMetadataUtils.saveSuggestionListsToFile( MostVisitedSitesMetadataUtils.saveSuggestionListsToFile(
mExpectedSiteSuggestions, latch::countDown); expectedSuggestionTiles, latch::countDown);
// Wait util the file has been saved. // Wait util the file has been saved.
latch.await(); latch.await();
// Restore list from file after saving finished. // Restore list from file after saving finished.
List<SiteSuggestion> sitesAfterRestore = List<Tile> sitesAfterRestore = MostVisitedSitesMetadataUtils.restoreFileToSuggestionLists();
MostVisitedSitesMetadataUtils.restoreFileToSuggestionLists();
// Ensure that the new list equals to old list. // Ensure that the new list equals to old list.
assertEquals(mExpectedSiteSuggestions, sitesAfterRestore); assertEquals(expectedSuggestionTiles.size(), sitesAfterRestore.size());
for (int i = 0; i < expectedSuggestionTiles.size(); i++) {
assertEquals(
expectedSuggestionTiles.get(i).getData(), sitesAfterRestore.get(i).getData());
}
} }
@Test(expected = IOException.class) @Test(expected = IOException.class)
...@@ -83,15 +93,78 @@ public class MostVisitedSitesMetadataUtilsTest { ...@@ -83,15 +93,78 @@ public class MostVisitedSitesMetadataUtilsTest {
MostVisitedSitesMetadataUtils.restoreFileToSuggestionLists(); MostVisitedSitesMetadataUtils.restoreFileToSuggestionLists();
} }
private static List<SiteSuggestion> createFakeSiteSuggestions() { /**
List<SiteSuggestion> siteSuggestions = new ArrayList<>(); * Test when current task is not finished, all coming tasks will be set as the pending task.
siteSuggestions.add(new SiteSuggestion("0 TOP_SITES", new GURL("https://www.foo.com"), "", * Besides, the latest task will override the old one.
*/
@Test
@SmallTest
public void testCurrentNotNull() {
mMostVisitedSitesMetadataUtils.setCurrentTaskForTesting(() -> {});
Runnable task1 = ()
-> mMostVisitedSitesMetadataUtils.saveSuggestionListsToFile(
createFakeSiteSuggestionTiles1());
List<Tile> task2Tiles = createFakeSiteSuggestionTiles2();
Runnable task2 = () -> mMostVisitedSitesMetadataUtils.saveSuggestionListsToFile(task2Tiles);
// If current task is not null, all saving tasks should be set as pending task.
TestThreadUtils.runOnUiThreadBlocking(() -> {
task1.run();
task2.run();
});
// newTopSites1 should be skipped and newTopSites2 should be the pending task.
assertEquals(task2Tiles.size(),
mMostVisitedSitesMetadataUtils.getPendingTaskTilesNumForTesting());
}
/**
* Test when current task is finished, the pending task should be set as current task and run.
*/
@Test
@SmallTest
public void testTasksContinuity() {
AtomicBoolean isPendingRun = new AtomicBoolean(false);
// Set and run current task.
assertNull(mMostVisitedSitesMetadataUtils.getCurrentTaskForTesting());
TestThreadUtils.runOnUiThreadBlocking(
()
-> mMostVisitedSitesMetadataUtils.saveSuggestionListsToFile(
createFakeSiteSuggestionTiles1()));
// When current task is not finished, set pending task.
assertNotNull(mMostVisitedSitesMetadataUtils.getCurrentTaskForTesting());
mMostVisitedSitesMetadataUtils.setPendingTaskForTesting(() -> isPendingRun.set(true));
// isPendingRun should eventually become true.
CriteriaHelper.pollInstrumentationThread(isPendingRun::get);
}
private static List<Tile> createFakeSiteSuggestionTiles1() {
List<Tile> suggestionTiles = new ArrayList<>();
SiteSuggestion data = new SiteSuggestion("0 TOP_SITES", new GURL("https://www.foo.com"), "",
TileTitleSource.TITLE_TAG, TileSource.TOP_SITES, TileSectionType.PERSONALIZED, TileTitleSource.TITLE_TAG, TileSource.TOP_SITES, TileSectionType.PERSONALIZED,
new Date())); new Date());
siteSuggestions.add(new SiteSuggestion("1 ALLOWLIST", new GURL("https://www.bar.com"), "", suggestionTiles.add(new Tile(data, 0));
data = new SiteSuggestion("1 ALLOWLIST", new GURL("https://www.bar.com"), "",
TileTitleSource.UNKNOWN, TileSource.ALLOWLIST, TileSectionType.PERSONALIZED, TileTitleSource.UNKNOWN, TileSource.ALLOWLIST, TileSectionType.PERSONALIZED,
new Date())); new Date());
siteSuggestions.get(1).faviconId = 1; suggestionTiles.add(new Tile(data, 1));
return siteSuggestions;
return suggestionTiles;
}
private static List<Tile> createFakeSiteSuggestionTiles2() {
List<Tile> suggestionTiles = new ArrayList<>();
SiteSuggestion data = new SiteSuggestion("0 TOP_SITES", new GURL("https://www.baz.com"), "",
TileTitleSource.TITLE_TAG, TileSource.TOP_SITES, TileSectionType.PERSONALIZED,
new Date());
suggestionTiles.add(new Tile(data, 0));
return suggestionTiles;
} }
} }
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