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

Side by Side Diff: chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapterTest.java

Issue 2274293002: 📰 Keep Suggestion sections in declaration order (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix comments Created 4 years, 3 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
« no previous file with comments | « chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SnippetsBridge.java ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 package org.chromium.chrome.browser.ntp.cards; 5 package org.chromium.chrome.browser.ntp.cards;
6 6
7 import static org.junit.Assert.assertEquals; 7 import static org.junit.Assert.assertEquals;
8 import static org.junit.Assert.assertFalse; 8 import static org.junit.Assert.assertFalse;
9 import static org.junit.Assert.assertTrue; 9 import static org.junit.Assert.assertTrue;
10 10
11 import org.chromium.base.metrics.RecordHistogram; 11 import org.chromium.base.metrics.RecordHistogram;
12 import org.chromium.base.metrics.RecordUserAction; 12 import org.chromium.base.metrics.RecordUserAction;
13 import org.chromium.base.test.util.Feature; 13 import org.chromium.base.test.util.Feature;
14 import org.chromium.chrome.browser.ntp.snippets.CategoryInt;
14 import org.chromium.chrome.browser.ntp.snippets.CategoryStatus; 15 import org.chromium.chrome.browser.ntp.snippets.CategoryStatus;
15 import org.chromium.chrome.browser.ntp.snippets.ContentSuggestionsCardLayout; 16 import org.chromium.chrome.browser.ntp.snippets.ContentSuggestionsCardLayout;
16 import org.chromium.chrome.browser.ntp.snippets.FakeSuggestionsSource; 17 import org.chromium.chrome.browser.ntp.snippets.FakeSuggestionsSource;
17 import org.chromium.chrome.browser.ntp.snippets.KnownCategories; 18 import org.chromium.chrome.browser.ntp.snippets.KnownCategories;
18 import org.chromium.chrome.browser.ntp.snippets.SnippetArticle; 19 import org.chromium.chrome.browser.ntp.snippets.SnippetArticle;
19 import org.chromium.testing.local.LocalRobolectricTestRunner; 20 import org.chromium.testing.local.LocalRobolectricTestRunner;
20 import org.junit.Before; 21 import org.junit.Before;
21 import org.junit.Test; 22 import org.junit.Test;
22 import org.junit.runner.RunWith; 23 import org.junit.runner.RunWith;
23 import org.robolectric.annotation.Config; 24 import org.robolectric.annotation.Config;
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after
311 CategoryStatus.LOADING_ERROR); 312 CategoryStatus.LOADING_ERROR);
312 assertItemsFor(); 313 assertItemsFor();
313 314
314 // Same when loading a new NTP. 315 // Same when loading a new NTP.
315 mNtpAdapter = new NewTabPageAdapter(null, null, mSnippetsSource, null); 316 mNtpAdapter = new NewTabPageAdapter(null, null, mSnippetsSource, null);
316 assertItemsFor(); 317 assertItemsFor();
317 318
318 // Same for CATEGORY_EXPLICITLY_DISABLED. 319 // Same for CATEGORY_EXPLICITLY_DISABLED.
319 mSnippetsSource.setStatusForCategory(KnownCategories.ARTICLES, CategoryS tatus.AVAILABLE); 320 mSnippetsSource.setStatusForCategory(KnownCategories.ARTICLES, CategoryS tatus.AVAILABLE);
320 mSnippetsSource.setSuggestionsForCategory(KnownCategories.ARTICLES, snip pets); 321 mSnippetsSource.setSuggestionsForCategory(KnownCategories.ARTICLES, snip pets);
322 mNtpAdapter = new NewTabPageAdapter(null, null, mSnippetsSource, null);
321 assertItemsFor(section(5)); 323 assertItemsFor(section(5));
322 mSnippetsSource.setStatusForCategory( 324 mSnippetsSource.setStatusForCategory(
323 KnownCategories.ARTICLES, CategoryStatus.CATEGORY_EXPLICITLY_DIS ABLED); 325 KnownCategories.ARTICLES, CategoryStatus.CATEGORY_EXPLICITLY_DIS ABLED);
324 assertItemsFor(); 326 assertItemsFor();
325 327
326 // Same when loading a new NTP. 328 // Same when loading a new NTP.
327 mNtpAdapter = new NewTabPageAdapter(null, null, mSnippetsSource, null); 329 mNtpAdapter = new NewTabPageAdapter(null, null, mSnippetsSource, null);
328 assertItemsFor(); 330 assertItemsFor();
329 } 331 }
330 332
(...skipping 11 matching lines...) Expand all
342 // When the category switches to NOT_PROVIDED, UI stays the same. 344 // When the category switches to NOT_PROVIDED, UI stays the same.
343 mSnippetsSource.setStatusForCategory(KnownCategories.ARTICLES, CategoryS tatus.NOT_PROVIDED); 345 mSnippetsSource.setStatusForCategory(KnownCategories.ARTICLES, CategoryS tatus.NOT_PROVIDED);
344 mSnippetsSource.silentlyRemoveCategory(KnownCategories.ARTICLES); 346 mSnippetsSource.silentlyRemoveCategory(KnownCategories.ARTICLES);
345 assertItemsFor(section(4)); 347 assertItemsFor(section(4));
346 348
347 // But it disappears when loading a new NTP. 349 // But it disappears when loading a new NTP.
348 mNtpAdapter = new NewTabPageAdapter(null, null, mSnippetsSource, null); 350 mNtpAdapter = new NewTabPageAdapter(null, null, mSnippetsSource, null);
349 assertItemsFor(); 351 assertItemsFor();
350 } 352 }
351 353
352 // TODO(dgn): Properly make this a test based on handling different Category Info when we
353 // stop hardcoding things in sections.
354 @Test 354 @Test
355 @Feature({"Ntp"}) 355 @Feature({"Ntp"})
356 public void testSectionVisibility() { 356 public void testSectionVisibleIfEmpty() {
357 mSnippetsSource.setStatusForCategory( 357 final int category = 42;
358 KnownCategories.BOOKMARKS, CategoryStatus.INITIALIZING); 358 final int sectionIdx = 1; // section 0 is the above the fold, we test th e one after.
359 mSnippetsSource.setInfoForCategory( 359 final List<SnippetArticle> articles = Collections.unmodifiableList(creat eDummySnippets(3));
360 KnownCategories.BOOKMARKS, 360 FakeSuggestionsSource suggestionsSource;
361 new SuggestionsCategoryInfo("Recent bookmarks", 361 SuggestionsSection section;
362 ContentSuggestionsCardLayout.MINIMAL_CARD, true, false)) ;
363 362
364 // Part 1: Test ARTICLES. 363 // Part 1: VisibleIfEmpty = true
364 suggestionsSource = new FakeSuggestionsSource();
365 suggestionsSource.setStatusForCategory(category, CategoryStatus.INITIALI ZING);
366 suggestionsSource.setInfoForCategory(
367 category, new SuggestionsCategoryInfo(
368 "", ContentSuggestionsCardLayout.MINIMAL_CARD, false, true));
365 369
366 // The |ARTICLES| section should be shown even if we don't receive any s uggestion for it. 370 // 1.1 - Initial state
367 mSnippetsSource.setStatusForCategory(KnownCategories.ARTICLES, CategoryS tatus.AVAILABLE); 371 mNtpAdapter = new NewTabPageAdapter(null, null, suggestionsSource, null) ;
368 mSnippetsSource.setSuggestionsForCategory(
369 KnownCategories.ARTICLES, Collections.<SnippetArticle>emptyList( ));
370 assertItemsFor(sectionWithStatusCard()); 372 assertItemsFor(sectionWithStatusCard());
371 373
372 // Make sure we show the articles when we load them. 374 // 1.2 - With suggestions
373 List<SnippetArticle> articles = createDummySnippets(3); 375 suggestionsSource.setStatusForCategory(category, CategoryStatus.AVAILABL E);
374 mSnippetsSource.setSuggestionsForCategory(KnownCategories.ARTICLES, arti cles); 376 suggestionsSource.setSuggestionsForCategory(category, articles);
375 assertItemsFor(section(3)); 377 assertItemsFor(section(3));
376 378
377 // When we dismiss them, we should have the status card coming back. 379 // 1.3 - When all suggestions are dismissed
378 int indexOfFirstItemOfArticlesGroup = 1; 380 assertEquals(SuggestionsSection.class, mNtpAdapter.getGroups().get(secti onIdx).getClass());
379 SuggestionsSection section = 381 section = (SuggestionsSection) mNtpAdapter.getGroups().get(sectionIdx);
380 (SuggestionsSection) mNtpAdapter.getGroup(indexOfFirstItemOfArti clesGroup); 382 assertEquals(section(3), section.getItems().size());
381 assertEquals(section.getItems().size(), section(3));
382 section.removeSuggestion(articles.get(0)); 383 section.removeSuggestion(articles.get(0));
383 section.removeSuggestion(articles.get(1)); 384 section.removeSuggestion(articles.get(1));
384 section.removeSuggestion(articles.get(2)); 385 section.removeSuggestion(articles.get(2));
385 assertItemsFor(sectionWithStatusCard()); 386 assertItemsFor(sectionWithStatusCard());
386 387
387 // Part 2: Test BOOKMARKS. 388 // Part 2: VisibleIfEmpty = false
389 suggestionsSource = new FakeSuggestionsSource();
390 suggestionsSource.setStatusForCategory(category, CategoryStatus.INITIALI ZING);
391 suggestionsSource.setInfoForCategory(
392 category, new SuggestionsCategoryInfo(
393 "", ContentSuggestionsCardLayout.MINIMAL_CARD, false, false));
388 394
389 // The |BOOKMARKS| section should not be shown if we don't receive any s uggestion for it. 395 // 2.1 - Initial state
390 mSnippetsSource.setStatusForCategory(KnownCategories.BOOKMARKS, Category Status.AVAILABLE); 396 mNtpAdapter = new NewTabPageAdapter(null, null, suggestionsSource, null) ;
391 mSnippetsSource.setSuggestionsForCategory( 397 assertItemsFor();
392 KnownCategories.BOOKMARKS, Collections.<SnippetArticle>emptyList ());
393 assertItemsFor(sectionHidden(), sectionWithStatusCard());
394 398
395 // When we get some, make sure we show the button. 399 // 2.2 - With suggestions
396 mSnippetsSource.setSuggestionsForCategory(KnownCategories.BOOKMARKS, art icles); 400 suggestionsSource.setStatusForCategory(category, CategoryStatus.AVAILABL E);
397 assertItemsFor(sectionWithMoreButton(3), sectionWithStatusCard()); 401 suggestionsSource.setSuggestionsForCategory(category, articles);
402 assertItemsFor();
398 403
399 // When we dismiss snippets, we should still keep the button. 404 // 2.3 - When all suggestions are dismissed - N/A, suggestions don't get added.
400 int indexOfFirstItemOfBookmarksGroup = 3;
401 section = (SuggestionsSection) mNtpAdapter.getGroup(indexOfFirstItemOfBo okmarksGroup);
402 assertEquals(section.getItems().size(), sectionWithMoreButton(3));
403 section.removeSuggestion(articles.get(0));
404 section.removeSuggestion(articles.get(1));
405 section.removeSuggestion(articles.get(2));
406 assertItemsFor(sectionWithStatusCardAndMoreButton(), sectionWithStatusCa rd());
407 } 405 }
408 406
409 /** 407 /**
410 * Tests that the more button is shown for sections that declare it. 408 * Tests that the more button is shown for sections that declare it.
411 */ 409 */
412 @Test 410 @Test
413 @Feature({"Ntp"}) 411 @Feature({"Ntp"})
414 public void testMoreButton() { 412 public void testMoreButton() {
415 List<SnippetArticle> articles = createDummySnippets(3); 413 final int category = 42;
416 mSnippetsSource.setStatusForCategory(KnownCategories.ARTICLES, CategoryS tatus.AVAILABLE); 414 final int sectionIdx = 1; // section 0 is the above the fold, we test th e one after.
417 mSnippetsSource.setSuggestionsForCategory(KnownCategories.ARTICLES, arti cles); 415 final List<SnippetArticle> articles = Collections.unmodifiableList(creat eDummySnippets(3));
416 FakeSuggestionsSource suggestionsSource;
417 SuggestionsSection section;
418
419 // Part 1: ShowMoreButton = true
420 suggestionsSource = new FakeSuggestionsSource();
421 suggestionsSource.setStatusForCategory(category, CategoryStatus.INITIALI ZING);
422 suggestionsSource.setInfoForCategory(
423 category, new SuggestionsCategoryInfo(
424 "", ContentSuggestionsCardLayout.MINIMAL_CARD, true, true));
425
426 // 1.1 - Initial state
427 mNtpAdapter = new NewTabPageAdapter(null, null, suggestionsSource, null) ;
428 assertItemsFor(sectionWithStatusCardAndMoreButton());
429
430 // 1.2 - With suggestions
431 suggestionsSource.setStatusForCategory(category, CategoryStatus.AVAILABL E);
432 suggestionsSource.setSuggestionsForCategory(category, articles);
433 assertItemsFor(sectionWithMoreButton(3));
434
435 // 1.3 - When all suggestions are dismissed
436 assertEquals(SuggestionsSection.class, mNtpAdapter.getGroups().get(secti onIdx).getClass());
437 section = (SuggestionsSection) mNtpAdapter.getGroups().get(sectionIdx);
438 assertEquals(sectionWithMoreButton(3), section.getItems().size());
439 section.removeSuggestion(articles.get(0));
440 section.removeSuggestion(articles.get(1));
441 section.removeSuggestion(articles.get(2));
442 assertItemsFor(sectionWithStatusCardAndMoreButton());
443
444 // Part 1: ShowMoreButton = false
445 suggestionsSource = new FakeSuggestionsSource();
446 suggestionsSource.setStatusForCategory(category, CategoryStatus.INITIALI ZING);
447 suggestionsSource.setInfoForCategory(
448 category, new SuggestionsCategoryInfo(
449 "", ContentSuggestionsCardLayout.MINIMAL_CARD, false, true));
450
451 // 2.1 - Initial state
452 mNtpAdapter = new NewTabPageAdapter(null, null, suggestionsSource, null) ;
453 assertItemsFor(sectionWithStatusCard());
454
455 // 2.2 - With suggestions
456 suggestionsSource.setStatusForCategory(category, CategoryStatus.AVAILABL E);
457 suggestionsSource.setSuggestionsForCategory(category, articles);
418 assertItemsFor(section(3)); 458 assertItemsFor(section(3));
419 459
420 List<SnippetArticle> bookmarks = createDummySnippets(10); 460 // 2.3 - When all suggestions are dismissed
421 mSnippetsSource.setInfoForCategory(KnownCategories.BOOKMARKS, 461 assertEquals(SuggestionsSection.class, mNtpAdapter.getGroups().get(secti onIdx).getClass());
422 new SuggestionsCategoryInfo("Bookmarks", ContentSuggestionsCardL ayout.MINIMAL_CARD, 462 section = (SuggestionsSection) mNtpAdapter.getGroups().get(sectionIdx);
423 true, false)); 463 assertEquals(section(3), section.getItems().size());
424 mSnippetsSource.setStatusForCategory(KnownCategories.BOOKMARKS, Category Status.AVAILABLE); 464 section.removeSuggestion(articles.get(0));
425 mSnippetsSource.setSuggestionsForCategory(KnownCategories.BOOKMARKS, boo kmarks); 465 section.removeSuggestion(articles.get(1));
426 assertItemsFor(sectionWithMoreButton(10), section(3)); 466 section.removeSuggestion(articles.get(2));
467 assertItemsFor(sectionWithStatusCard());
427 } 468 }
428 469
429 /** 470 /**
430 * Tests that invalidated suggestions are immediately removed. 471 * Tests that invalidated suggestions are immediately removed.
431 */ 472 */
432 @Test 473 @Test
433 @Feature({"Ntp"}) 474 @Feature({"Ntp"})
434 public void testSuggestionInvalidated() { 475 public void testSuggestionInvalidated() {
435 List<SnippetArticle> articles = createDummySnippets(3); 476 List<SnippetArticle> articles = createDummySnippets(3);
436 mSnippetsSource.setStatusForCategory(KnownCategories.ARTICLES, CategoryS tatus.AVAILABLE); 477 mSnippetsSource.setStatusForCategory(KnownCategories.ARTICLES, CategoryS tatus.AVAILABLE);
437 mSnippetsSource.setSuggestionsForCategory(KnownCategories.ARTICLES, arti cles); 478 mSnippetsSource.setSuggestionsForCategory(KnownCategories.ARTICLES, arti cles);
438 assertItemsFor(section(3)); 479 assertItemsFor(section(3));
439 assertEquals(articles, mNtpAdapter.getItems().subList(2, 5)); 480 assertEquals(articles, mNtpAdapter.getItems().subList(2, 5));
440 481
441 SnippetArticle removed = articles.remove(1); 482 SnippetArticle removed = articles.remove(1);
442 mSnippetsSource.fireSuggestionInvalidated(KnownCategories.ARTICLES, remo ved.mId); 483 mSnippetsSource.fireSuggestionInvalidated(KnownCategories.ARTICLES, remo ved.mId);
443 assertEquals(articles, mNtpAdapter.getItems().subList(2, 4)); 484 assertEquals(articles, mNtpAdapter.getItems().subList(2, 4));
444 } 485 }
445 486
487 /**
488 * Tests that the order of the categories is kept.
489 */
490 @Test
491 @Feature({"Ntp"})
492 public void testCategoryOrder() {
493 FakeSuggestionsSource suggestionsSource = new FakeSuggestionsSource();
494 registerCategory(suggestionsSource, KnownCategories.ARTICLES, 0);
495 registerCategory(suggestionsSource, KnownCategories.BOOKMARKS, 0);
496 registerCategory(suggestionsSource, KnownCategories.PHYSICAL_WEB_PAGES, 0);
497 registerCategory(suggestionsSource, KnownCategories.DOWNLOADS, 0);
498
499 NewTabPageAdapter ntpAdapter = new NewTabPageAdapter(null, null, suggest ionsSource, null);
500 List<ItemGroup> groups = ntpAdapter.getGroups();
501
502 assertEquals(6, groups.size());
503 assertEquals(AboveTheFoldItem.class, groups.get(0).getClass());
504 assertEquals(SuggestionsSection.class, groups.get(1).getClass());
505 assertEquals(KnownCategories.ARTICLES, getCategory(groups.get(1)));
506 assertEquals(SuggestionsSection.class, groups.get(2).getClass());
507 assertEquals(KnownCategories.BOOKMARKS, getCategory(groups.get(2)));
508 assertEquals(SuggestionsSection.class, groups.get(3).getClass());
509 assertEquals(KnownCategories.PHYSICAL_WEB_PAGES, getCategory(groups.get( 3)));
510 assertEquals(SuggestionsSection.class, groups.get(4).getClass());
511 assertEquals(KnownCategories.DOWNLOADS, getCategory(groups.get(4)));
512
513 // With a different order
514 suggestionsSource = new FakeSuggestionsSource();
515 registerCategory(suggestionsSource, KnownCategories.ARTICLES, 0);
516 registerCategory(suggestionsSource, KnownCategories.PHYSICAL_WEB_PAGES, 0);
517 registerCategory(suggestionsSource, KnownCategories.DOWNLOADS, 0);
518 registerCategory(suggestionsSource, KnownCategories.BOOKMARKS, 0);
519
520 ntpAdapter = new NewTabPageAdapter(null, null, suggestionsSource, null);
521 groups = ntpAdapter.getGroups();
522
523 assertEquals(6, groups.size());
524 assertEquals(AboveTheFoldItem.class, groups.get(0).getClass());
525 assertEquals(SuggestionsSection.class, groups.get(1).getClass());
526 assertEquals(KnownCategories.ARTICLES, getCategory(groups.get(1)));
527 assertEquals(SuggestionsSection.class, groups.get(2).getClass());
528 assertEquals(KnownCategories.PHYSICAL_WEB_PAGES, getCategory(groups.get( 2)));
529 assertEquals(SuggestionsSection.class, groups.get(3).getClass());
530 assertEquals(KnownCategories.DOWNLOADS, getCategory(groups.get(3)));
531 assertEquals(SuggestionsSection.class, groups.get(4).getClass());
532 assertEquals(KnownCategories.BOOKMARKS, getCategory(groups.get(4)));
533
534 // With unknown categories
535 suggestionsSource = new FakeSuggestionsSource();
536 registerCategory(suggestionsSource, KnownCategories.ARTICLES, 0);
537 registerCategory(suggestionsSource, KnownCategories.PHYSICAL_WEB_PAGES, 0);
538 registerCategory(suggestionsSource, KnownCategories.DOWNLOADS, 0);
539
540 ntpAdapter = new NewTabPageAdapter(null, null, suggestionsSource, null);
541
542 // The adapter is already initialised, it will not only accept new categ ories
Bernhard Bauer 2016/08/25 15:20:31 "not accept new categories anymore"
dgn 2016/08/25 15:33:32 Done.
543 registerCategory(suggestionsSource, 42, 1);
544 registerCategory(suggestionsSource, KnownCategories.BOOKMARKS, 1);
545
546 groups = ntpAdapter.getGroups();
547
548 assertEquals(5, groups.size());
549 assertEquals(AboveTheFoldItem.class, groups.get(0).getClass());
550 assertEquals(SuggestionsSection.class, groups.get(1).getClass());
551 assertEquals(KnownCategories.ARTICLES, getCategory(groups.get(1)));
552 assertEquals(SuggestionsSection.class, groups.get(2).getClass());
553 assertEquals(KnownCategories.PHYSICAL_WEB_PAGES, getCategory(groups.get( 2)));
554 assertEquals(SuggestionsSection.class, groups.get(3).getClass());
555 assertEquals(KnownCategories.DOWNLOADS, getCategory(groups.get(3)));
556 }
557
446 private List<SnippetArticle> createDummySnippets(int count) { 558 private List<SnippetArticle> createDummySnippets(int count) {
447 List<SnippetArticle> snippets = new ArrayList<>(); 559 List<SnippetArticle> snippets = new ArrayList<>();
448 for (int index = 0; index < count; index++) { 560 for (int index = 0; index < count; index++) {
449 snippets.add(new SnippetArticle(0, "https://site.com/url" + index, " title" + index, 561 snippets.add(new SnippetArticle(0, "https://site.com/url" + index, " title" + index,
450 "pub" + index, "txt" + index, "https://site.com/url" + index , 562 "pub" + index, "txt" + index, "https://site.com/url" + index ,
451 "https://amp.site.com/url" + index, 0, 0, 0, 563 "https://amp.site.com/url" + index, 0, 0, 0,
452 ContentSuggestionsCardLayout.FULL_CARD)); 564 ContentSuggestionsCardLayout.FULL_CARD));
453 } 565 }
454 return snippets; 566 return snippets;
455 } 567 }
568
569 /** Registers the category with hasMoreButton=false and showIfEmpty=true*/
570 private void registerCategory(FakeSuggestionsSource suggestionsSource,
571 @CategoryInt int category, int suggestionCount) {
572 // FakeSuggestionSource does not provide snippets if the category's stat us is not available.
573 suggestionsSource.setStatusForCategory(category, CategoryStatus.AVAILABL E);
574 // Important: showIfEmpty flag to true.
575 suggestionsSource.setInfoForCategory(
576 category, new SuggestionsCategoryInfo(
577 "", ContentSuggestionsCardLayout.FULL_CARD, fa lse, true));
578 suggestionsSource.setSuggestionsForCategory(category, createDummySnippet s(suggestionCount));
579 }
580
581 private int getCategory(ItemGroup itemGroup) {
582 return ((SuggestionsSection) itemGroup).getCategory();
583 }
456 } 584 }
OLDNEW
« no previous file with comments | « chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SnippetsBridge.java ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698