blob: 657f5bdc24c38b278f7fa0bcfbf870a9d99cb67c [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.touchless;
import android.support.annotation.Nullable;
import android.view.View;
import org.chromium.base.Callback;
import org.chromium.chrome.browser.native_page.ContextMenuManager;
import org.chromium.chrome.browser.ntp.cards.ItemViewType;
import org.chromium.chrome.browser.ntp.cards.NewTabPageAdapter;
import org.chromium.chrome.browser.ntp.cards.NewTabPageViewHolder;
import org.chromium.chrome.browser.offlinepages.OfflinePageBridge;
import org.chromium.chrome.browser.suggestions.SuggestionsUiDelegate;
import org.chromium.chrome.browser.widget.displaystyle.UiConfig;
import org.chromium.ui.modelutil.PropertyModel;
import java.util.List;
/**
* Adds touchless specific logic that needs to be attached and/or interacted with view holders.
*/
public class TouchlessNewTabPageAdapter extends NewTabPageAdapter {
private PropertyModel mModel;
// Initial focus should only be set once. After that happens this sentinel is sent to false and
// the initial focus field should not be used.
private boolean mCheckInitialFocus = true;
/**
* Creates the adapter that will manage all the cards to display on the NTP.
* @param uiDelegate used to interact with the rest of the system.
* @param aboveTheFoldView the layout encapsulating all the above-the-fold elements
* (logo, search box, most visited tiles), or null if only suggestions should
* be displayed.
* @param uiConfig the NTP UI configuration, to be passed to created views.
* @param offlinePageBridge used to determine if articles are available.
* @param contextMenuManager used to build context menus.
* @param model the model of the recycler view component.
*/
public TouchlessNewTabPageAdapter(SuggestionsUiDelegate uiDelegate,
@Nullable View aboveTheFoldView, UiConfig uiConfig, OfflinePageBridge offlinePageBridge,
ContextMenuManager contextMenuManager, PropertyModel model) {
super(uiDelegate, aboveTheFoldView, uiConfig, offlinePageBridge, contextMenuManager);
mModel = model;
}
@Override
public void onBindViewHolder(NewTabPageViewHolder holder, int position, List<Object> payloads) {
super.onBindViewHolder(holder, position, payloads);
Callback<TouchlessNewTabPageFocusInfo> focusCallback =
mModel.get(TouchlessNewTabPageProperties.FOCUS_CHANGE_CALLBACK);
if (focusCallback != null && holder.getItemViewType() == ItemViewType.SNIPPET) {
holder.itemView.setOnFocusChangeListener((View view, boolean hasFocus) -> {
if (hasFocus) {
focusCallback.onResult(new TouchlessNewTabPageFocusInfo(
TouchlessNewTabPageFocusInfo.FocusType.ARTICLE,
holder.getAdapterPosition()));
// If focus is changing due to user interactions, the initial focus is no longer
// needed. While this flag is typically flipped when the initial focus is set,
// if the initial focus is not restored successfully, for example when the
// initial focus would be on an index larger than the initial number of cards,
// then it needs to be cleared here.
mCheckInitialFocus = false;
}
});
}
TouchlessNewTabPageFocusInfo focus =
mModel.get(TouchlessNewTabPageProperties.INITIAL_FOCUS);
if (mCheckInitialFocus && focus != null && focus.index == holder.getAdapterPosition()
&& focus.type == holder.getItemViewType()) {
holder.itemView.requestFocus();
mCheckInitialFocus = false;
}
}
}