blob: 0073f9511838c8474089c8e1e100708c45f55e42 [file] [log] [blame]
// 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;
import android.content.Context;
import android.support.annotation.IntDef;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager;
import org.chromium.chrome.browser.favicon.FaviconHelper;
import org.chromium.chrome.browser.lifecycle.Destroyable;
import org.chromium.chrome.browser.profiles.Profile;
import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.tabmodel.TabModelSelector;
import org.chromium.chrome.browser.tasks.tab_groups.TabGroupUtils;
import org.chromium.components.feature_engagement.FeatureConstants;
import org.chromium.ui.modelutil.PropertyKey;
import org.chromium.ui.modelutil.PropertyModel;
import org.chromium.ui.modelutil.RecyclerViewAdapter;
import org.chromium.ui.modelutil.SimpleRecyclerViewMcpBase;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.List;
/**
* Coordinator for showing UI for a list of tabs. Can be used in GRID or STRIP modes.
*/
public class TabListCoordinator implements Destroyable {
/** Modes of showing the list of tabs */
@IntDef({TabListMode.GRID, TabListMode.STRIP})
@Retention(RetentionPolicy.SOURCE)
public @interface TabListMode {
int GRID = 0;
int STRIP = 1;
int NUM_ENTRIES = 2;
}
private static final int GRID_LAYOUT_SPAN_COUNT = 2;
private final SimpleRecyclerViewMcpBase mModelChangeProcessor;
private final TabListMediator mMediator;
private final TabListRecyclerView mRecyclerView;
private final @TabListMode int mMode;
/**
* Construct a coordinator for UI that shows a list of tabs.
* @param mode Modes of showing the list of tabs. Can be used in GRID or STRIP.
* @param context The context to use for accessing {@link android.content.res.Resources}.
* @param tabModelSelector {@link TabModelSelector} that will provide and receive signals about
* the tabs concerned.
* @param tabContentManager {@link TabContentManager} to provide screenshot related details.
* @param parentView {@link ViewGroup} The root view of the UI.
* @param attachToParent Whether the UI should attach to root view.
* @param componentName A unique string uses to identify different components for UMA recording.
* Recommended to use the class name or make sure the string is unique
* through actions.xml file.
*/
TabListCoordinator(@TabListMode int mode, Context context, TabModelSelector tabModelSelector,
TabContentManager tabContentManager, @NonNull ViewGroup parentView,
boolean attachToParent, String componentName) {
TabListModel tabListModel = new TabListModel();
mMode = mode;
RecyclerViewAdapter adapter;
if (mMode == TabListMode.GRID) {
SimpleRecyclerViewMcpBase<PropertyModel, TabGridViewHolder, PropertyKey> mcp =
new SimpleRecyclerViewMcpBase<>(
null, TabGridViewBinder::onBindViewHolder, tabListModel);
adapter = new RecyclerViewAdapter<>(mcp, TabGridViewHolder::create);
mModelChangeProcessor = mcp;
} else if (mMode == TabListMode.STRIP) {
SimpleRecyclerViewMcpBase<PropertyModel, TabStripViewHolder, PropertyKey> mcp =
new SimpleRecyclerViewMcpBase<>(
null, TabStripViewBinder::onBindViewHolder, tabListModel);
adapter = new RecyclerViewAdapter<>(mcp, TabStripViewHolder::create);
mModelChangeProcessor = mcp;
} else {
throw new IllegalArgumentException(
"Attempting to create a tab list UI with invalid mode");
}
if (!attachToParent) {
mRecyclerView = (TabListRecyclerView) LayoutInflater.from(context).inflate(
R.layout.tab_list_recycler_view_layout, parentView, false);
} else {
LayoutInflater.from(context).inflate(
R.layout.tab_list_recycler_view_layout, parentView, true);
mRecyclerView = parentView.findViewById(R.id.tab_list_view);
}
mRecyclerView.setAdapter(adapter);
if (mMode == TabListMode.GRID) {
mRecyclerView.setLayoutManager(new GridLayoutManager(context, GRID_LAYOUT_SPAN_COUNT));
} else if (mMode == TabListMode.STRIP) {
mRecyclerView.setLayoutManager(
new LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false));
}
mRecyclerView.setHasFixedSize(true);
mMediator = new TabListMediator(Profile.getLastUsedProfile(), tabListModel, context,
tabModelSelector, tabContentManager, new FaviconHelper(), componentName);
}
/**
* @return The container {@link android.support.v7.widget.RecyclerView} that is showing the
* tab list UI.
*/
public TabListRecyclerView getContainerView() {
return mRecyclerView;
}
/**
* Reset the tab grid with the given List of Tabs. Can be null.
* @param tabs List of Tabs to show for in the UI.
*/
public void resetWithListOfTabs(@Nullable List<Tab> tabs) {
mMediator.resetWithListOfTabs(tabs);
if (mMode == TabListMode.STRIP && tabs != null && tabs.size() > 1) {
TabGroupUtils.maybeShowIPH(
FeatureConstants.TAB_GROUPS_TAP_TO_SEE_ANOTHER_TAB_FEATURE, mRecyclerView);
}
}
/**
* Destroy any members that needs clean up.
*/
@Override
public void destroy() {
mMediator.destroy();
}
}