Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(5015)

Unified Diff: chrome/android/java_staging/src/org/chromium/chrome/browser/ntp/RecentTabsRowAdapter.java

Issue 1141283003: Upstream oodles of Chrome for Android code into Chromium. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: final patch? Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/android/java_staging/src/org/chromium/chrome/browser/ntp/RecentTabsRowAdapter.java
diff --git a/chrome/android/java_staging/src/org/chromium/chrome/browser/ntp/RecentTabsRowAdapter.java b/chrome/android/java_staging/src/org/chromium/chrome/browser/ntp/RecentTabsRowAdapter.java
new file mode 100644
index 0000000000000000000000000000000000000000..882d7ee15067a1b9027a693e54b2cee0a9050bda
--- /dev/null
+++ b/chrome/android/java_staging/src/org/chromium/chrome/browser/ntp/RecentTabsRowAdapter.java
@@ -0,0 +1,835 @@
+// Copyright 2015 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.ntp;
+
+import android.app.Activity;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.text.TextUtils;
+import android.util.LruCache;
+import android.view.ContextMenu;
+import android.view.LayoutInflater;
+import android.view.MenuItem;
+import android.view.MenuItem.OnMenuItemClickListener;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseExpandableListAdapter;
+import android.widget.TextView;
+
+import com.google.android.apps.chrome.R;
+
+import org.chromium.base.ApiCompatibilityUtils;
+import org.chromium.chrome.browser.ForeignSessionHelper.ForeignSession;
+import org.chromium.chrome.browser.ForeignSessionHelper.ForeignSessionTab;
+import org.chromium.chrome.browser.ForeignSessionHelper.ForeignSessionWindow;
+import org.chromium.chrome.browser.RecentlyClosedBridge.RecentlyClosedTab;
+import org.chromium.chrome.browser.favicon.FaviconHelper.FaviconImageCallback;
+import org.chromium.ui.WindowOpenDisposition;
+import org.chromium.ui.base.DeviceFormFactor;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Row adapter for presenting recently closed tabs, synced tabs from other devices, the sync or
+ * sign in promo, and currently open tabs (only in document mode) in a grouped list view.
+ */
+public class RecentTabsRowAdapter extends BaseExpandableListAdapter {
+ private static final int MAX_NUM_FAVICONS_TO_CACHE = 256;
+
+ private enum ChildType {
+ NONE, DEFAULT_CONTENT, SYNC_PROMO
+ }
+
+ private enum GroupType {
+ CONTENT, VISIBLE_SEPARATOR, INVISIBLE_SEPARATOR
+ }
+
+ private final Activity mActivity;
+ private final ArrayList<Group> mGroups;
+ private final Drawable mDefaultFavicon;
+ private final RecentTabsManager mRecentTabsManager;
+ private final RecentlyClosedTabsGroup mRecentlyClosedTabsGroup = new RecentlyClosedTabsGroup();
+ private final SeparatorGroup mVisibleSeparatorGroup = new SeparatorGroup(true);
+ private final SeparatorGroup mInvisibleSeparatorGroup = new SeparatorGroup(false);
+ private final long mInitializationTimestamp; // Seconds since Unix epoch.
+ private final FaviconCache mFaviconCache;
+ private final int mFaviconSize;
+
+ /**
+ * A generic group of objects to be shown in the RecentTabsRowAdapter, such as the list of
+ * recently closed tabs.
+ */
+ abstract class Group {
+ /**
+ * @return The type of group: GroupType.CONTENT or GroupType.SEPARATOR.
+ */
+ abstract GroupType getGroupType();
+
+ /**
+ * @return The number of children in this group.
+ */
+ abstract int getChildrenCount();
+
+ /**
+ * @return The child type.
+ */
+ abstract ChildType getChildType();
+
+
+ /**
+ * @return The child at the position childPosition.
+ */
+ abstract Object getChild(int childPosition);
+
+ /**
+ * Returns the view corresponding to the child view at a given position.
+ *
+ * @param childPosition The position of the child.
+ * @param isLastChild Whether this child is the last one.
+ * @param convertView The re-usable child view (may be null).
+ * @param parent The parent view group.
+ *
+ * @return The view corresponding to the child.
+ */
+ View getChildView(int childPosition, boolean isLastChild,
+ View convertView, ViewGroup parent) {
+ View childView = convertView;
+ if (childView == null) {
+ LayoutInflater inflater = LayoutInflater.from(mActivity);
+ childView = inflater.inflate(R.layout.recent_tabs_list_item, parent, false);
+
+ ViewHolder viewHolder = new ViewHolder();
+ viewHolder.textView = (TextView) childView;
+ childView.setTag(viewHolder);
+ }
+
+ ViewHolder viewHolder = (ViewHolder) childView.getTag();
+ configureChildView(childPosition, viewHolder);
+
+ return childView;
+ }
+
+ /**
+ * Configures a view inflated from recent_tabs_list_item.xml to display information about
+ * a child in this group.
+ *
+ * @param childPosition The position of the child within this group.
+ * @param viewHolder The ViewHolder with references to pieces of the view.
+ */
+ abstract void configureChildView(int childPosition, ViewHolder viewHolder);
+
+ /**
+ * Returns the view corresponding to this group.
+ *
+ * @param isExpanded Whether the group is expanded.
+ * @param convertView The re-usable group view (may be null).
+ * @param parent The parent view group.
+ *
+ * @return The view corresponding to the group.
+ */
+ public View getGroupView(boolean isExpanded, View convertView, ViewGroup parent) {
+ assert convertView == null || convertView instanceof RecentTabsGroupView;
+ RecentTabsGroupView groupView = (RecentTabsGroupView) convertView;
+ if (groupView == null) {
+ groupView = (RecentTabsGroupView) LayoutInflater.from(mActivity).inflate(
+ R.layout.recent_tabs_group_item, parent, false);
+ groupView.initialize(mInitializationTimestamp);
+ }
+ configureGroupView(groupView, isExpanded);
+ return groupView;
+ }
+
+ /**
+ * Configures an RecentTabsGroupView to display the header of this group.
+ * @param groupView The RecentTabsGroupView to configure.
+ * @param isExpanded Whether the view is currently expanded.
+ */
+ abstract void configureGroupView(RecentTabsGroupView groupView, boolean isExpanded);
+
+ /**
+ * Sets whether this group is collapsed (i.e. whether only the header is visible).
+ */
+ abstract void setCollapsed(boolean isCollapsed);
+
+ /**
+ * @return Whether this group is collapsed.
+ */
+ abstract boolean isCollapsed();
+
+ /**
+ * Called when a child item is clicked.
+ * @param childPosition The position of the child in the group.
+ * @return Whether the click was handled.
+ */
+ abstract boolean onChildClick(int childPosition);
+
+ /**
+ * Called when the context menu for the group view is being built.
+ * @param menu The context menu being built.
+ * @param activity The current activity.
+ */
+ void onCreateContextMenuForGroup(ContextMenu menu, Activity activity) {
+ }
+
+ /**
+ * Called when a context menu for one of the child views is being built.
+ * @param childPosition The position of the child in the group.
+ * @param menu The context menu being built.
+ * @param activity The current activity.
+ */
+ void onCreateContextMenuForChild(int childPosition, ContextMenu menu,
+ Activity activity) {
+ }
+ }
+
+ /**
+ * A group containing all the tabs currently open on this device.
+ */
+ class CurrentlyOpenTabsGroup extends Group {
+ private static final int NUM_DEFAULT_VISIBLE_TABS = 6;
+
+ private final List<CurrentlyOpenTab> mCurrentlyOpenTabs;
+ private final boolean mShowingAll;
+
+ public CurrentlyOpenTabsGroup(List<CurrentlyOpenTab> tabsList) {
+ mCurrentlyOpenTabs = tabsList;
+ mShowingAll = mRecentTabsManager.isCurrentlyOpenTabsShowingAll();
+ }
+
+ private boolean isMoreButton(int childPosition) {
+ return !mShowingAll && childPosition
+ == Math.min(NUM_DEFAULT_VISIBLE_TABS, mCurrentlyOpenTabs.size());
+ }
+
+ @Override
+ GroupType getGroupType() {
+ return GroupType.CONTENT;
+ }
+
+ @Override
+ int getChildrenCount() {
+ if (mShowingAll) return mCurrentlyOpenTabs.size();
+ return Math.min(NUM_DEFAULT_VISIBLE_TABS, mCurrentlyOpenTabs.size() - 1) + 1;
+ }
+
+ @Override
+ ChildType getChildType() {
+ return ChildType.DEFAULT_CONTENT;
+ }
+
+ @Override
+ CurrentlyOpenTab getChild(int childPosition) {
+ if (isMoreButton(childPosition)) return null;
+
+ return mCurrentlyOpenTabs.get(childPosition);
+ }
+
+ @Override
+ void configureChildView(int childPosition, ViewHolder viewHolder) {
+ if (isMoreButton(childPosition)) {
+ Resources resources = mActivity.getResources();
+ String text = resources.getString(R.string.recent_tabs_show_more);
+ viewHolder.textView.setText(text);
+ Drawable drawable = ApiCompatibilityUtils.getDrawable(
+ resources, R.drawable.more_horiz);
+ ApiCompatibilityUtils.setCompoundDrawablesRelativeWithIntrinsicBounds(
+ viewHolder.textView, drawable, null, null, null);
+ } else {
+ CurrentlyOpenTab openTab = getChild(childPosition);
+ viewHolder.textView.setText(TextUtils.isEmpty(openTab.getTitle()) ? openTab.getUrl()
+ : openTab.getTitle());
+ loadLocalFavicon(viewHolder, openTab.getUrl());
+ }
+ }
+
+ @Override
+ void configureGroupView(RecentTabsGroupView groupView, boolean isExpanded) {
+ groupView.configureForCurrentlyOpenTabs(isExpanded);
+ }
+
+ @Override
+ void setCollapsed(boolean isCollapsed) {
+ mRecentTabsManager.setCurrentlyOpenTabsCollapsed(isCollapsed);
+ }
+
+ @Override
+ boolean isCollapsed() {
+ return mRecentTabsManager.isCurrentlyOpenTabsCollapsed();
+ }
+
+ @Override
+ boolean onChildClick(int childPosition) {
+ if (isMoreButton(childPosition)) {
+ mRecentTabsManager.setCurrentlyOpenTabsShowAll(true);
+ } else {
+ getChild(childPosition).getRunnable().run();
+ }
+ return true;
+ }
+ }
+
+ /**
+ * A group containing all the tabs associated with a foreign session from a synced device.
+ */
+ class ForeignSessionGroup extends Group {
+ private final ForeignSession mForeignSession;
+
+ ForeignSessionGroup(ForeignSession foreignSession) {
+ mForeignSession = foreignSession;
+ }
+
+ @Override
+ public GroupType getGroupType() {
+ return GroupType.CONTENT;
+ }
+
+ @Override
+ public int getChildrenCount() {
+ int count = 0;
+ for (ForeignSessionWindow window : mForeignSession.windows) {
+ count += window.tabs.size();
+ }
+ return count;
+ }
+
+ @Override
+ public ChildType getChildType() {
+ return ChildType.DEFAULT_CONTENT;
+ }
+
+ @Override
+ public ForeignSessionTab getChild(int childPosition) {
+ for (ForeignSessionWindow window : mForeignSession.windows) {
+ if (childPosition < window.tabs.size()) {
+ return window.tabs.get(childPosition);
+ }
+ childPosition -= window.tabs.size();
+ }
+ assert false;
+ return null;
+ }
+
+ @Override
+ public void configureChildView(int childPosition, ViewHolder viewHolder) {
+ ForeignSessionTab sessionTab = getChild(childPosition);
+ viewHolder.textView.setText(TextUtils.isEmpty(sessionTab.title) ? sessionTab.url
+ : sessionTab.title);
+ loadSyncedFavicon(viewHolder, sessionTab.url);
+ }
+
+ @Override
+ public void configureGroupView(RecentTabsGroupView groupView, boolean isExpanded) {
+ groupView.configureForForeignSession(mForeignSession, isExpanded);
+ }
+
+ @Override
+ public void setCollapsed(boolean isCollapsed) {
+ mRecentTabsManager.setForeignSessionCollapsed(mForeignSession, isCollapsed);
+ }
+
+ @Override
+ public boolean isCollapsed() {
+ return mRecentTabsManager.getForeignSessionCollapsed(mForeignSession);
+ }
+
+ @Override
+ public boolean onChildClick(int childPosition) {
+ ForeignSessionTab foreignSessionTab = getChild(childPosition);
+ mRecentTabsManager.openForeignSessionTab(mForeignSession, foreignSessionTab,
+ WindowOpenDisposition.CURRENT_TAB);
+ return true;
+ }
+
+ @Override
+ public void onCreateContextMenuForGroup(ContextMenu menu, Activity activity) {
+ OnMenuItemClickListener listener = new OnMenuItemClickListener() {
+ @Override
+ public boolean onMenuItemClick(MenuItem item) {
+ mRecentTabsManager.deleteForeignSession(mForeignSession);
+ return true;
+ }
+ };
+ menu.add(R.string.ntp_recent_tabs_remove_menu_option)
+ .setOnMenuItemClickListener(listener);
+ }
+
+ @Override
+ public void onCreateContextMenuForChild(int childPosition, ContextMenu menu,
+ Activity activity) {
+ final ForeignSessionTab foreignSessionTab = getChild(childPosition);
+ OnMenuItemClickListener listener = new OnMenuItemClickListener() {
+ @Override
+ public boolean onMenuItemClick(MenuItem item) {
+ mRecentTabsManager.openForeignSessionTab(mForeignSession, foreignSessionTab,
+ WindowOpenDisposition.NEW_BACKGROUND_TAB);
+ return true;
+ }
+ };
+ menu.add(R.string.contextmenu_open_in_new_tab).setOnMenuItemClickListener(listener);
+ }
+ }
+
+ /**
+ * A group containing tabs that were recently closed on this device and a link to the history
+ * page.
+ */
+ class RecentlyClosedTabsGroup extends Group {
+ private static final int ID_OPEN_IN_NEW_TAB = 1;
+ private static final int ID_REMOVE_ALL = 2;
+
+ @Override
+ public GroupType getGroupType() {
+ return GroupType.CONTENT;
+ }
+
+ @Override
+ public int getChildrenCount() {
+ // The number of children is the number of recently closed tabs, plus one for the "Show
+ // full history" item.
+ return 1 + mRecentTabsManager.getRecentlyClosedTabs().size();
+ }
+
+ @Override
+ public ChildType getChildType() {
+ return ChildType.DEFAULT_CONTENT;
+ }
+
+ /**
+ * @param childPosition The index of an item in the recently closed list.
+ * @return Whether the item at childPosition is the link to the history page.
+ */
+ private boolean isHistoryLink(int childPosition) {
+ return childPosition == mRecentTabsManager.getRecentlyClosedTabs().size();
+ }
+
+ @Override
+ public RecentlyClosedTab getChild(int childPosition) {
+ if (isHistoryLink(childPosition)) {
+ return null;
+ }
+ return mRecentTabsManager.getRecentlyClosedTabs().get(childPosition);
+ }
+
+ @Override
+ public void configureChildView(int childPosition, ViewHolder viewHolder) {
+ if (isHistoryLink(childPosition)) {
+ viewHolder.textView.setText(R.string.show_full_history);
+ ApiCompatibilityUtils.setCompoundDrawablesRelativeWithIntrinsicBounds(
+ viewHolder.textView, R.drawable.history_favicon, 0, 0, 0);
+ } else {
+ RecentlyClosedTab tab = getChild(childPosition);
+ String title = NewTabPageView.getTitleForDisplay(tab.title, tab.url);
+ viewHolder.textView.setText(title);
+ loadLocalFavicon(viewHolder, tab.url);
+ }
+ }
+
+ @Override
+ public void configureGroupView(RecentTabsGroupView groupView, boolean isExpanded) {
+ groupView.configureForRecentlyClosedTabs(isExpanded);
+ }
+
+ @Override
+ public void setCollapsed(boolean isCollapsed) {
+ mRecentTabsManager.setRecentlyClosedTabsCollapsed(isCollapsed);
+ }
+
+ @Override
+ public boolean isCollapsed() {
+ return mRecentTabsManager.isRecentlyClosedTabsCollapsed();
+ }
+
+ @Override
+ public boolean onChildClick(int childPosition) {
+ if (isHistoryLink(childPosition)) {
+ mRecentTabsManager.openHistoryPage();
+ } else {
+ mRecentTabsManager.openRecentlyClosedTab(getChild(childPosition),
+ WindowOpenDisposition.CURRENT_TAB);
+ }
+ return true;
+ }
+
+ @Override
+ public void onCreateContextMenuForGroup(ContextMenu menu, Activity activity) {
+ }
+
+ @Override
+ public void onCreateContextMenuForChild(final int childPosition, ContextMenu menu,
+ Activity activity) {
+ final RecentlyClosedTab recentlyClosedTab = getChild(childPosition);
+ if (recentlyClosedTab == null) return;
+ OnMenuItemClickListener listener = new OnMenuItemClickListener() {
+ @Override
+ public boolean onMenuItemClick(MenuItem item) {
+ switch (item.getItemId()) {
+ case ID_REMOVE_ALL:
+ mRecentTabsManager.clearRecentlyClosedTabs();
+ break;
+ case ID_OPEN_IN_NEW_TAB:
+ mRecentTabsManager.openRecentlyClosedTab(recentlyClosedTab,
+ WindowOpenDisposition.NEW_BACKGROUND_TAB);
+ break;
+ default:
+ assert false;
+ }
+ return true;
+ }
+ };
+ menu.add(ContextMenu.NONE, ID_OPEN_IN_NEW_TAB, ContextMenu.NONE,
+ R.string.contextmenu_open_in_new_tab).setOnMenuItemClickListener(listener);
+ menu.add(ContextMenu.NONE, ID_REMOVE_ALL, ContextMenu.NONE,
+ R.string.remove_all).setOnMenuItemClickListener(listener);
+ }
+ }
+
+ /**
+ * A group containing a blank separator.
+ */
+ class SeparatorGroup extends Group {
+ private final boolean mIsVisible;
+
+ public SeparatorGroup(boolean isVisible) {
+ mIsVisible = isVisible;
+ }
+
+ @Override
+ public GroupType getGroupType() {
+ return mIsVisible ? GroupType.VISIBLE_SEPARATOR : GroupType.INVISIBLE_SEPARATOR;
+ }
+
+ @Override
+ public ChildType getChildType() {
+ return ChildType.NONE;
+ }
+
+ @Override
+ public int getChildrenCount() {
+ return 0;
+ }
+
+ @Override
+ public View getGroupView(boolean isExpanded, View convertView, ViewGroup parent) {
+ if (convertView == null) {
+ int layout = mIsVisible
+ ? R.layout.recent_tabs_group_separator_visible
+ : R.layout.recent_tabs_group_separator_invisible;
+ convertView = LayoutInflater.from(mActivity).inflate(layout, parent, false);
+ }
+ return convertView;
+ }
+
+ @Override
+ public void configureGroupView(RecentTabsGroupView groupView, boolean isExpanded) {
+ }
+
+ @Override
+ public void configureChildView(int childPosition, ViewHolder viewHolder) {
+ }
+
+ @Override
+ public Object getChild(int childPosition) {
+ return null;
+ }
+
+ @Override
+ public void setCollapsed(boolean isCollapsed) {
+ }
+
+ @Override
+ public boolean isCollapsed() {
+ return false;
+ }
+
+ @Override
+ public boolean onChildClick(int childPosition) {
+ return false;
+ }
+ }
+
+ /**
+ * A group containing the Sync Promo.
+ */
+ class SyncPromoGroup extends Group {
+ @Override
+ public GroupType getGroupType() {
+ return GroupType.CONTENT;
+ }
+
+ @Override
+ public ChildType getChildType() {
+ return ChildType.SYNC_PROMO;
+ }
+
+ @Override
+ public int getChildrenCount() {
+ return 1;
+ }
+
+ @Override
+ public Object getChild(int childPosition) {
+ return null;
+ }
+
+ @Override
+ View getChildView(int childPosition, boolean isLastChild, View convertView,
+ ViewGroup parent) {
+ if (convertView == null) {
+ convertView = new RecentTabsPromoView(mActivity, mRecentTabsManager, null);
+ }
+ return convertView;
+ }
+
+ @Override
+ public void configureChildView(int childPosition, ViewHolder viewHolder) {
+ }
+
+ @Override
+ public void configureGroupView(RecentTabsGroupView groupView, boolean isExpanded) {
+ groupView.configureForSyncPromo(isExpanded);
+ }
+
+ @Override
+ public void setCollapsed(boolean isCollapsed) {
+ mRecentTabsManager.setSyncPromoCollapsed(isCollapsed);
+ }
+
+ @Override
+ public boolean isCollapsed() {
+ return mRecentTabsManager.isSyncPromoCollapsed();
+ }
+
+ @Override
+ public boolean onChildClick(int childPosition) {
+ return false;
+ }
+ }
+
+ private static class FaviconCache {
+ private static final String SYNCED_FAVICON_PREFIX = "Synced";
+ private static final String LOCAL_FAVICON_PREFIX = "Local";
+
+ private final LruCache<String, Drawable> mMemoryCache;
+
+ public FaviconCache(int size) {
+ mMemoryCache = new LruCache<String, Drawable>(size);
+ }
+
+ public Drawable getSyncedFaviconImage(String url) {
+ return mMemoryCache.get(SYNCED_FAVICON_PREFIX + url);
+ }
+
+ public void putSycnedFaviconImage(String url, Drawable image) {
+ mMemoryCache.put(SYNCED_FAVICON_PREFIX + url, image);
+ }
+
+ public Drawable getLocalFaviconImage(String url) {
+ return mMemoryCache.get(LOCAL_FAVICON_PREFIX + url);
+ }
+
+ public void putLocalFaviconImage(String url, Drawable image) {
+ mMemoryCache.put(LOCAL_FAVICON_PREFIX + url, image);
+ }
+ }
+
+ /**
+ * Creates an RecentTabsRowAdapter used to populate an ExpandableList with other
+ * devices and foreign tab cells.
+ *
+ * @param activity The Android activity this adapter will work in.
+ * @param recentTabsManager The RecentTabsManager that will act as the data source.
+ */
+ public RecentTabsRowAdapter(Activity activity, RecentTabsManager recentTabsManager) {
+ mActivity = activity;
+ mRecentTabsManager = recentTabsManager;
+ mGroups = new ArrayList<Group>();
+ mInitializationTimestamp =
+ TimeUnit.SECONDS.convert(System.currentTimeMillis(), TimeUnit.MILLISECONDS);
+ mFaviconCache = buildFaviconCache(MAX_NUM_FAVICONS_TO_CACHE);
+
+ Resources resources = activity.getResources();
+ mDefaultFavicon = ApiCompatibilityUtils.getDrawable(resources, R.drawable.default_favicon);
+ mFaviconSize = mDefaultFavicon.getIntrinsicHeight();
+ }
+
+ private static FaviconCache buildFaviconCache(int size) {
+ return new FaviconCache(size);
+ }
+
+ /**
+ * ViewHolder class optimizes looking up table row fields. findViewById is only called once
+ * per row view initialization, and the references are cached here. Also stores a reference to
+ * the favicon image callback; so that we can make sure we load the correct favicon.
+ */
+ private static class ViewHolder {
+ public TextView textView;
+ public FaviconImageCallback imageCallback;
+ }
+
+ private Drawable faviconDrawable(Bitmap image) {
+ if (image == null) return null;
+ return new BitmapDrawable(mActivity.getResources(), Bitmap.createScaledBitmap(image,
+ mFaviconSize, mFaviconSize, true));
+ }
+
+ private void loadSyncedFavicon(final ViewHolder viewHolder, final String url) {
+ Drawable image = mFaviconCache.getSyncedFaviconImage(url);
+ if (image == null) {
+ image = faviconDrawable(mRecentTabsManager.getSyncedFaviconImageForURL(url));
+ image = (image == null) ? mDefaultFavicon : image;
+ mFaviconCache.putSycnedFaviconImage(url, image);
+ }
+ ApiCompatibilityUtils.setCompoundDrawablesRelativeWithIntrinsicBounds(viewHolder.textView,
+ image, null, null, null);
+ }
+
+ private void loadLocalFavicon(final ViewHolder viewHolder, final String url) {
+ Drawable image;
+ if (url == null) {
+ // URL is null for print jobs, for example.
+ image = mDefaultFavicon;
+ } else {
+ image = mFaviconCache.getLocalFaviconImage(url);
+ if (image == null) {
+ FaviconImageCallback imageCallback = new FaviconImageCallback() {
+ @Override
+ public void onFaviconAvailable(Bitmap bitmap, String iconUrl) {
+ if (this != viewHolder.imageCallback) return;
+ Drawable image = faviconDrawable(bitmap);
+ image = (image == null) ? mDefaultFavicon : image;
+ mFaviconCache.putLocalFaviconImage(url, image);
+ ApiCompatibilityUtils.setCompoundDrawablesRelativeWithIntrinsicBounds(
+ viewHolder.textView, image, null, null, null);
+ }
+ };
+ viewHolder.imageCallback = imageCallback;
+ mRecentTabsManager.getLocalFaviconForUrl(url, mFaviconSize, imageCallback);
+ image = mDefaultFavicon;
+ }
+ }
+ ApiCompatibilityUtils.setCompoundDrawablesRelativeWithIntrinsicBounds(viewHolder.textView,
+ image, null, null, null);
+ }
+
+ @Override
+ public View getChildView(int groupPosition, int childPosition, boolean isLastChild,
+ View convertView, ViewGroup parent) {
+ return getGroup(groupPosition).getChildView(childPosition, isLastChild, convertView,
+ parent);
+ }
+
+ // BaseExpandableListAdapter group related implementations
+ @Override
+ public int getGroupCount() {
+ return mGroups.size();
+ }
+
+ @Override
+ public long getGroupId(int groupPosition) {
+ return groupPosition;
+ }
+
+ @Override
+ public Group getGroup(int groupPosition) {
+ return mGroups.get(groupPosition);
+ }
+
+ @Override
+ public View getGroupView(int groupPosition, boolean isExpanded, View convertView,
+ ViewGroup parent) {
+ return getGroup(groupPosition).getGroupView(isExpanded, convertView, parent);
+ }
+
+ // BaseExpandableListAdapter child related implementations
+ @Override
+ public int getChildrenCount(int groupPosition) {
+ return getGroup(groupPosition).getChildrenCount();
+ }
+
+ @Override
+ public long getChildId(int groupPosition, int childPosition) {
+ return childPosition;
+ }
+
+ @Override
+ public Object getChild(int groupPosition, int childPosition) {
+ return getGroup(groupPosition).getChild(childPosition);
+ }
+
+ @Override
+ public boolean isChildSelectable(int groupPosition, int childPosition) {
+ return true;
+ }
+
+ // BaseExpandableListAdapter misc. implementation
+ @Override
+ public boolean hasStableIds() {
+ return false;
+ }
+
+ @Override
+ public int getGroupType(int groupPosition) {
+ return getGroup(groupPosition).getGroupType().ordinal();
+ }
+
+ @Override
+ public int getGroupTypeCount() {
+ return GroupType.values().length;
+ }
+
+ private void addGroup(Group group) {
+ if (!DeviceFormFactor.isTablet(mActivity)) {
+ mGroups.add(group);
+ } else {
+ if (mGroups.size() == 0) {
+ mGroups.add(mInvisibleSeparatorGroup);
+ }
+ mGroups.add(group);
+ mGroups.add(mInvisibleSeparatorGroup);
+ }
+ }
+
+ @Override
+ public void notifyDataSetChanged() {
+ mGroups.clear();
+ List<CurrentlyOpenTab> tabList = mRecentTabsManager.getCurrentlyOpenTabs();
+ if (tabList != null && !tabList.isEmpty()) {
+ addGroup(new CurrentlyOpenTabsGroup(tabList));
+ }
+ addGroup(mRecentlyClosedTabsGroup);
+ for (ForeignSession session : mRecentTabsManager.getForeignSessions()) {
+ addGroup(new ForeignSessionGroup(session));
+ }
+ if (mRecentTabsManager.shouldDisplaySyncPromo()) {
+ addGroup(new SyncPromoGroup());
+ }
+
+ // Add separator line after the recently closed tabs group.
+ int recentlyClosedIndex = mGroups.indexOf(mRecentlyClosedTabsGroup);
+ if (DeviceFormFactor.isTablet(mActivity)) {
+ if (recentlyClosedIndex != mGroups.size() - 2) {
+ mGroups.set(recentlyClosedIndex + 1, mVisibleSeparatorGroup);
+ }
+ } else if (recentlyClosedIndex != mGroups.size() - 1) {
+ mGroups.add(recentlyClosedIndex + 1, mVisibleSeparatorGroup);
+ }
+
+ super.notifyDataSetChanged();
+ }
+
+ @Override
+ public int getChildType(int groupPosition, int childPosition) {
+ return mGroups.get(groupPosition).getChildType().ordinal();
+ }
+
+ @Override
+ public int getChildTypeCount() {
+ return ChildType.values().length;
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698