Commit f436da6b authored by David Maunder's avatar David Maunder Committed by Commit Bot

Add TabSuggestionsObserver and start passing messages from Orchestrator

TabSuggestionsObserver is used by the orchestrator to broadcast
messages about new suggestion results and when tabContexts
become invalidated.

Bug: 1017896
Change-Id: I5ba99bd920a8fefccf94a3b7137e7dff8bb1074c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1879600
Commit-Queue: David Maunder <davidjm@chromium.org>
Reviewed-by: default avatarYusuf Ozuysal <yusufo@chromium.org>
Reviewed-by: default avatarMei Liang <meiliang@chromium.org>
Cr-Commit-Position: refs/heads/master@{#712108}
parent c49ee98c
......@@ -4,9 +4,19 @@
package org.chromium.chrome.browser.tasks.tab_management.suggestions;
import java.util.List;
/**
* Interface for the Tab Suggestions framework.
*/
public interface TabSuggestions { List<TabSuggestion> getSuggestions(TabContext tabContext); }
public interface TabSuggestions {
/**
* Adds an observer
* @param tabSuggestionsObserver observer which is notified when new suggestions are available
*/
void addObserver(TabSuggestionsObserver tabSuggestionsObserver);
/**
* Removes an observer
* @param tabSuggestionsObserver observer which is notified when new suggestions are available
*/
void removeObserver(TabSuggestionsObserver tabSuggestionsObserver);
}
// Copyright 2019 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.tasks.tab_management.suggestions;
import java.util.List;
/**
* Observes when new Tab Suggestions become available
*/
public interface TabSuggestionsObserver {
/**
* Notify when we have new Tab Suggestions
* @param tabSuggestions tab suggestions acquired
*/
void onNewSuggestion(List<TabSuggestion> tabSuggestions);
/**
* Notify when a {@link TabContext} is no longer valid/representative of the user's tabs.
*/
void onTabSuggestionInvalidated();
}
......@@ -4,6 +4,7 @@
package org.chromium.chrome.browser.tasks.tab_management.suggestions;
import org.chromium.base.ObserverList;
import org.chromium.chrome.browser.lifecycle.ActivityLifecycleDispatcher;
import org.chromium.chrome.browser.lifecycle.Destroyable;
import org.chromium.chrome.browser.tabmodel.TabModelSelector;
......@@ -27,15 +28,26 @@ public class TabSuggestionsOrchestrator implements TabSuggestions, Destroyable {
private List<TabSuggestion> mPrefetchedResults = new LinkedList<>();
private TabContext mPrefetchedTabContext;
private TabModelSelector mTabModelSelector;
private ObserverList<TabSuggestionsObserver> mTabSuggestionsObservers;
private int mRemainingFetchers;
public TabSuggestionsOrchestrator(
TabModelSelector selector, ActivityLifecycleDispatcher activityLifecycleDispatcher) {
mTabModelSelector = selector;
mTabSuggestionsFetchers = new LinkedList<>();
mTabSuggestionsFetchers.add(new TabSuggestionsClientFetcher());
mTabSuggestionsObservers = new ObserverList<>();
mTabContextObserver = new TabContextObserver(selector) {
@Override
public void onTabContextChanged(@TabContextChangeReason int changeReason) {
synchronized (mPrefetchedResults) {
if (mPrefetchedTabContext != null) {
for (TabSuggestionsObserver tabSuggestionsObserver :
mTabSuggestionsObservers) {
tabSuggestionsObserver.onTabSuggestionInvalidated();
}
}
}
prefetchSuggestions();
}
};
......@@ -43,16 +55,6 @@ public class TabSuggestionsOrchestrator implements TabSuggestions, Destroyable {
activityLifecycleDispatcher.register(this);
}
@Override
public List<TabSuggestion> getSuggestions(TabContext tabContext) {
synchronized (mPrefetchedResults) {
if (tabContext.equals(mPrefetchedTabContext)) {
return aggregateResults(mPrefetchedResults);
}
return new LinkedList<>();
}
}
private List<TabSuggestion> aggregateResults(List<TabSuggestion> tabSuggestions) {
List<TabSuggestion> aggregated = new LinkedList<>();
for (TabSuggestion tabSuggestion : tabSuggestions) {
......@@ -90,10 +92,12 @@ public class TabSuggestionsOrchestrator implements TabSuggestions, Destroyable {
protected void prefetchSuggestions() {
TabContext tabContext = TabContext.createCurrentContext(mTabModelSelector);
synchronized (mPrefetchedResults) {
mRemainingFetchers = 0;
mPrefetchedTabContext = tabContext;
mPrefetchedResults = new LinkedList<>();
for (TabSuggestionsFetcher tabSuggestionsFetcher : mTabSuggestionsFetchers) {
if (tabSuggestionsFetcher.isEnabled()) {
mRemainingFetchers++;
tabSuggestionsFetcher.fetch(tabContext, res -> prefetchCallback(res));
}
}
......@@ -102,9 +106,28 @@ public class TabSuggestionsOrchestrator implements TabSuggestions, Destroyable {
private void prefetchCallback(TabSuggestionsFetcherResults suggestions) {
synchronized (mPrefetchedResults) {
// If the tab context has changed since the fetchers were used,
// we simply ignore the result as it is no longer relevant.
if (suggestions.tabContext.equals(mPrefetchedTabContext)) {
mRemainingFetchers--;
mPrefetchedResults.addAll(suggestions.tabSuggestions);
if (mRemainingFetchers == 0) {
for (TabSuggestionsObserver tabSuggestionsObserver : mTabSuggestionsObservers) {
tabSuggestionsObserver.onNewSuggestion(
aggregateResults(mPrefetchedResults));
}
}
}
}
}
@Override
public void addObserver(TabSuggestionsObserver tabSuggestionsObserver) {
mTabSuggestionsObservers.addObserver(tabSuggestionsObserver);
}
@Override
public void removeObserver(TabSuggestionsObserver tabSuggestionsObserver) {
mTabSuggestionsObservers.removeObserver(tabSuggestionsObserver);
}
}
......@@ -32,6 +32,7 @@ import org.chromium.chrome.browser.tabmodel.TabModelSelector;
import org.chromium.chrome.test.util.browser.Features;
import org.chromium.testing.local.LocalRobolectricTestRunner;
import java.util.LinkedList;
import java.util.List;
/**
......@@ -87,9 +88,18 @@ public class TabSuggestionsOrchestratorTest {
}
TabSuggestionsOrchestrator tabSuggestionsOrchestrator =
new TabSuggestionsOrchestrator(mTabModelSelector, mDispatcher);
List<TabSuggestion> suggestions = new LinkedList<>();
TabSuggestionsObserver tabSuggestionsObserver = new TabSuggestionsObserver() {
@Override
public void onNewSuggestion(List<TabSuggestion> tabSuggestions) {
suggestions.addAll(tabSuggestions);
}
@Override
public void onTabSuggestionInvalidated() {}
};
tabSuggestionsOrchestrator.addObserver(tabSuggestionsObserver);
tabSuggestionsOrchestrator.mTabContextObserver.mTabModelObserver.didAddTab(null, 0);
List<TabSuggestion> suggestions = tabSuggestionsOrchestrator.getSuggestions(
TabContext.createCurrentContext(mTabModelSelector));
Assert.assertEquals(1, suggestions.size());
Assert.assertEquals(TAB_IDS.length, suggestions.get(0).getTabsInfo().size());
for (int idx = 0; idx < TAB_IDS.length; idx++) {
......@@ -112,9 +122,17 @@ public class TabSuggestionsOrchestratorTest {
doReturn(sTabs[0]).when(mTabModelFilter).getTabAt(eq(0));
TabSuggestionsOrchestrator tabSuggestionsOrchestrator =
new TabSuggestionsOrchestrator(mTabModelSelector, mDispatcher);
List<TabSuggestion> suggestions = new LinkedList<>();
TabSuggestionsObserver tabSuggestionsObserver = new TabSuggestionsObserver() {
@Override
public void onNewSuggestion(List<TabSuggestion> tabSuggestions) {
suggestions.addAll(tabSuggestions);
}
@Override
public void onTabSuggestionInvalidated() {}
};
tabSuggestionsOrchestrator.mTabContextObserver.mTabModelObserver.didAddTab(null, 0);
List<TabSuggestion> suggestions = tabSuggestionsOrchestrator.getSuggestions(
TabContext.createCurrentContext(mTabModelSelector));
Assert.assertEquals(0, suggestions.size());
}
}
......@@ -17,6 +17,7 @@ public_tab_management_java_sources = [
"//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcher.java",
"//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/suggestions/TabContext.java",
"//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/suggestions/TabSuggestions.java",
"//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/suggestions/TabSuggestionsObserver.java",
"//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/suggestions/TabSuggestion.java",
]
......
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