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

Side by Side 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 package org.chromium.chrome.browser.ntp;
6
7 import android.app.Activity;
8 import android.content.res.Resources;
9 import android.graphics.Bitmap;
10 import android.graphics.drawable.BitmapDrawable;
11 import android.graphics.drawable.Drawable;
12 import android.text.TextUtils;
13 import android.util.LruCache;
14 import android.view.ContextMenu;
15 import android.view.LayoutInflater;
16 import android.view.MenuItem;
17 import android.view.MenuItem.OnMenuItemClickListener;
18 import android.view.View;
19 import android.view.ViewGroup;
20 import android.widget.BaseExpandableListAdapter;
21 import android.widget.TextView;
22
23 import com.google.android.apps.chrome.R;
24
25 import org.chromium.base.ApiCompatibilityUtils;
26 import org.chromium.chrome.browser.ForeignSessionHelper.ForeignSession;
27 import org.chromium.chrome.browser.ForeignSessionHelper.ForeignSessionTab;
28 import org.chromium.chrome.browser.ForeignSessionHelper.ForeignSessionWindow;
29 import org.chromium.chrome.browser.RecentlyClosedBridge.RecentlyClosedTab;
30 import org.chromium.chrome.browser.favicon.FaviconHelper.FaviconImageCallback;
31 import org.chromium.ui.WindowOpenDisposition;
32 import org.chromium.ui.base.DeviceFormFactor;
33
34 import java.util.ArrayList;
35 import java.util.List;
36 import java.util.concurrent.TimeUnit;
37
38 /**
39 * Row adapter for presenting recently closed tabs, synced tabs from other devic es, the sync or
40 * sign in promo, and currently open tabs (only in document mode) in a grouped l ist view.
41 */
42 public class RecentTabsRowAdapter extends BaseExpandableListAdapter {
43 private static final int MAX_NUM_FAVICONS_TO_CACHE = 256;
44
45 private enum ChildType {
46 NONE, DEFAULT_CONTENT, SYNC_PROMO
47 }
48
49 private enum GroupType {
50 CONTENT, VISIBLE_SEPARATOR, INVISIBLE_SEPARATOR
51 }
52
53 private final Activity mActivity;
54 private final ArrayList<Group> mGroups;
55 private final Drawable mDefaultFavicon;
56 private final RecentTabsManager mRecentTabsManager;
57 private final RecentlyClosedTabsGroup mRecentlyClosedTabsGroup = new Recentl yClosedTabsGroup();
58 private final SeparatorGroup mVisibleSeparatorGroup = new SeparatorGroup(tru e);
59 private final SeparatorGroup mInvisibleSeparatorGroup = new SeparatorGroup(f alse);
60 private final long mInitializationTimestamp; // Seconds since Unix epoch.
61 private final FaviconCache mFaviconCache;
62 private final int mFaviconSize;
63
64 /**
65 * A generic group of objects to be shown in the RecentTabsRowAdapter, such as the list of
66 * recently closed tabs.
67 */
68 abstract class Group {
69 /**
70 * @return The type of group: GroupType.CONTENT or GroupType.SEPARATOR.
71 */
72 abstract GroupType getGroupType();
73
74 /**
75 * @return The number of children in this group.
76 */
77 abstract int getChildrenCount();
78
79 /**
80 * @return The child type.
81 */
82 abstract ChildType getChildType();
83
84
85 /**
86 * @return The child at the position childPosition.
87 */
88 abstract Object getChild(int childPosition);
89
90 /**
91 * Returns the view corresponding to the child view at a given position.
92 *
93 * @param childPosition The position of the child.
94 * @param isLastChild Whether this child is the last one.
95 * @param convertView The re-usable child view (may be null).
96 * @param parent The parent view group.
97 *
98 * @return The view corresponding to the child.
99 */
100 View getChildView(int childPosition, boolean isLastChild,
101 View convertView, ViewGroup parent) {
102 View childView = convertView;
103 if (childView == null) {
104 LayoutInflater inflater = LayoutInflater.from(mActivity);
105 childView = inflater.inflate(R.layout.recent_tabs_list_item, par ent, false);
106
107 ViewHolder viewHolder = new ViewHolder();
108 viewHolder.textView = (TextView) childView;
109 childView.setTag(viewHolder);
110 }
111
112 ViewHolder viewHolder = (ViewHolder) childView.getTag();
113 configureChildView(childPosition, viewHolder);
114
115 return childView;
116 }
117
118 /**
119 * Configures a view inflated from recent_tabs_list_item.xml to display information about
120 * a child in this group.
121 *
122 * @param childPosition The position of the child within this group.
123 * @param viewHolder The ViewHolder with references to pieces of the vie w.
124 */
125 abstract void configureChildView(int childPosition, ViewHolder viewHolde r);
126
127 /**
128 * Returns the view corresponding to this group.
129 *
130 * @param isExpanded Whether the group is expanded.
131 * @param convertView The re-usable group view (may be null).
132 * @param parent The parent view group.
133 *
134 * @return The view corresponding to the group.
135 */
136 public View getGroupView(boolean isExpanded, View convertView, ViewGroup parent) {
137 assert convertView == null || convertView instanceof RecentTabsGroup View;
138 RecentTabsGroupView groupView = (RecentTabsGroupView) convertView;
139 if (groupView == null) {
140 groupView = (RecentTabsGroupView) LayoutInflater.from(mActivity) .inflate(
141 R.layout.recent_tabs_group_item, parent, false);
142 groupView.initialize(mInitializationTimestamp);
143 }
144 configureGroupView(groupView, isExpanded);
145 return groupView;
146 }
147
148 /**
149 * Configures an RecentTabsGroupView to display the header of this group .
150 * @param groupView The RecentTabsGroupView to configure.
151 * @param isExpanded Whether the view is currently expanded.
152 */
153 abstract void configureGroupView(RecentTabsGroupView groupView, boolean isExpanded);
154
155 /**
156 * Sets whether this group is collapsed (i.e. whether only the header is visible).
157 */
158 abstract void setCollapsed(boolean isCollapsed);
159
160 /**
161 * @return Whether this group is collapsed.
162 */
163 abstract boolean isCollapsed();
164
165 /**
166 * Called when a child item is clicked.
167 * @param childPosition The position of the child in the group.
168 * @return Whether the click was handled.
169 */
170 abstract boolean onChildClick(int childPosition);
171
172 /**
173 * Called when the context menu for the group view is being built.
174 * @param menu The context menu being built.
175 * @param activity The current activity.
176 */
177 void onCreateContextMenuForGroup(ContextMenu menu, Activity activity) {
178 }
179
180 /**
181 * Called when a context menu for one of the child views is being built.
182 * @param childPosition The position of the child in the group.
183 * @param menu The context menu being built.
184 * @param activity The current activity.
185 */
186 void onCreateContextMenuForChild(int childPosition, ContextMenu menu,
187 Activity activity) {
188 }
189 }
190
191 /**
192 * A group containing all the tabs currently open on this device.
193 */
194 class CurrentlyOpenTabsGroup extends Group {
195 private static final int NUM_DEFAULT_VISIBLE_TABS = 6;
196
197 private final List<CurrentlyOpenTab> mCurrentlyOpenTabs;
198 private final boolean mShowingAll;
199
200 public CurrentlyOpenTabsGroup(List<CurrentlyOpenTab> tabsList) {
201 mCurrentlyOpenTabs = tabsList;
202 mShowingAll = mRecentTabsManager.isCurrentlyOpenTabsShowingAll();
203 }
204
205 private boolean isMoreButton(int childPosition) {
206 return !mShowingAll && childPosition
207 == Math.min(NUM_DEFAULT_VISIBLE_TABS, mCurrentlyOpenTabs.siz e());
208 }
209
210 @Override
211 GroupType getGroupType() {
212 return GroupType.CONTENT;
213 }
214
215 @Override
216 int getChildrenCount() {
217 if (mShowingAll) return mCurrentlyOpenTabs.size();
218 return Math.min(NUM_DEFAULT_VISIBLE_TABS, mCurrentlyOpenTabs.size() - 1) + 1;
219 }
220
221 @Override
222 ChildType getChildType() {
223 return ChildType.DEFAULT_CONTENT;
224 }
225
226 @Override
227 CurrentlyOpenTab getChild(int childPosition) {
228 if (isMoreButton(childPosition)) return null;
229
230 return mCurrentlyOpenTabs.get(childPosition);
231 }
232
233 @Override
234 void configureChildView(int childPosition, ViewHolder viewHolder) {
235 if (isMoreButton(childPosition)) {
236 Resources resources = mActivity.getResources();
237 String text = resources.getString(R.string.recent_tabs_show_more );
238 viewHolder.textView.setText(text);
239 Drawable drawable = ApiCompatibilityUtils.getDrawable(
240 resources, R.drawable.more_horiz);
241 ApiCompatibilityUtils.setCompoundDrawablesRelativeWithIntrinsicB ounds(
242 viewHolder.textView, drawable, null, null, null);
243 } else {
244 CurrentlyOpenTab openTab = getChild(childPosition);
245 viewHolder.textView.setText(TextUtils.isEmpty(openTab.getTitle() ) ? openTab.getUrl()
246 : openTab.getTitle());
247 loadLocalFavicon(viewHolder, openTab.getUrl());
248 }
249 }
250
251 @Override
252 void configureGroupView(RecentTabsGroupView groupView, boolean isExpande d) {
253 groupView.configureForCurrentlyOpenTabs(isExpanded);
254 }
255
256 @Override
257 void setCollapsed(boolean isCollapsed) {
258 mRecentTabsManager.setCurrentlyOpenTabsCollapsed(isCollapsed);
259 }
260
261 @Override
262 boolean isCollapsed() {
263 return mRecentTabsManager.isCurrentlyOpenTabsCollapsed();
264 }
265
266 @Override
267 boolean onChildClick(int childPosition) {
268 if (isMoreButton(childPosition)) {
269 mRecentTabsManager.setCurrentlyOpenTabsShowAll(true);
270 } else {
271 getChild(childPosition).getRunnable().run();
272 }
273 return true;
274 }
275 }
276
277 /**
278 * A group containing all the tabs associated with a foreign session from a synced device.
279 */
280 class ForeignSessionGroup extends Group {
281 private final ForeignSession mForeignSession;
282
283 ForeignSessionGroup(ForeignSession foreignSession) {
284 mForeignSession = foreignSession;
285 }
286
287 @Override
288 public GroupType getGroupType() {
289 return GroupType.CONTENT;
290 }
291
292 @Override
293 public int getChildrenCount() {
294 int count = 0;
295 for (ForeignSessionWindow window : mForeignSession.windows) {
296 count += window.tabs.size();
297 }
298 return count;
299 }
300
301 @Override
302 public ChildType getChildType() {
303 return ChildType.DEFAULT_CONTENT;
304 }
305
306 @Override
307 public ForeignSessionTab getChild(int childPosition) {
308 for (ForeignSessionWindow window : mForeignSession.windows) {
309 if (childPosition < window.tabs.size()) {
310 return window.tabs.get(childPosition);
311 }
312 childPosition -= window.tabs.size();
313 }
314 assert false;
315 return null;
316 }
317
318 @Override
319 public void configureChildView(int childPosition, ViewHolder viewHolder) {
320 ForeignSessionTab sessionTab = getChild(childPosition);
321 viewHolder.textView.setText(TextUtils.isEmpty(sessionTab.title) ? se ssionTab.url
322 : sessionTab.title);
323 loadSyncedFavicon(viewHolder, sessionTab.url);
324 }
325
326 @Override
327 public void configureGroupView(RecentTabsGroupView groupView, boolean is Expanded) {
328 groupView.configureForForeignSession(mForeignSession, isExpanded);
329 }
330
331 @Override
332 public void setCollapsed(boolean isCollapsed) {
333 mRecentTabsManager.setForeignSessionCollapsed(mForeignSession, isCol lapsed);
334 }
335
336 @Override
337 public boolean isCollapsed() {
338 return mRecentTabsManager.getForeignSessionCollapsed(mForeignSession );
339 }
340
341 @Override
342 public boolean onChildClick(int childPosition) {
343 ForeignSessionTab foreignSessionTab = getChild(childPosition);
344 mRecentTabsManager.openForeignSessionTab(mForeignSession, foreignSes sionTab,
345 WindowOpenDisposition.CURRENT_TAB);
346 return true;
347 }
348
349 @Override
350 public void onCreateContextMenuForGroup(ContextMenu menu, Activity activ ity) {
351 OnMenuItemClickListener listener = new OnMenuItemClickListener() {
352 @Override
353 public boolean onMenuItemClick(MenuItem item) {
354 mRecentTabsManager.deleteForeignSession(mForeignSession);
355 return true;
356 }
357 };
358 menu.add(R.string.ntp_recent_tabs_remove_menu_option)
359 .setOnMenuItemClickListener(listener);
360 }
361
362 @Override
363 public void onCreateContextMenuForChild(int childPosition, ContextMenu m enu,
364 Activity activity) {
365 final ForeignSessionTab foreignSessionTab = getChild(childPosition);
366 OnMenuItemClickListener listener = new OnMenuItemClickListener() {
367 @Override
368 public boolean onMenuItemClick(MenuItem item) {
369 mRecentTabsManager.openForeignSessionTab(mForeignSession, fo reignSessionTab,
370 WindowOpenDisposition.NEW_BACKGROUND_TAB);
371 return true;
372 }
373 };
374 menu.add(R.string.contextmenu_open_in_new_tab).setOnMenuItemClickLis tener(listener);
375 }
376 }
377
378 /**
379 * A group containing tabs that were recently closed on this device and a li nk to the history
380 * page.
381 */
382 class RecentlyClosedTabsGroup extends Group {
383 private static final int ID_OPEN_IN_NEW_TAB = 1;
384 private static final int ID_REMOVE_ALL = 2;
385
386 @Override
387 public GroupType getGroupType() {
388 return GroupType.CONTENT;
389 }
390
391 @Override
392 public int getChildrenCount() {
393 // The number of children is the number of recently closed tabs, plu s one for the "Show
394 // full history" item.
395 return 1 + mRecentTabsManager.getRecentlyClosedTabs().size();
396 }
397
398 @Override
399 public ChildType getChildType() {
400 return ChildType.DEFAULT_CONTENT;
401 }
402
403 /**
404 * @param childPosition The index of an item in the recently closed list .
405 * @return Whether the item at childPosition is the link to the history page.
406 */
407 private boolean isHistoryLink(int childPosition) {
408 return childPosition == mRecentTabsManager.getRecentlyClosedTabs().s ize();
409 }
410
411 @Override
412 public RecentlyClosedTab getChild(int childPosition) {
413 if (isHistoryLink(childPosition)) {
414 return null;
415 }
416 return mRecentTabsManager.getRecentlyClosedTabs().get(childPosition) ;
417 }
418
419 @Override
420 public void configureChildView(int childPosition, ViewHolder viewHolder) {
421 if (isHistoryLink(childPosition)) {
422 viewHolder.textView.setText(R.string.show_full_history);
423 ApiCompatibilityUtils.setCompoundDrawablesRelativeWithIntrinsicB ounds(
424 viewHolder.textView, R.drawable.history_favicon, 0, 0, 0 );
425 } else {
426 RecentlyClosedTab tab = getChild(childPosition);
427 String title = NewTabPageView.getTitleForDisplay(tab.title, tab. url);
428 viewHolder.textView.setText(title);
429 loadLocalFavicon(viewHolder, tab.url);
430 }
431 }
432
433 @Override
434 public void configureGroupView(RecentTabsGroupView groupView, boolean is Expanded) {
435 groupView.configureForRecentlyClosedTabs(isExpanded);
436 }
437
438 @Override
439 public void setCollapsed(boolean isCollapsed) {
440 mRecentTabsManager.setRecentlyClosedTabsCollapsed(isCollapsed);
441 }
442
443 @Override
444 public boolean isCollapsed() {
445 return mRecentTabsManager.isRecentlyClosedTabsCollapsed();
446 }
447
448 @Override
449 public boolean onChildClick(int childPosition) {
450 if (isHistoryLink(childPosition)) {
451 mRecentTabsManager.openHistoryPage();
452 } else {
453 mRecentTabsManager.openRecentlyClosedTab(getChild(childPosition) ,
454 WindowOpenDisposition.CURRENT_TAB);
455 }
456 return true;
457 }
458
459 @Override
460 public void onCreateContextMenuForGroup(ContextMenu menu, Activity activ ity) {
461 }
462
463 @Override
464 public void onCreateContextMenuForChild(final int childPosition, Context Menu menu,
465 Activity activity) {
466 final RecentlyClosedTab recentlyClosedTab = getChild(childPosition);
467 if (recentlyClosedTab == null) return;
468 OnMenuItemClickListener listener = new OnMenuItemClickListener() {
469 @Override
470 public boolean onMenuItemClick(MenuItem item) {
471 switch (item.getItemId()) {
472 case ID_REMOVE_ALL:
473 mRecentTabsManager.clearRecentlyClosedTabs();
474 break;
475 case ID_OPEN_IN_NEW_TAB:
476 mRecentTabsManager.openRecentlyClosedTab(recentlyClo sedTab,
477 WindowOpenDisposition.NEW_BACKGROUND_TAB);
478 break;
479 default:
480 assert false;
481 }
482 return true;
483 }
484 };
485 menu.add(ContextMenu.NONE, ID_OPEN_IN_NEW_TAB, ContextMenu.NONE,
486 R.string.contextmenu_open_in_new_tab).setOnMenuItemClickList ener(listener);
487 menu.add(ContextMenu.NONE, ID_REMOVE_ALL, ContextMenu.NONE,
488 R.string.remove_all).setOnMenuItemClickListener(listener);
489 }
490 }
491
492 /**
493 * A group containing a blank separator.
494 */
495 class SeparatorGroup extends Group {
496 private final boolean mIsVisible;
497
498 public SeparatorGroup(boolean isVisible) {
499 mIsVisible = isVisible;
500 }
501
502 @Override
503 public GroupType getGroupType() {
504 return mIsVisible ? GroupType.VISIBLE_SEPARATOR : GroupType.INVISIBL E_SEPARATOR;
505 }
506
507 @Override
508 public ChildType getChildType() {
509 return ChildType.NONE;
510 }
511
512 @Override
513 public int getChildrenCount() {
514 return 0;
515 }
516
517 @Override
518 public View getGroupView(boolean isExpanded, View convertView, ViewGroup parent) {
519 if (convertView == null) {
520 int layout = mIsVisible
521 ? R.layout.recent_tabs_group_separator_visible
522 : R.layout.recent_tabs_group_separator_invisible;
523 convertView = LayoutInflater.from(mActivity).inflate(layout, par ent, false);
524 }
525 return convertView;
526 }
527
528 @Override
529 public void configureGroupView(RecentTabsGroupView groupView, boolean is Expanded) {
530 }
531
532 @Override
533 public void configureChildView(int childPosition, ViewHolder viewHolder) {
534 }
535
536 @Override
537 public Object getChild(int childPosition) {
538 return null;
539 }
540
541 @Override
542 public void setCollapsed(boolean isCollapsed) {
543 }
544
545 @Override
546 public boolean isCollapsed() {
547 return false;
548 }
549
550 @Override
551 public boolean onChildClick(int childPosition) {
552 return false;
553 }
554 }
555
556 /**
557 * A group containing the Sync Promo.
558 */
559 class SyncPromoGroup extends Group {
560 @Override
561 public GroupType getGroupType() {
562 return GroupType.CONTENT;
563 }
564
565 @Override
566 public ChildType getChildType() {
567 return ChildType.SYNC_PROMO;
568 }
569
570 @Override
571 public int getChildrenCount() {
572 return 1;
573 }
574
575 @Override
576 public Object getChild(int childPosition) {
577 return null;
578 }
579
580 @Override
581 View getChildView(int childPosition, boolean isLastChild, View convertVi ew,
582 ViewGroup parent) {
583 if (convertView == null) {
584 convertView = new RecentTabsPromoView(mActivity, mRecentTabsMana ger, null);
585 }
586 return convertView;
587 }
588
589 @Override
590 public void configureChildView(int childPosition, ViewHolder viewHolder) {
591 }
592
593 @Override
594 public void configureGroupView(RecentTabsGroupView groupView, boolean is Expanded) {
595 groupView.configureForSyncPromo(isExpanded);
596 }
597
598 @Override
599 public void setCollapsed(boolean isCollapsed) {
600 mRecentTabsManager.setSyncPromoCollapsed(isCollapsed);
601 }
602
603 @Override
604 public boolean isCollapsed() {
605 return mRecentTabsManager.isSyncPromoCollapsed();
606 }
607
608 @Override
609 public boolean onChildClick(int childPosition) {
610 return false;
611 }
612 }
613
614 private static class FaviconCache {
615 private static final String SYNCED_FAVICON_PREFIX = "Synced";
616 private static final String LOCAL_FAVICON_PREFIX = "Local";
617
618 private final LruCache<String, Drawable> mMemoryCache;
619
620 public FaviconCache(int size) {
621 mMemoryCache = new LruCache<String, Drawable>(size);
622 }
623
624 public Drawable getSyncedFaviconImage(String url) {
625 return mMemoryCache.get(SYNCED_FAVICON_PREFIX + url);
626 }
627
628 public void putSycnedFaviconImage(String url, Drawable image) {
629 mMemoryCache.put(SYNCED_FAVICON_PREFIX + url, image);
630 }
631
632 public Drawable getLocalFaviconImage(String url) {
633 return mMemoryCache.get(LOCAL_FAVICON_PREFIX + url);
634 }
635
636 public void putLocalFaviconImage(String url, Drawable image) {
637 mMemoryCache.put(LOCAL_FAVICON_PREFIX + url, image);
638 }
639 }
640
641 /**
642 * Creates an RecentTabsRowAdapter used to populate an ExpandableList with o ther
643 * devices and foreign tab cells.
644 *
645 * @param activity The Android activity this adapter will work in.
646 * @param recentTabsManager The RecentTabsManager that will act as the data source.
647 */
648 public RecentTabsRowAdapter(Activity activity, RecentTabsManager recentTabsM anager) {
649 mActivity = activity;
650 mRecentTabsManager = recentTabsManager;
651 mGroups = new ArrayList<Group>();
652 mInitializationTimestamp =
653 TimeUnit.SECONDS.convert(System.currentTimeMillis(), TimeUnit.MILLIS ECONDS);
654 mFaviconCache = buildFaviconCache(MAX_NUM_FAVICONS_TO_CACHE);
655
656 Resources resources = activity.getResources();
657 mDefaultFavicon = ApiCompatibilityUtils.getDrawable(resources, R.drawabl e.default_favicon);
658 mFaviconSize = mDefaultFavicon.getIntrinsicHeight();
659 }
660
661 private static FaviconCache buildFaviconCache(int size) {
662 return new FaviconCache(size);
663 }
664
665 /**
666 * ViewHolder class optimizes looking up table row fields. findViewById is o nly called once
667 * per row view initialization, and the references are cached here. Also sto res a reference to
668 * the favicon image callback; so that we can make sure we load the correct favicon.
669 */
670 private static class ViewHolder {
671 public TextView textView;
672 public FaviconImageCallback imageCallback;
673 }
674
675 private Drawable faviconDrawable(Bitmap image) {
676 if (image == null) return null;
677 return new BitmapDrawable(mActivity.getResources(), Bitmap.createScaledB itmap(image,
678 mFaviconSize, mFaviconSize, true));
679 }
680
681 private void loadSyncedFavicon(final ViewHolder viewHolder, final String url ) {
682 Drawable image = mFaviconCache.getSyncedFaviconImage(url);
683 if (image == null) {
684 image = faviconDrawable(mRecentTabsManager.getSyncedFaviconImageForU RL(url));
685 image = (image == null) ? mDefaultFavicon : image;
686 mFaviconCache.putSycnedFaviconImage(url, image);
687 }
688 ApiCompatibilityUtils.setCompoundDrawablesRelativeWithIntrinsicBounds(vi ewHolder.textView,
689 image, null, null, null);
690 }
691
692 private void loadLocalFavicon(final ViewHolder viewHolder, final String url) {
693 Drawable image;
694 if (url == null) {
695 // URL is null for print jobs, for example.
696 image = mDefaultFavicon;
697 } else {
698 image = mFaviconCache.getLocalFaviconImage(url);
699 if (image == null) {
700 FaviconImageCallback imageCallback = new FaviconImageCallback() {
701 @Override
702 public void onFaviconAvailable(Bitmap bitmap, String iconUrl ) {
703 if (this != viewHolder.imageCallback) return;
704 Drawable image = faviconDrawable(bitmap);
705 image = (image == null) ? mDefaultFavicon : image;
706 mFaviconCache.putLocalFaviconImage(url, image);
707 ApiCompatibilityUtils.setCompoundDrawablesRelativeWithIn trinsicBounds(
708 viewHolder.textView, image, null, null, null);
709 }
710 };
711 viewHolder.imageCallback = imageCallback;
712 mRecentTabsManager.getLocalFaviconForUrl(url, mFaviconSize, imag eCallback);
713 image = mDefaultFavicon;
714 }
715 }
716 ApiCompatibilityUtils.setCompoundDrawablesRelativeWithIntrinsicBounds(vi ewHolder.textView,
717 image, null, null, null);
718 }
719
720 @Override
721 public View getChildView(int groupPosition, int childPosition, boolean isLas tChild,
722 View convertView, ViewGroup parent) {
723 return getGroup(groupPosition).getChildView(childPosition, isLastChild, convertView,
724 parent);
725 }
726
727 // BaseExpandableListAdapter group related implementations
728 @Override
729 public int getGroupCount() {
730 return mGroups.size();
731 }
732
733 @Override
734 public long getGroupId(int groupPosition) {
735 return groupPosition;
736 }
737
738 @Override
739 public Group getGroup(int groupPosition) {
740 return mGroups.get(groupPosition);
741 }
742
743 @Override
744 public View getGroupView(int groupPosition, boolean isExpanded, View convert View,
745 ViewGroup parent) {
746 return getGroup(groupPosition).getGroupView(isExpanded, convertView, par ent);
747 }
748
749 // BaseExpandableListAdapter child related implementations
750 @Override
751 public int getChildrenCount(int groupPosition) {
752 return getGroup(groupPosition).getChildrenCount();
753 }
754
755 @Override
756 public long getChildId(int groupPosition, int childPosition) {
757 return childPosition;
758 }
759
760 @Override
761 public Object getChild(int groupPosition, int childPosition) {
762 return getGroup(groupPosition).getChild(childPosition);
763 }
764
765 @Override
766 public boolean isChildSelectable(int groupPosition, int childPosition) {
767 return true;
768 }
769
770 // BaseExpandableListAdapter misc. implementation
771 @Override
772 public boolean hasStableIds() {
773 return false;
774 }
775
776 @Override
777 public int getGroupType(int groupPosition) {
778 return getGroup(groupPosition).getGroupType().ordinal();
779 }
780
781 @Override
782 public int getGroupTypeCount() {
783 return GroupType.values().length;
784 }
785
786 private void addGroup(Group group) {
787 if (!DeviceFormFactor.isTablet(mActivity)) {
788 mGroups.add(group);
789 } else {
790 if (mGroups.size() == 0) {
791 mGroups.add(mInvisibleSeparatorGroup);
792 }
793 mGroups.add(group);
794 mGroups.add(mInvisibleSeparatorGroup);
795 }
796 }
797
798 @Override
799 public void notifyDataSetChanged() {
800 mGroups.clear();
801 List<CurrentlyOpenTab> tabList = mRecentTabsManager.getCurrentlyOpenTabs ();
802 if (tabList != null && !tabList.isEmpty()) {
803 addGroup(new CurrentlyOpenTabsGroup(tabList));
804 }
805 addGroup(mRecentlyClosedTabsGroup);
806 for (ForeignSession session : mRecentTabsManager.getForeignSessions()) {
807 addGroup(new ForeignSessionGroup(session));
808 }
809 if (mRecentTabsManager.shouldDisplaySyncPromo()) {
810 addGroup(new SyncPromoGroup());
811 }
812
813 // Add separator line after the recently closed tabs group.
814 int recentlyClosedIndex = mGroups.indexOf(mRecentlyClosedTabsGroup);
815 if (DeviceFormFactor.isTablet(mActivity)) {
816 if (recentlyClosedIndex != mGroups.size() - 2) {
817 mGroups.set(recentlyClosedIndex + 1, mVisibleSeparatorGroup);
818 }
819 } else if (recentlyClosedIndex != mGroups.size() - 1) {
820 mGroups.add(recentlyClosedIndex + 1, mVisibleSeparatorGroup);
821 }
822
823 super.notifyDataSetChanged();
824 }
825
826 @Override
827 public int getChildType(int groupPosition, int childPosition) {
828 return mGroups.get(groupPosition).getChildType().ordinal();
829 }
830
831 @Override
832 public int getChildTypeCount() {
833 return ChildType.values().length;
834 }
835 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698