diff --git a/DEPS b/DEPS index 52aff2b..18b9add 100644 --- a/DEPS +++ b/DEPS
@@ -40,11 +40,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': 'db0e4f952a71a7a5009ec8276a234227e0ec18f6', + 'skia_revision': 'af7bbc8b0495612cdbc98847fadb0a08924c41bb', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'v8_revision': 'a2104e4aebf5d9a498b54eb1f350fa596e9f1efd', + 'v8_revision': '11e3de08c734763e1f9f6907cf41d97c6465c5e3', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling swarming_client # and whatever else without interference from each other. @@ -52,7 +52,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ANGLE # and whatever else without interference from each other. - 'angle_revision': 'abe89c7d32d719ffd86ce2400505188b52b55e4c', + 'angle_revision': '308d745d8e3c7710778c993a9b37fe74d0a2bc12', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling build tools # and whatever else without interference from each other. @@ -96,7 +96,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. - 'catapult_revision': 'df581f5fc8deac24b0027c260b6bace47906161b', + 'catapult_revision': '71c4c9aba898fe6d112646d549cb94de1b41a54f', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other.
diff --git a/build/android/pylib/constants/__init__.py b/build/android/pylib/constants/__init__.py index 80ad2c1a..916ee27 100644 --- a/build/android/pylib/constants/__init__.py +++ b/build/android/pylib/constants/__init__.py
@@ -37,28 +37,28 @@ 'chromecast_shell': chrome.PackageInfo( 'com.google.android.apps.mediashell', 'com.google.android.apps.mediashell.MediaShellActivity', - '/data/local/tmp/castshell-command-line', + 'castshell-command-line', None), 'android_webview_shell': chrome.PackageInfo( 'org.chromium.android_webview.shell', 'org.chromium.android_webview.shell.AwShellActivity', - '/data/local/tmp/android-webview-command-line', + 'android-webview-command-line', None), 'gtest': chrome.PackageInfo( 'org.chromium.native_test', 'org.chromium.native_test.NativeUnitTestActivity', - '/data/local/tmp/chrome-native-tests-command-line', + 'chrome-native-tests-command-line', None), 'components_browsertests': chrome.PackageInfo( 'org.chromium.components_browsertests_apk', ('org.chromium.components_browsertests_apk' + '.ComponentsBrowserTestsActivity'), - '/data/local/tmp/chrome-native-tests-command-line', + 'chrome-native-tests-command-line', None), 'content_browsertests': chrome.PackageInfo( 'org.chromium.content_browsertests_apk', 'org.chromium.content_browsertests_apk.ContentBrowserTestsActivity', - '/data/local/tmp/chrome-native-tests-command-line', + 'chrome-native-tests-command-line', None), 'chromedriver_webview_shell': chrome.PackageInfo( 'org.chromium.chromedriver_webview_shell',
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapter.java index 0c5f37a3..aad8ce4 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapter.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapter.java
@@ -73,7 +73,7 @@ mUiConfig = uiConfig; mRoot = new InnerNode(); - mSections = new SectionList(mUiDelegate, offlinePageBridge, mUiConfig); + mSections = new SectionList(mUiDelegate, offlinePageBridge); mSigninPromo = new SignInPromo(mUiDelegate); mAllDismissed = new AllDismissedItem(); mFooter = new Footer();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SectionList.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SectionList.java index 1199690..24bc8c0 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SectionList.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SectionList.java
@@ -17,7 +17,6 @@ import org.chromium.chrome.browser.offlinepages.OfflinePageBridge; import org.chromium.chrome.browser.suggestions.SuggestionsRanker; import org.chromium.chrome.browser.suggestions.SuggestionsUiDelegate; -import org.chromium.chrome.browser.widget.displaystyle.UiConfig; import java.util.LinkedHashMap; import java.util.List; @@ -36,12 +35,9 @@ private final SuggestionsUiDelegate mUiDelegate; private final OfflinePageBridge mOfflinePageBridge; private final SuggestionsRanker mSuggestionsRanker; - private final UiConfig mUiConfig; - public SectionList(SuggestionsUiDelegate uiDelegate, OfflinePageBridge offlinePageBridge, - UiConfig uiConfig) { + public SectionList(SuggestionsUiDelegate uiDelegate, OfflinePageBridge offlinePageBridge) { mSuggestionsRanker = new SuggestionsRanker(); - mUiConfig = uiConfig; mUiDelegate = uiDelegate; mUiDelegate.getSuggestionsSource().setObserver(this); mUiDelegate.getMetricsReporter().setRanker(mSuggestionsRanker); @@ -247,9 +243,6 @@ // If there is more than a section we want to show the headers for disambiguation purposes. if (mSections.size() != 1) return; - // On larger screens there is no need to hide the header and showing it is more consistent. - if (!mUiConfig.getCurrentDisplayStyle().isSmall()) return; - SuggestionsSection articlesSection = mSections.get(KnownCategories.ARTICLES); if (articlesSection == null) return;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SuggestionsSection.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SuggestionsSection.java index d2498867..05815973 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SuggestionsSection.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SuggestionsSection.java
@@ -37,8 +37,6 @@ public class SuggestionsSection extends InnerNode { private static final String TAG = "NtpCards"; - private static final Set<Integer> SECTION_DISMISSAL_GROUP = new HashSet<>(Arrays.asList(1, 2)); - private final Delegate mDelegate; private final SuggestionsCategoryInfo mCategoryInfo; private final OfflinePageBridge mOfflinePageBridge; @@ -489,14 +487,11 @@ private Set<Integer> getSectionDismissalRange() { if (hasSuggestions()) return Collections.emptySet(); - if (!mMoreButton.isVisible()) { - assert getStartingOffsetForChild(mStatus) == 1; - return Collections.singleton(1); - } + int statusCardIndex = getStartingOffsetForChild(mStatus); + if (!mMoreButton.isVisible()) return Collections.singleton(statusCardIndex); - assert SECTION_DISMISSAL_GROUP.contains(getStartingOffsetForChild(mStatus)); - assert SECTION_DISMISSAL_GROUP.contains(getStartingOffsetForChild(mMoreButton)); - return SECTION_DISMISSAL_GROUP; + assert statusCardIndex + 1 == getStartingOffsetForChild(mMoreButton); + return new HashSet<>(Arrays.asList(statusCardIndex, statusCardIndex + 1)); } public SuggestionsCategoryInfo getCategoryInfo() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/password_manager/AccountChooserDialog.java b/chrome/android/java/src/org/chromium/chrome/browser/password_manager/AccountChooserDialog.java index 36a80ad..225e06b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/password_manager/AccountChooserDialog.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/password_manager/AccountChooserDialog.java
@@ -18,6 +18,7 @@ import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; +import android.view.View.MeasureSpec; import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.ImageButton; @@ -214,25 +215,45 @@ text.setText(message); text.announceForAccessibility(message); - final int screenWidth = resources.getDisplayMetrics().widthPixels; - final int screenHeight = resources.getDisplayMetrics().heightPixels; - + // The tooltip should be shown above and to the left (right for RTL) of the info button. + // In order to do so the tooltip's location on the screen is determined. This location is + // specified with regard to the top left corner and ignores RTL layouts. For this reason the + // location of the tooltip is also specified as offsets to the top left corner of the + // screen. Since the tooltip should be shown above the info button, the height of the + // tooltip needs to be measured. Furthermore, the height of the statusbar is ignored when + // obtaining the icon's screen location, but must be considered when specifying a y offset. + // In addition, the measured width is needed in LTR layout, so that the right end of the + // tooltip aligns with the right end of the info icon. final int[] screenPos = new int[2]; view.getLocationOnScreen(screenPos); - final int width = view.getWidth(); - final int tooltipMargin = resources.getDimensionPixelSize(R.dimen.psl_info_tooltip_margin); + text.measure(MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), + MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)); - // The toast should be shown above and to the left (right for RTL) of the info button. - // In order to avoid measuring the size of the toast offsets are specified with regard - // to the bottom right / left corner of the screen. + final int width = view.getWidth(); + final int xOffset = ApiCompatibilityUtils.isLayoutRtl(view) ? screenPos[0] - : screenWidth - screenPos[0] - width; - final int yOffset = screenHeight - screenPos[1] + tooltipMargin; + : screenPos[0] + width - text.getMeasuredWidth(); + + final int statusBarHeightResourceId = + resources.getIdentifier("status_bar_height", "dimen", "android"); + + final int statusBarHeight = statusBarHeightResourceId > 0 + ? resources.getDimensionPixelSize(statusBarHeightResourceId) + : 0; + + final int tooltipMargin = resources.getDimensionPixelSize(R.dimen.psl_info_tooltip_margin); + + final int yOffset = + screenPos[1] - tooltipMargin - statusBarHeight - text.getMeasuredHeight(); + + // The xOffset is with regard to the left edge of the screen. Gravity.LEFT is deprecated, + // which is why the following line is necessary. + final int xGravity = ApiCompatibilityUtils.isLayoutRtl(view) ? Gravity.END : Gravity.START; Toast toast = new Toast(context); - toast.setGravity(Gravity.BOTTOM | Gravity.END, xOffset, yOffset); + toast.setGravity(Gravity.TOP | xGravity, xOffset, yOffset); toast.setDuration(Toast.LENGTH_SHORT); toast.setView(text); toast.show();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/displaystyle/UiConfig.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/displaystyle/UiConfig.java index ce5bfd9..5aa23d6 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/displaystyle/UiConfig.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/displaystyle/UiConfig.java
@@ -19,10 +19,9 @@ * Exposes general configuration info about the display style for a given reference View. */ public class UiConfig { - - public static final int REGULAR_DISPLAY_STYLE_MIN_WIDTH_DP = 360; + public static final int NARROW_DISPLAY_STYLE_MAX_WIDTH_DP = 320; public static final int WIDE_DISPLAY_STYLE_MIN_WIDTH_DP = 600; - public static final int REGULAR_DISPLAY_STYLE_MIN_HEIGHT_DP = 360; + public static final int FLAT_DISPLAY_STYLE_MAX_HEIGHT_DP = 320; private static final String TAG = "DisplayStyle"; private static final boolean DEBUG = false; @@ -94,7 +93,7 @@ @HorizontalDisplayStyle int newHorizontalDisplayStyle; - if (widthDp < REGULAR_DISPLAY_STYLE_MIN_WIDTH_DP) { + if (widthDp <= NARROW_DISPLAY_STYLE_MAX_WIDTH_DP) { newHorizontalDisplayStyle = HorizontalDisplayStyle.NARROW; } else if (widthDp >= WIDE_DISPLAY_STYLE_MIN_WIDTH_DP) { newHorizontalDisplayStyle = HorizontalDisplayStyle.WIDE; @@ -104,8 +103,8 @@ @VerticalDisplayStyle int newVerticalDisplayStyle = - heightDp < REGULAR_DISPLAY_STYLE_MIN_HEIGHT_DP ? VerticalDisplayStyle.FLAT - : VerticalDisplayStyle.REGULAR; + heightDp <= FLAT_DISPLAY_STYLE_MAX_HEIGHT_DP ? VerticalDisplayStyle.FLAT + : VerticalDisplayStyle.REGULAR; final DisplayStyle displayStyle = new DisplayStyle(newHorizontalDisplayStyle, newVerticalDisplayStyle);
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/SectionListTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/SectionListTest.java index 750ed15f..f9e2a34b 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/SectionListTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/SectionListTest.java
@@ -14,7 +14,6 @@ import static org.mockito.Mockito.when; import static org.chromium.chrome.browser.ntp.cards.ContentSuggestionsUnitTestUtils.bindViewHolders; -import static org.chromium.chrome.browser.ntp.cards.ContentSuggestionsUnitTestUtils.makeUiConfig; import static org.chromium.chrome.test.util.browser.suggestions.ContentSuggestionsTestUtils.createDummySuggestions; import static org.chromium.chrome.test.util.browser.suggestions.ContentSuggestionsTestUtils.registerCategory; @@ -37,9 +36,6 @@ import org.chromium.chrome.browser.offlinepages.OfflinePageBridge; import org.chromium.chrome.browser.suggestions.SuggestionsMetricsReporter; import org.chromium.chrome.browser.suggestions.SuggestionsUiDelegate; -import org.chromium.chrome.browser.widget.displaystyle.HorizontalDisplayStyle; -import org.chromium.chrome.browser.widget.displaystyle.UiConfig; -import org.chromium.chrome.browser.widget.displaystyle.VerticalDisplayStyle; import org.chromium.chrome.test.util.browser.suggestions.ContentSuggestionsTestUtils.CategoryInfoBuilder; import org.chromium.chrome.test.util.browser.suggestions.FakeSuggestionsSource; import org.chromium.testing.local.LocalRobolectricTestRunner; @@ -99,7 +95,7 @@ registerCategory(mSuggestionSource, CATEGORY1 + CATEGORY2, 0); List<SnippetArticle> suggestions2 = registerCategory(mSuggestionSource, CATEGORY2, 4); - SectionList sectionList = new SectionList(mUiDelegate, mOfflinePageBridge, makeUiConfig()); + SectionList sectionList = new SectionList(mUiDelegate, mOfflinePageBridge); bindViewHolders(sectionList); @@ -133,7 +129,7 @@ registerCategory(mSuggestionSource, CATEGORY1 + CATEGORY2, 0); List<SnippetArticle> suggestions2 = registerCategory(mSuggestionSource, CATEGORY2, 4); - SectionList sectionList = new SectionList(mUiDelegate, mOfflinePageBridge, makeUiConfig()); + SectionList sectionList = new SectionList(mUiDelegate, mOfflinePageBridge); bindViewHolders(sectionList, 0, 5); // Bind until after the third item from |suggestions1|. @@ -228,7 +224,7 @@ registerCategory(mSuggestionSource, new CategoryInfoBuilder(CATEGORY2).withViewAllAction().build(), 3); - SectionList sectionList = new SectionList(mUiDelegate, mOfflinePageBridge, makeUiConfig()); + SectionList sectionList = new SectionList(mUiDelegate, mOfflinePageBridge); bindViewHolders(sectionList); assertThat(sectionList.getSectionForTesting(CATEGORY1) @@ -247,7 +243,7 @@ registerCategory(mSuggestionSource, CATEGORY1, 1); registerCategory(mSuggestionSource, new CategoryInfoBuilder(CATEGORY2).withViewAllAction().build(), 3); - SectionList sectionList = new SectionList(mUiDelegate, mOfflinePageBridge, makeUiConfig()); + SectionList sectionList = new SectionList(mUiDelegate, mOfflinePageBridge); bindViewHolders(sectionList); ArgumentCaptor<DestructionObserver> argument = @@ -269,34 +265,22 @@ @Test @Feature({"Ntp"}) - public void testArticlesHeaderShownOnRegularDisplays() { + public void testArticlesHeaderHiddenWhenAlone() { registerCategory(mSuggestionSource, KnownCategories.ARTICLES, 1); - SectionList sectionList = new SectionList(mUiDelegate, mOfflinePageBridge, makeUiConfig()); - SuggestionsSection articles = sectionList.getSectionForTesting(KnownCategories.ARTICLES); - assertTrue(articles.getHeaderItemForTesting().isVisible()); - } - - @Test - @Feature({"Ntp"}) - public void testArticlesHeaderHiddenOnNarrowDisplays() { - registerCategory(mSuggestionSource, KnownCategories.ARTICLES, 1); - - UiConfig config = makeUiConfig(HorizontalDisplayStyle.NARROW, VerticalDisplayStyle.REGULAR); - SectionList sectionList = new SectionList(mUiDelegate, mOfflinePageBridge, config); + SectionList sectionList = new SectionList(mUiDelegate, mOfflinePageBridge); SuggestionsSection articles = sectionList.getSectionForTesting(KnownCategories.ARTICLES); assertFalse(articles.getHeaderItemForTesting().isVisible()); } @Test @Feature({"Ntp"}) - public void testArticlesHeaderHiddenOnFlatDisplays() { - registerCategory(mSuggestionSource, KnownCategories.ARTICLES, 1); + public void testRandomSectionHeaderShownWhenAlone() { + registerCategory(mSuggestionSource, CATEGORY1, 1); - UiConfig config = makeUiConfig(HorizontalDisplayStyle.REGULAR, VerticalDisplayStyle.FLAT); - SectionList sectionList = new SectionList(mUiDelegate, mOfflinePageBridge, config); - SuggestionsSection articles = sectionList.getSectionForTesting(KnownCategories.ARTICLES); - assertFalse(articles.getHeaderItemForTesting().isVisible()); + SectionList sectionList = new SectionList(mUiDelegate, mOfflinePageBridge); + SuggestionsSection section = sectionList.getSectionForTesting(CATEGORY1); + assertTrue(section.getHeaderItemForTesting().isVisible()); } @Test @@ -305,8 +289,7 @@ registerCategory(mSuggestionSource, KnownCategories.ARTICLES, 1); registerCategory(mSuggestionSource, CATEGORY1, 1); - UiConfig config = makeUiConfig(HorizontalDisplayStyle.REGULAR, VerticalDisplayStyle.FLAT); - SectionList sectionList = new SectionList(mUiDelegate, mOfflinePageBridge, config); + SectionList sectionList = new SectionList(mUiDelegate, mOfflinePageBridge); SuggestionsSection articles = sectionList.getSectionForTesting(KnownCategories.ARTICLES); assertTrue(articles.getHeaderItemForTesting().isVisible()); }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/SuggestionsSectionTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/SuggestionsSectionTest.java index c2fe9dc..31302ff 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/SuggestionsSectionTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/SuggestionsSectionTest.java
@@ -118,6 +118,38 @@ @Test @Feature({"Ntp"}) + public void testGetDismissalGroupWithoutHeader() { + SuggestionsSection section = createSectionWithFetchAction(true); + section.setHeaderVisibility(false); + + assertEquals(ItemViewType.STATUS, section.getItemViewType(0)); + assertEquals(setOf(0, 1), section.getItemDismissalGroup(0)); + + assertEquals(ItemViewType.ACTION, section.getItemViewType(1)); + assertEquals(setOf(0, 1), section.getItemDismissalGroup(1)); + } + + @Test + @Feature({"Ntp"}) + public void testGetDismissalGroupWithoutAction() { + SuggestionsSection section = createSectionWithFetchAction(false); + + assertEquals(ItemViewType.STATUS, section.getItemViewType(1)); + assertEquals(Collections.singleton(1), section.getItemDismissalGroup(1)); + } + + @Test + @Feature({"Ntp"}) + public void testGetDismissalGroupActionAndHeader() { + SuggestionsSection section = createSectionWithFetchAction(false); + section.setHeaderVisibility(false); + + assertEquals(ItemViewType.STATUS, section.getItemViewType(0)); + assertEquals(Collections.singleton(0), section.getItemDismissalGroup(0)); + } + + @Test + @Feature({"Ntp"}) public void testAddSuggestionsNotification() { final int suggestionCount = 5; List<SnippetArticle> snippets = createDummySuggestions(suggestionCount,
diff --git a/chrome/browser/chromeos/policy/restore_on_startup_browsertest_chromeos.cc b/chrome/browser/chromeos/policy/restore_on_startup_browsertest_chromeos.cc index 8a88dca..468fa4d7 100644 --- a/chrome/browser/chromeos/policy/restore_on_startup_browsertest_chromeos.cc +++ b/chrome/browser/chromeos/policy/restore_on_startup_browsertest_chromeos.cc
@@ -70,13 +70,16 @@ } // Verify that the policies are honored on a new user's login. -IN_PROC_BROWSER_TEST_F(RestoreOnStartupTestChromeOS, PRE_LogInAndVerify) { +// Disabled https://crbug.com/694269 +IN_PROC_BROWSER_TEST_F(RestoreOnStartupTestChromeOS, + DISABLED_PRE_LogInAndVerify) { SkipToLoginScreen(); LogInAndVerifyStartUpURLs(); } // Verify that the policies are honored on an existing user's login. -IN_PROC_BROWSER_TEST_F(RestoreOnStartupTestChromeOS, LogInAndVerify) { +// Disabled https://crbug.com/694269 +IN_PROC_BROWSER_TEST_F(RestoreOnStartupTestChromeOS, DISABLED_LogInAndVerify) { content::WindowedNotificationObserver( chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE, content::NotificationService::AllSources()).Wait();
diff --git a/chrome/browser/profiles/profile_browsertest.cc b/chrome/browser/profiles/profile_browsertest.cc index 2c68938..b21a79357 100644 --- a/chrome/browser/profiles/profile_browsertest.cc +++ b/chrome/browser/profiles/profile_browsertest.cc
@@ -50,6 +50,7 @@ #include "net/test/embedded_test_server/http_request.h" #include "net/test/embedded_test_server/http_response.h" #include "net/test/url_request/url_request_failed_job.h" +#include "net/traffic_annotation/network_traffic_annotation_test_helper.h" #include "net/url_request/url_fetcher.h" #include "net/url_request/url_fetcher_delegate.h" #include "net/url_request/url_request_context_getter.h" @@ -78,7 +79,10 @@ net::URLRequestStatus expected_request_status) : expected_request_status_(expected_request_status), is_complete_(false), - fetcher_(net::URLFetcher::Create(url, net::URLFetcher::GET, this)) { + fetcher_(net::URLFetcher::Create(url, + net::URLFetcher::GET, + this, + TRAFFIC_ANNOTATION_FOR_TESTS)) { fetcher_->SetRequestContext(context_getter.get()); fetcher_->Start(); }
diff --git a/chrome/browser/profiles/profile_downloader.cc b/chrome/browser/profiles/profile_downloader.cc index 01e19295..ea33467a 100644 --- a/chrome/browser/profiles/profile_downloader.cc +++ b/chrome/browser/profiles/profile_downloader.cc
@@ -35,6 +35,7 @@ #include "content/public/browser/browser_thread.h" #include "google_apis/gaia/gaia_constants.h" #include "net/base/load_flags.h" +#include "net/traffic_annotation/network_traffic_annotation.h" #include "net/url_request/url_fetcher.h" #include "net/url_request/url_request_status.h" #include "skia/ext/image_operations.h" @@ -237,9 +238,33 @@ return; } + // Create traffic annotation tag. + net::NetworkTrafficAnnotationTag traffic_annotation = + net::DefineNetworkTrafficAnnotation("signed_in_profile_avatar", R"( + semantics { + sender: "Profile G+ Image Downloader" + description: + "Signed in users use their G+ profile image as their Chrome " + "profile image, unless they explicitly select otherwise. This " + "fetcher uses the sign-in token and the image URL provided by GAIA " + "to fetch the image." + trigger: "User signs into a Profile." + data: "Filename of the png to download and Google OAuth bearer token." + destination: GOOGLE_OWNED_SERVICE + } + policy { + cookies_allowed: false + setting: "This feature cannot be disabled by settings." + policy_exception_justification: + "Not implemented, considered not useful as no content is being " + "uploaded or saved; this request merely downloads the user's G+ " + "profile image." + })"); + VLOG(1) << "Fetching profile image from " << image_url_with_size; - profile_image_fetcher_ = net::URLFetcher::Create( - GURL(image_url_with_size), net::URLFetcher::GET, this); + profile_image_fetcher_ = + net::URLFetcher::Create(GURL(image_url_with_size), net::URLFetcher::GET, + this, traffic_annotation); data_use_measurement::DataUseUserData::AttachToFetcher( profile_image_fetcher_.get(), data_use_measurement::DataUseUserData::PROFILE_DOWNLOADER);
diff --git a/chrome/browser/resources/local_ntp/local_ntp.js b/chrome/browser/resources/local_ntp/local_ntp.js index c21d544..f30a670 100644 --- a/chrome/browser/resources/local_ntp/local_ntp.js +++ b/chrome/browser/resources/local_ntp/local_ntp.js
@@ -338,7 +338,8 @@ /** - * Fetches new data, creates, and renders tiles. + * Fetches new data (RIDs) from the embeddedSearch.newTabPage API and passes + * them to the iframe. */ function reloadTiles() { var pages = ntpApiHandle.mostVisited; @@ -649,7 +650,7 @@ var iframe = document.createElement('iframe'); iframe.id = IDS.TILES_IFRAME; iframe.tabIndex = 1; - iframe.src = '//most-visited/single.html?' + args.join('&'); + iframe.src = 'chrome-search://most-visited/single.html?' + args.join('&'); $(IDS.TILES).appendChild(iframe); iframe.onload = function() {
diff --git a/chrome/browser/search/suggestions/image_decoder_impl.h b/chrome/browser/search/suggestions/image_decoder_impl.h index 658b7c4..0757e27 100644 --- a/chrome/browser/search/suggestions/image_decoder_impl.h +++ b/chrome/browser/search/suggestions/image_decoder_impl.h
@@ -13,7 +13,9 @@ namespace suggestions { -// image_fetcher::ImageDecoder Implementation. +// image_fetcher::ImageDecoder implementation. +// TODO(treib,markusheintz): Move this to a better place - it really has +// nothing to do with suggestions. crbug.com/624761 class ImageDecoderImpl : public image_fetcher::ImageDecoder { public: ImageDecoderImpl();
diff --git a/chrome/browser/ui/search/instant_test_utils.cc b/chrome/browser/ui/search/instant_test_utils.cc index 6ab4a5f..0708ea50 100644 --- a/chrome/browser/ui/search/instant_test_utils.cc +++ b/chrome/browser/ui/search/instant_test_utils.cc
@@ -104,32 +104,32 @@ nav_observer.Wait(); } -bool InstantTestBase::GetBoolFromJS(content::WebContents* contents, +bool InstantTestBase::GetBoolFromJS(const content::ToRenderFrameHost& adapter, const std::string& script, bool* result) { - return content::ExecuteScriptAndExtractBool( - contents, WrapScript(script), result); + return content::ExecuteScriptAndExtractBool(adapter, WrapScript(script), + result); } -bool InstantTestBase::GetIntFromJS(content::WebContents* contents, +bool InstantTestBase::GetIntFromJS(const content::ToRenderFrameHost& adapter, const std::string& script, int* result) { - return content::ExecuteScriptAndExtractInt( - contents, WrapScript(script), result); + return content::ExecuteScriptAndExtractInt(adapter, WrapScript(script), + result); } -bool InstantTestBase::GetDoubleFromJS(content::WebContents* contents, +bool InstantTestBase::GetDoubleFromJS(const content::ToRenderFrameHost& adapter, const std::string& script, double* result) { - return content::ExecuteScriptAndExtractDouble(contents, WrapScript(script), + return content::ExecuteScriptAndExtractDouble(adapter, WrapScript(script), result); } -bool InstantTestBase::GetStringFromJS(content::WebContents* contents, +bool InstantTestBase::GetStringFromJS(const content::ToRenderFrameHost& adapter, const std::string& script, std::string* result) { - return content::ExecuteScriptAndExtractString( - contents, WrapScript(script), result); + return content::ExecuteScriptAndExtractString(adapter, WrapScript(script), + result); } std::string InstantTestBase::GetOmniboxText() {
diff --git a/chrome/browser/ui/search/instant_test_utils.h b/chrome/browser/ui/search/instant_test_utils.h index e688e22..0d5f678 100644 --- a/chrome/browser/ui/search/instant_test_utils.h +++ b/chrome/browser/ui/search/instant_test_utils.h
@@ -13,15 +13,12 @@ #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/location_bar/location_bar.h" #include "chrome/browser/ui/search/instant_controller.h" +#include "content/public/test/browser_test_utils.h" #include "net/test/embedded_test_server/embedded_test_server.h" #include "url/gurl.h" class OmniboxView; -namespace content { -class WebContents; -}; - // This utility class is meant to be used in a "mix-in" fashion, giving the // derived test class additional Instant-related functionality. class InstantTestBase { @@ -55,16 +52,16 @@ void PressEnterAndWaitForNavigation(); void PressEnterAndWaitForFrameLoad(); - bool GetBoolFromJS(content::WebContents* contents, + bool GetBoolFromJS(const content::ToRenderFrameHost& adapter, const std::string& script, bool* result) WARN_UNUSED_RESULT; - bool GetIntFromJS(content::WebContents* contents, + bool GetIntFromJS(const content::ToRenderFrameHost& adapter, const std::string& script, int* result) WARN_UNUSED_RESULT; - bool GetDoubleFromJS(content::WebContents* contents, + bool GetDoubleFromJS(const content::ToRenderFrameHost& adapter, const std::string& script, double* result) WARN_UNUSED_RESULT; - bool GetStringFromJS(content::WebContents* contents, + bool GetStringFromJS(const content::ToRenderFrameHost& adapter, const std::string& script, std::string* result) WARN_UNUSED_RESULT;
diff --git a/chrome/browser/ui/search/local_ntp_browsertest.cc b/chrome/browser/ui/search/local_ntp_browsertest.cc index 97cd8e9c..c80828b 100644 --- a/chrome/browser/ui/search/local_ntp_browsertest.cc +++ b/chrome/browser/ui/search/local_ntp_browsertest.cc
@@ -19,6 +19,7 @@ #include "components/prefs/pref_service.h" #include "content/public/browser/notification_service.h" #include "content/public/browser/web_contents.h" +#include "content/public/test/browser_test_utils.h" #include "content/public/test/test_utils.h" #include "net/test/embedded_test_server/embedded_test_server.h" #include "ui/base/resource/resource_bundle.h" @@ -135,6 +136,81 @@ EXPECT_FALSE(result); } +namespace { + +// Returns the RenderFrameHost corresponding to the most visited iframe in the +// given |tab|. |tab| must correspond to an NTP. +content::RenderFrameHost* GetMostVisitedIframe(content::WebContents* tab) { + CHECK_EQ(2u, tab->GetAllFrames().size()); + for (content::RenderFrameHost* frame : tab->GetAllFrames()) { + if (frame != tab->GetMainFrame()) { + return frame; + } + } + NOTREACHED(); + return nullptr; +} + +} // namespace + +IN_PROC_BROWSER_TEST_F(LocalNTPTest, LoadsIframe) { + ASSERT_NO_FATAL_FAILURE(SetupInstant(browser())); + FocusOmnibox(); + + ui_test_utils::NavigateToURLWithDisposition( + browser(), ntp_url(), WindowOpenDisposition::NEW_FOREGROUND_TAB, + ui_test_utils::BROWSER_TEST_WAIT_FOR_TAB | + ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); + content::WebContents* active_tab = + browser()->tab_strip_model()->GetActiveWebContents(); + ASSERT_TRUE(search::IsInstantNTP(active_tab)); + + content::DOMMessageQueue msg_queue; + + bool result = false; + ASSERT_TRUE(GetBoolFromJS(active_tab, "!!setupAdvancedTest(true)", &result)); + ASSERT_TRUE(result); + + // Wait for the MV iframe to load. + std::string message; + // First get rid of the "true" message from the GetBoolFromJS call above. + ASSERT_TRUE(msg_queue.PopMessage(&message)); + ASSERT_EQ("true", message); + // Now wait for the "loaded" message. + ASSERT_TRUE(msg_queue.WaitForMessage(&message)); + ASSERT_EQ("\"loaded\"", message); + + // Get the iframe and check that the tiles loaded correctly. + content::RenderFrameHost* iframe = GetMostVisitedIframe(active_tab); + + // Get the total number of (non-empty) tiles from the iframe. + int total_thumbs = 0; + ASSERT_TRUE(GetIntFromJS( + iframe, "document.querySelectorAll('.mv-thumb').length", &total_thumbs)); + // Also get how many of the tiles succeeded and failed in loading their + // thumbnail images. + int succeeded_imgs = 0; + ASSERT_TRUE(GetIntFromJS(iframe, + "document.querySelectorAll('.mv-thumb img').length", + &succeeded_imgs)); + int failed_imgs = 0; + ASSERT_TRUE(GetIntFromJS( + iframe, "document.querySelectorAll('.mv-thumb.failed-img').length", + &failed_imgs)); + + // First, sanity check that the numbers line up (none of the css classes was + // renamed, etc). + EXPECT_EQ(total_thumbs, succeeded_imgs + failed_imgs); + + // Since we're in a non-signed-in, fresh profile with no history, there should + // be the default TopSites tiles (see history::PrepopulatedPage). + // Check that there is at least one tile, and that all of them loaded their + // images successfully. + EXPECT_GT(total_thumbs, 0); + EXPECT_EQ(total_thumbs, succeeded_imgs); + EXPECT_EQ(0, failed_imgs); +} + IN_PROC_BROWSER_TEST_F(LocalNTPTest, NTPRespectsBrowserLanguageSetting) { // Make sure the default language is not French.
diff --git a/chrome/test/data/extensions/api_test/webrequest/csp/violation.html b/chrome/test/data/extensions/api_test/webrequest/csp/violation.html new file mode 100644 index 0000000..de4cfe37 --- /dev/null +++ b/chrome/test/data/extensions/api_test/webrequest/csp/violation.html
@@ -0,0 +1,4 @@ +This page is served with a report-uri in its CSP header, and content that violates the policy. +<script> +console.log('This should be blocked by the Content-Security-Policy, and reported to the value in report-uri.'); +</script>
diff --git a/chrome/test/data/extensions/api_test/webrequest/csp/violation.html.mock-http-headers b/chrome/test/data/extensions/api_test/webrequest/csp/violation.html.mock-http-headers new file mode 100644 index 0000000..dedf3b3 --- /dev/null +++ b/chrome/test/data/extensions/api_test/webrequest/csp/violation.html.mock-http-headers
@@ -0,0 +1,3 @@ +HTTP/1.1 200 OK +Content-Type: text/html +Content-Security-Policy: script-src 'none'; report-uri /csp-violation-dont-ignore-me
diff --git a/chrome/test/data/extensions/api_test/webrequest/test_types.js b/chrome/test/data/extensions/api_test/webrequest/test_types.js index 561cd0c..5bf86cb 100644 --- a/chrome/test/data/extensions/api_test/webrequest/test_types.js +++ b/chrome/test/data/extensions/api_test/webrequest/test_types.js
@@ -35,6 +35,12 @@ return getServerURL('empty.html?as-beacon'); } +function getCSPReportURL() { + // dont-ignore-me is included so that framework.js does not filter out the + // request of type "other". + return getServerURL('csp-violation-dont-ignore-me'); +} + // A slow URL used for the beacon test, to make sure that the test fails // deterministically if there is a bug that causes the frameId/tabId to not be // set if the frame is removed during the request. @@ -610,4 +616,94 @@ }; frame.remove(); }, + + function typeOther_cspreport() { + expect([ + { label: 'onBeforeRequest', + event: 'onBeforeRequest', + details: { + type: 'csp_report', + method: 'POST', + url: getCSPReportURL(), + frameUrl: 'unknown frame URL', + frameId: 1, + parentFrameId: 0, + tabId: 1, + } + }, + { label: 'onBeforeSendHeaders', + event: 'onBeforeSendHeaders', + details: { + type: 'csp_report', + method: 'POST', + url: getCSPReportURL(), + frameId: 1, + parentFrameId: 0, + tabId: 1, + }, + }, + { label: 'onSendHeaders', + event: 'onSendHeaders', + details: { + type: 'csp_report', + method: 'POST', + url: getCSPReportURL(), + frameId: 1, + parentFrameId: 0, + tabId: 1, + }, + }, + { label: 'onHeadersReceived', + event: 'onHeadersReceived', + details: { + type: 'csp_report', + method: 'POST', + url: getCSPReportURL(), + frameId: 1, + parentFrameId: 0, + tabId: 1, + statusLine: 'HTTP/1.1 404 Not Found', + statusCode: 404, + }, + }, + { label: 'onResponseStarted', + event: 'onResponseStarted', + details: { + type: 'csp_report', + method: 'POST', + url: getCSPReportURL(), + frameId: 1, + parentFrameId: 0, + tabId: 1, + ip: '127.0.0.1', + fromCache: false, + statusLine: 'HTTP/1.1 404 Not Found', + statusCode: 404, + }, + }, + { label: 'onCompleted', + event: 'onCompleted', + details: { + type: 'csp_report', + method: 'POST', + url: getCSPReportURL(), + frameId: 1, + parentFrameId: 0, + tabId: 1, + ip: '127.0.0.1', + fromCache: false, + statusLine: 'HTTP/1.1 404 Not Found', + statusCode: 404, + }, + }], + [['onBeforeRequest', 'onBeforeSendHeaders', 'onSendHeaders', + 'onHeadersReceived', 'onResponseStarted', 'onCompleted']], { + urls: ['<all_urls>'], types: ['csp_report'] + }); + + var frame = document.createElement('iframe'); + frame.src = + getServerURL('extensions/api_test/webrequest/csp/violation.html'); + document.body.appendChild(frame); + }, ]);
diff --git a/chrome/test/data/local_ntp_browsertest.js b/chrome/test/data/local_ntp_browsertest.js index bb33e34..f16fc95f 100644 --- a/chrome/test/data/local_ntp_browsertest.js +++ b/chrome/test/data/local_ntp_browsertest.js
@@ -139,7 +139,18 @@ // Advanced tests are controlled from the native side. The helpers here are // called from native code to set up the page and to check results. -function setupAdvancedTest() { +function handlePostMessage(event) { + if (event.data.cmd == 'loaded') { + domAutomationController.setAutomationId(0); + domAutomationController.send('loaded'); + } +} + +function setupAdvancedTest(opt_waitForIframeLoaded) { + if (opt_waitForIframeLoaded) { + window.addEventListener('message', handlePostMessage); + } + setUp(); initLocalNTP(/*isGooglePage=*/true);
diff --git a/chrome/test/data/webui/settings/settings_autofill_section_browsertest.js b/chrome/test/data/webui/settings/settings_autofill_section_browsertest.js index 5431d452..360debc 100644 --- a/chrome/test/data/webui/settings/settings_autofill_section_browsertest.js +++ b/chrome/test/data/webui/settings/settings_autofill_section_browsertest.js
@@ -170,7 +170,10 @@ }, }; -TEST_F('SettingsAutofillSectionBrowserTest', 'CreditCardTests', function() { +// Disabled because of flakiness http://crbug.com/694289 +TEST_F('SettingsAutofillSectionBrowserTest', + 'DISABLED_CreditCardTests', + function() { var self = this; setup(function() {
diff --git a/components/browser_watcher/BUILD.gn b/components/browser_watcher/BUILD.gn index 6963cef3..2e831c9 100644 --- a/components/browser_watcher/BUILD.gn +++ b/components/browser_watcher/BUILD.gn
@@ -69,6 +69,7 @@ ":stability_data", ":stability_report_proto", "//base", + "//components/variations", "//third_party/crashpad/crashpad/client", "//third_party/crashpad/crashpad/util", ]
diff --git a/components/browser_watcher/DEPS b/components/browser_watcher/DEPS index 1d59b5c..7650b54 100644 --- a/components/browser_watcher/DEPS +++ b/components/browser_watcher/DEPS
@@ -1,4 +1,5 @@ include_rules = [ "+components/metrics", + "+components/variations", "+third_party/crashpad/crashpad", ]
diff --git a/components/browser_watcher/postmortem_report_collector.cc b/components/browser_watcher/postmortem_report_collector.cc index 8f1ccd4..7f5bf145 100644 --- a/components/browser_watcher/postmortem_report_collector.cc +++ b/components/browser_watcher/postmortem_report_collector.cc
@@ -13,9 +13,11 @@ #include "base/metrics/histogram_macros.h" #include "base/path_service.h" #include "base/strings/string_piece.h" +#include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "components/browser_watcher/postmortem_minidump_writer.h" #include "components/browser_watcher/stability_data_names.h" +#include "components/variations/active_field_trials.h" #include "third_party/crashpad/crashpad/client/settings.h" #include "third_party/crashpad/crashpad/util/misc/uuid.h" @@ -32,14 +34,18 @@ namespace { +const char kFieldTrialKeyPrefix[] = "FieldTrial."; + // Collects stability user data from the recorded format to the collected // format. void CollectUserData( const ActivityUserData::Snapshot& recorded_map, - google::protobuf::Map<std::string, TypedValue>* collected_map) { + google::protobuf::Map<std::string, TypedValue>* collected_map, + StabilityReport* report) { DCHECK(collected_map); for (const auto& name_and_value : recorded_map) { + const std::string& key = name_and_value.first; const ActivityUserData::TypedValue& recorded_value = name_and_value.second; TypedValue collected_value; @@ -47,9 +53,11 @@ case ActivityUserData::END_OF_VALUES: NOTREACHED(); break; - case ActivityUserData::RAW_VALUE: - collected_value.set_bytes_value(recorded_value.Get().as_string()); + case ActivityUserData::RAW_VALUE: { + base::StringPiece raw = recorded_value.Get(); + collected_value.set_bytes_value(raw.data(), raw.size()); break; + } case ActivityUserData::RAW_VALUE_REFERENCE: { base::StringPiece recorded_ref = recorded_value.GetReference(); TypedValue::Reference* collected_ref = @@ -59,10 +67,25 @@ collected_ref->set_size(recorded_ref.size()); break; } - case ActivityUserData::STRING_VALUE: - collected_value.set_string_value( - recorded_value.GetString().as_string()); + case ActivityUserData::STRING_VALUE: { + base::StringPiece value = recorded_value.GetString(); + + if (report && base::StartsWith(key, kFieldTrialKeyPrefix, + base::CompareCase::SENSITIVE)) { + // This entry represents an active Field Trial. + std::string trial_name = + key.substr(std::strlen(kFieldTrialKeyPrefix)); + variations::ActiveGroupId group_id = + variations::MakeActiveGroupId(trial_name, value.as_string()); + FieldTrial* field_trial = report->add_field_trials(); + field_trial->set_name_id(group_id.name); + field_trial->set_group_id(group_id.group); + continue; + } + + collected_value.set_string_value(value.data(), value.size()); break; + } case ActivityUserData::STRING_VALUE_REFERENCE: { base::StringPiece recorded_ref = recorded_value.GetStringReference(); TypedValue::Reference* collected_ref = @@ -72,10 +95,11 @@ collected_ref->set_size(recorded_ref.size()); break; } - case ActivityUserData::CHAR_VALUE: - collected_value.set_char_value( - std::string(1, recorded_value.GetChar())); + case ActivityUserData::CHAR_VALUE: { + char char_value = recorded_value.GetChar(); + collected_value.set_char_value(&char_value, 1); break; + } case ActivityUserData::BOOL_VALUE: collected_value.set_bool_value(recorded_value.GetBool()); break; @@ -87,7 +111,7 @@ break; } - (*collected_map)[name_and_value.first].Swap(&collected_value); + (*collected_map)[key].Swap(&collected_value); } } @@ -288,7 +312,7 @@ // Collect global user data. google::protobuf::Map<std::string, TypedValue>& global_data = *(*report)->mutable_global_data(); - CollectUserData(global_data_snapshot, &global_data); + CollectUserData(global_data_snapshot, &global_data, report->get()); // Add the reporting Chrome's details to the report. global_data[kStabilityReporterChannel].set_string_value(channel_name()); @@ -371,7 +395,7 @@ // Collect user data if (i < snapshot.user_data_stack.size()) { CollectUserData(snapshot.user_data_stack[i], - collected->mutable_user_data()); + collected->mutable_user_data(), nullptr); } } }
diff --git a/components/browser_watcher/postmortem_report_collector.h b/components/browser_watcher/postmortem_report_collector.h index 4dd768d35..0650d37ec 100644 --- a/components/browser_watcher/postmortem_report_collector.h +++ b/components/browser_watcher/postmortem_report_collector.h
@@ -80,6 +80,9 @@ GlobalUserDataCollection); FRIEND_TEST_ALL_PREFIXES( PostmortemReportCollectorCollectionFromGlobalTrackerTest, + FieldTrialCollection); + FRIEND_TEST_ALL_PREFIXES( + PostmortemReportCollectorCollectionFromGlobalTrackerTest, ModuleCollection); // Virtual for unittesting.
diff --git a/components/browser_watcher/postmortem_report_collector_unittest.cc b/components/browser_watcher/postmortem_report_collector_unittest.cc index 8d8d5cc..ae241e3 100644 --- a/components/browser_watcher/postmortem_report_collector_unittest.cc +++ b/components/browser_watcher/postmortem_report_collector_unittest.cc
@@ -650,6 +650,38 @@ } TEST_F(PostmortemReportCollectorCollectionFromGlobalTrackerTest, + FieldTrialCollection) { + // Record some data. + GlobalActivityTracker::CreateWithFile(debug_file_path(), kMemorySize, 0ULL, + "", 3); + ActivityUserData& global_data = GlobalActivityTracker::Get()->global_data(); + global_data.SetString("string", "bar"); + global_data.SetString("FieldTrial.string", "bar"); + global_data.SetString("FieldTrial.foo", "bar"); + + // Collect the stability report. + PostmortemReportCollector collector(kProductName, kVersionNumber, + kChannelName); + std::unique_ptr<StabilityReport> report; + ASSERT_EQ(PostmortemReportCollector::SUCCESS, + collector.Collect(debug_file_path(), &report)); + ASSERT_NE(nullptr, report); + + // Validate the report's experiment and global data. + ASSERT_EQ(2, report->field_trials_size()); + EXPECT_NE(0U, report->field_trials(0).name_id()); + EXPECT_NE(0U, report->field_trials(0).group_id()); + EXPECT_NE(0U, report->field_trials(1).name_id()); + EXPECT_EQ(report->field_trials(0).group_id(), + report->field_trials(1).group_id()); + + // Expect 5 key/value pairs (including product details). + const auto& collected_data = report->global_data(); + EXPECT_EQ(5U, collected_data.size()); + EXPECT_TRUE(base::ContainsKey(collected_data, "string")); +} + +TEST_F(PostmortemReportCollectorCollectionFromGlobalTrackerTest, ModuleCollection) { // Record some module information. GlobalActivityTracker::CreateWithFile(debug_file_path(), kMemorySize, 0ULL,
diff --git a/components/browser_watcher/stability_report.proto b/components/browser_watcher/stability_report.proto index 7f20f7d5..b5039a2 100644 --- a/components/browser_watcher/stability_report.proto +++ b/components/browser_watcher/stability_report.proto
@@ -150,10 +150,24 @@ // TODO(manzagop): add experiment state. } +// Description of a field trial or experiment that the user is currently +// enrolled in. This message is an analogue of the UMA proto in +// components/metrics/proto/system_profile.proto. For details about generating +// the identifiers from the field trial and group names, see +// variations::MakeActiveGroupId(). +// Next id: 3 +message FieldTrial { + // A 32-bit identifier for the name of the field trial. + optional fixed32 name_id = 1; + + // A 32-bit identifier for the user's group within the field trial. + optional fixed32 group_id = 2; +} + // A stability report contains information pertaining to the execution of a // single logical instance of a "chrome browser". It is comprised of information // about the system state and about the chrome browser's processes. -// Next id: 5 +// Next id: 6 message StabilityReport { optional SystemState system_state = 1; // TODO(manzagop): revisit whether a single repeated field should contain all @@ -166,4 +180,7 @@ // relocate these to their process (and perhaps thread). repeated string log_messages = 3; map<string, TypedValue> global_data = 4; + + // The field trials the user is currently enrolled in. + repeated FieldTrial field_trials = 5; }
diff --git a/components/image_fetcher/image_fetcher.h b/components/image_fetcher/image_fetcher.h index 6983638..9529bc1 100644 --- a/components/image_fetcher/image_fetcher.h +++ b/components/image_fetcher/image_fetcher.h
@@ -41,6 +41,9 @@ const GURL& image_url, base::Callback<void(const std::string&, const gfx::Image&)> callback) = 0; + // TODO(treib,markusheintz): Now that iOS uses the same ImageFetcherImpl (see + // crbug.com/689020), add a getter for the ImageDecoder here. + private: DISALLOW_COPY_AND_ASSIGN(ImageFetcher); };
diff --git a/components/image_fetcher/image_fetcher_impl.h b/components/image_fetcher/image_fetcher_impl.h index d8294ef..8c92d917 100644 --- a/components/image_fetcher/image_fetcher_impl.h +++ b/components/image_fetcher/image_fetcher_impl.h
@@ -28,8 +28,7 @@ namespace image_fetcher { -// TODO(markusheintz): Once the iOS implementation of the ImageFetcher is -// removed merge the two classes ImageFetcher and ImageFetcherImpl. +// The standard (non-test) implementation of ImageFetcher. class ImageFetcherImpl : public image_fetcher::ImageFetcher { public: ImageFetcherImpl(
diff --git a/components/subresource_filter/content/browser/BUILD.gn b/components/subresource_filter/content/browser/BUILD.gn index 6388aab..24a4c3cf 100644 --- a/components/subresource_filter/content/browser/BUILD.gn +++ b/components/subresource_filter/content/browser/BUILD.gn
@@ -4,6 +4,8 @@ static_library("browser") { sources = [ + "async_document_subresource_filter.cc", + "async_document_subresource_filter.h", "content_ruleset_service_delegate.cc", "content_ruleset_service_delegate.h", "content_subresource_filter_driver_factory.cc", @@ -31,6 +33,7 @@ source_set("unit_tests") { testonly = true sources = [ + "async_document_subresource_filter_unittest.cc", "content_ruleset_service_delegate_unittest.cc", "content_subresource_filter_driver_factory_unittest.cc", "verified_ruleset_dealer_unittest.cc",
diff --git a/components/subresource_filter/content/browser/async_document_subresource_filter.cc b/components/subresource_filter/content/browser/async_document_subresource_filter.cc new file mode 100644 index 0000000..099eec1 --- /dev/null +++ b/components/subresource_filter/content/browser/async_document_subresource_filter.cc
@@ -0,0 +1,138 @@ +// Copyright 2017 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. + +#include "components/subresource_filter/content/browser/async_document_subresource_filter.h" + +#include <utility> + +#include "base/bind.h" +#include "base/bind_helpers.h" +#include "base/location.h" +#include "base/logging.h" +#include "base/task_runner_util.h" +#include "base/threading/sequenced_task_runner_handle.h" +#include "components/subresource_filter/core/common/memory_mapped_ruleset.h" + +namespace subresource_filter { + +// AsyncDocumentSubresourceFilter::InitializationParams ------------------------ + +using InitializationParams = + AsyncDocumentSubresourceFilter::InitializationParams; + +InitializationParams::InitializationParams() = default; + +InitializationParams::InitializationParams(GURL document_url, + ActivationLevel activation_level, + bool measure_performance) + : document_url(std::move(document_url)), + parent_activation_state(activation_level) { + DCHECK_NE(ActivationLevel::DISABLED, activation_level); + parent_activation_state.measure_performance = measure_performance; +} + +InitializationParams::InitializationParams( + GURL document_url, + url::Origin parent_document_origin, + ActivationState parent_activation_state) + : document_url(std::move(document_url)), + parent_document_origin(std::move(parent_document_origin)), + parent_activation_state(parent_activation_state) { + DCHECK_NE(ActivationLevel::DISABLED, + parent_activation_state.activation_level); +} + +InitializationParams::~InitializationParams() = default; +InitializationParams::InitializationParams(InitializationParams&&) = default; +InitializationParams& InitializationParams::operator=(InitializationParams&&) = + default; + +// AsyncDocumentSubresourceFilter ---------------------------------------------- + +AsyncDocumentSubresourceFilter::AsyncDocumentSubresourceFilter( + VerifiedRuleset::Handle* ruleset_handle, + InitializationParams params, + base::Callback<void(ActivationState)> activation_state_callback, + base::OnceClosure first_disallowed_load_callback) + : task_runner_(ruleset_handle->task_runner()), + core_(new Core(), base::OnTaskRunnerDeleter(task_runner_)), + first_disallowed_load_callback_( + std::move(first_disallowed_load_callback)) { + DCHECK_NE(ActivationLevel::DISABLED, + params.parent_activation_state.activation_level); + + // Note: It is safe to post |ruleset_handle|'s VerifiedRuleset pointer, + // because a task to delete it can only be posted to (and, therefore, + // processed by) |task_runner| after this method returns, hence after the + // below task is posted. + base::PostTaskAndReplyWithResult( + task_runner_, FROM_HERE, + base::Bind(&Core::Initialize, base::Unretained(core_.get()), + base::Passed(¶ms), ruleset_handle->ruleset_.get()), + std::move(activation_state_callback)); +} + +AsyncDocumentSubresourceFilter::~AsyncDocumentSubresourceFilter() { + DCHECK(thread_checker_.CalledOnValidThread()); +} + +void AsyncDocumentSubresourceFilter::GetLoadPolicyForSubdocument( + const GURL& subdocument_url, + LoadPolicyCallback result_callback) { + DCHECK(thread_checker_.CalledOnValidThread()); + + // TODO(pkalinnikov): Think about avoiding copy of |subdocument_url| if it is + // too big and won't be allowed anyway (e.g., it's a data: URI). + base::PostTaskAndReplyWithResult( + task_runner_, FROM_HERE, + base::Bind( + [](AsyncDocumentSubresourceFilter::Core* core, + const GURL& subdocument_url) { + DCHECK(core); + DocumentSubresourceFilter* filter = core->filter(); + return filter + ? filter->GetLoadPolicy(subdocument_url, + proto::ELEMENT_TYPE_SUBDOCUMENT) + : LoadPolicy::ALLOW; + }, + core_.get(), subdocument_url), + std::move(result_callback)); +} + +void AsyncDocumentSubresourceFilter::ReportDisallowedLoad() { + if (!first_disallowed_load_callback_.is_null()) + std::move(first_disallowed_load_callback_).Run(); +} + +// AsyncDocumentSubresourceFilter::Core ---------------------------------------- + +AsyncDocumentSubresourceFilter::Core::Core() { + thread_checker_.DetachFromThread(); +} + +AsyncDocumentSubresourceFilter::Core::~Core() { + DCHECK(thread_checker_.CalledOnValidThread()); +} + +ActivationState AsyncDocumentSubresourceFilter::Core::Initialize( + InitializationParams params, + VerifiedRuleset* verified_ruleset) { + DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK(verified_ruleset); + + if (!verified_ruleset->Get()) + return ActivationState(ActivationLevel::DISABLED); + + ActivationState activation_state = ComputeActivationState( + params.document_url, params.parent_document_origin, + params.parent_activation_state, verified_ruleset->Get()); + + DCHECK_NE(ActivationLevel::DISABLED, activation_state.activation_level); + filter_.emplace(url::Origin(params.document_url), activation_state, + verified_ruleset->Get()); + + return activation_state; +} + +} // namespace subresource_filter
diff --git a/components/subresource_filter/content/browser/async_document_subresource_filter.h b/components/subresource_filter/content/browser/async_document_subresource_filter.h new file mode 100644 index 0000000..3d4c9dd --- /dev/null +++ b/components/subresource_filter/content/browser/async_document_subresource_filter.h
@@ -0,0 +1,148 @@ +// Copyright 2017 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. + +#ifndef COMPONENTS_SUBRESOURCE_FILTER_CONTENT_BROWSER_ASYNC_DOCUMENT_SUBRESOURCE_FILTER_H_ +#define COMPONENTS_SUBRESOURCE_FILTER_CONTENT_BROWSER_ASYNC_DOCUMENT_SUBRESOURCE_FILTER_H_ + +#include <memory> + +#include "base/callback.h" +#include "base/macros.h" +#include "base/optional.h" +#include "base/sequenced_task_runner.h" +#include "base/threading/thread_checker.h" +#include "components/subresource_filter/content/browser/verified_ruleset_dealer.h" +#include "components/subresource_filter/core/common/activation_level.h" +#include "components/subresource_filter/core/common/activation_state.h" +#include "components/subresource_filter/core/common/document_subresource_filter.h" +#include "url/gurl.h" +#include "url/origin.h" + +namespace subresource_filter { + +// An asynchronous wrapper around DocumentSubresourceFilter (DSF). +// +// It is accessed on the UI thread and owns a DSF living on a dedicated +// sequenced |task_runner|. Provides asynchronous access to the DSF and destroys +// it asynchronously. +// +// Initially holds an empty filter in the synchronously created Core object, and +// initializes the filter on the |task_runner| asynchronously. This lets ADSF be +// created synchrously and be immediately used by clients on the UI thread, +// while the DSF is retrieved on the |task_runner| in a deferred manner. +class AsyncDocumentSubresourceFilter { + public: + using LoadPolicyCallback = base::Callback<void(LoadPolicy)>; + + class Core; + + // Encapsulates the parameters needed for computing the frame-level + // ActivationState appropriate for the frame this ADSF is created for. These + // parameters are posted to ADSF::Core during its initialization. + struct InitializationParams { + InitializationParams(); + + // Takes parameters needed for calculating the main-frame ActivationState, + // that is: the main-frame |document| URL, the page-level + // |activation_level|, and whether or not to |measure_performance|. + InitializationParams(GURL document_url, + ActivationLevel activation_level, + bool measure_performance); + + // Takes parameters needed for calculating the sub-frame ActivationState, + // that is: the sub-frame |document| URL, the origin of its |parent|, as + // well as the parent's |activation_state|. + InitializationParams(GURL document_url, + url::Origin parent_document_origin, + ActivationState parent_activation_state); + + ~InitializationParams(); + + InitializationParams(InitializationParams&& other); + InitializationParams& operator=(InitializationParams&& other); + + // Parameters used to compute ActivationState for the |document| before + // creating a DocumentSubresourceFilter. + GURL document_url; + url::Origin parent_document_origin; + ActivationState parent_activation_state; + + private: + DISALLOW_COPY_AND_ASSIGN(InitializationParams); + }; + + // Creates a Core and initializes it asynchronously on a |task_runner| using + // the supplied initialization |params| and a VerifiedRuleset taken from the + // |ruleset_handle|. The core remains owned by |this| object, but lives on + // (and is accessed on) the |task_runner|. + // + // Once the ActivationState for the current frame is calculated, it is + // reported back via |activation_state_callback| on the task runner associated + // with the current thread. If MemoryMappedRuleset is not present or + // malformed, then a default ActivationState is reported (with ActivationLevel + // equal to DISABLED). + // + // The |first_disallowed_load_callback|, if it is non-null, is invoked on the + // first ReportDisallowedLoad() call. + AsyncDocumentSubresourceFilter( + VerifiedRuleset::Handle* ruleset_handle, + InitializationParams params, + base::Callback<void(ActivationState)> activation_state_callback, + base::OnceClosure first_disallowed_load_callback); + + ~AsyncDocumentSubresourceFilter(); + + // Computes LoadPolicy on a |task_runner| and returns it back to the calling + // thread via |result_callback|. If MemoryMappedRuleset is not present or + // malformed, then a LoadPolicy::Allow is returned. + void GetLoadPolicyForSubdocument(const GURL& subdocument_url, + LoadPolicyCallback result_callback); + + // Invokes |first_disallowed_load_callback|, if necessary, and posts a task to + // call DocumentSubresourceFilter::reportDisallowedCallback() on the + // |task_runner|. + void ReportDisallowedLoad(); + + private: + // Note: Raw pointer, |core_| already holds a reference to |task_runner_|. + base::SequencedTaskRunner* task_runner_; + std::unique_ptr<Core, base::OnTaskRunnerDeleter> core_; + base::OnceClosure first_disallowed_load_callback_; + + base::ThreadChecker thread_checker_; + + DISALLOW_COPY_AND_ASSIGN(AsyncDocumentSubresourceFilter); +}; + +// Holds a DocumentSubresourceFilter that is created in a deferred manner in +// Initialize(), provided there is a valid ruleset to work with. +class AsyncDocumentSubresourceFilter::Core { + public: + Core(); + ~Core(); + + // Can return nullptr even after initialization in case MemoryMappedRuleset + // was not present, or was malformed during it. + DocumentSubresourceFilter* filter() { + DCHECK(thread_checker_.CalledOnValidThread()); + return filter_ ? &filter_.value() : nullptr; + } + + private: + friend class AsyncDocumentSubresourceFilter; + + // Computes ActivationState from |params| and initializes a DSF using it. + // Returns the computed activation state. + ActivationState Initialize(InitializationParams params, + VerifiedRuleset* verified_ruleset); + + base::Optional<DocumentSubresourceFilter> filter_; + base::ThreadChecker thread_checker_; + + DISALLOW_COPY_AND_ASSIGN(Core); +}; + +} // namespace subresource_filter + +#endif // COMPONENTS_SUBRESOURCE_FILTER_CONTENT_BROWSER_ASYNC_DOCUMENT_SUBRESOURCE_FILTER_H_
diff --git a/components/subresource_filter/content/browser/async_document_subresource_filter_unittest.cc b/components/subresource_filter/content/browser/async_document_subresource_filter_unittest.cc new file mode 100644 index 0000000..a3cef15 --- /dev/null +++ b/components/subresource_filter/content/browser/async_document_subresource_filter_unittest.cc
@@ -0,0 +1,267 @@ +// Copyright 2017 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. + +#include "components/subresource_filter/content/browser/async_document_subresource_filter.h" + +#include <memory> +#include <vector> + +#include "base/bind.h" +#include "base/bind_helpers.h" +#include "base/macros.h" +#include "base/memory/ptr_util.h" +#include "base/test/test_simple_task_runner.h" +#include "base/threading/sequenced_task_runner_handle.h" +#include "components/subresource_filter/core/common/proto/rules.pb.h" +#include "components/subresource_filter/core/common/test_ruleset_creator.h" +#include "components/subresource_filter/core/common/test_ruleset_utils.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace subresource_filter { + +class AsyncDocumentSubresourceFilterTest : public ::testing::Test { + public: + AsyncDocumentSubresourceFilterTest() + : reply_task_runner_(new base::TestSimpleTaskRunner), + reply_task_runner_handle_(reply_task_runner_), + blocking_task_runner_(new base::TestSimpleTaskRunner) {} + + protected: + void SetUp() override { + std::vector<proto::UrlRule> rules; + rules.push_back(testing::CreateWhitelistRuleForDocument( + "whitelisted.subframe.com", proto::ACTIVATION_TYPE_GENERICBLOCK, + {"example.com"})); + rules.push_back(testing::CreateSuffixRule("disallowed.html")); + + ASSERT_NO_FATAL_FAILURE(test_ruleset_creator_.CreateRulesetWithRules( + rules, &test_ruleset_pair_)); + + dealer_handle_.reset( + new VerifiedRulesetDealer::Handle(blocking_task_runner_)); + } + + void TearDown() override { + dealer_handle_.reset(nullptr); + RunUntilIdle(); + } + + const testing::TestRuleset& ruleset() const { + return test_ruleset_pair_.indexed; + } + + void RunUntilIdle() { + while (blocking_task_runner_->HasPendingTask() || + reply_task_runner_->HasPendingTask()) { + blocking_task_runner_->RunUntilIdle(); + reply_task_runner_->RunUntilIdle(); + } + } + + VerifiedRulesetDealer::Handle* dealer_handle() { + return dealer_handle_.get(); + } + + std::unique_ptr<VerifiedRuleset::Handle> CreateRulesetHandle() { + return base::MakeUnique<VerifiedRuleset::Handle>(dealer_handle()); + } + + private: + testing::TestRulesetCreator test_ruleset_creator_; + testing::TestRulesetPair test_ruleset_pair_; + + // Note: ADSF assumes a task runner is associated with the current thread. + scoped_refptr<base::TestSimpleTaskRunner> reply_task_runner_; + base::SequencedTaskRunnerHandle reply_task_runner_handle_; + scoped_refptr<base::TestSimpleTaskRunner> blocking_task_runner_; + + std::unique_ptr<VerifiedRulesetDealer::Handle> dealer_handle_; + + DISALLOW_COPY_AND_ASSIGN(AsyncDocumentSubresourceFilterTest); +}; + +namespace { + +class TestActivationStateCallbackReceiver { + public: + TestActivationStateCallbackReceiver() = default; + + base::Callback<void(ActivationState)> callback() { + return base::Bind(&TestActivationStateCallbackReceiver::Callback, + base::Unretained(this)); + } + void ExpectReceivedOnce(ActivationState expected_state) const { + ASSERT_EQ(1, callback_count_); + EXPECT_EQ(expected_state, last_activation_state_); + } + + private: + void Callback(ActivationState activation_state) { + ++callback_count_; + last_activation_state_ = activation_state; + } + + ActivationState last_activation_state_; + int callback_count_ = 0; + + DISALLOW_COPY_AND_ASSIGN(TestActivationStateCallbackReceiver); +}; + +class TestCallbackReceiver { + public: + TestCallbackReceiver() = default; + + base::Closure closure() { + return base::Bind(&TestCallbackReceiver::Callback, base::Unretained(this)); + } + int callback_count() const { return callback_count_; } + + private: + void Callback() { ++callback_count_; } + + int callback_count_ = 0; + + DISALLOW_COPY_AND_ASSIGN(TestCallbackReceiver); +}; + +class LoadPolicyCallbackReceiver { + public: + LoadPolicyCallbackReceiver() = default; + + AsyncDocumentSubresourceFilter::LoadPolicyCallback callback() { + return base::Bind(&LoadPolicyCallbackReceiver::Callback, + base::Unretained(this)); + } + void ExpectReceivedOnce(LoadPolicy load_policy) const { + ASSERT_EQ(1, callback_count_); + EXPECT_EQ(load_policy, last_load_policy_); + } + + private: + void Callback(LoadPolicy load_policy) { + ++callback_count_; + last_load_policy_ = load_policy; + } + + int callback_count_ = 0; + LoadPolicy last_load_policy_; + + DISALLOW_COPY_AND_ASSIGN(LoadPolicyCallbackReceiver); +}; + +} // namespace + +TEST_F(AsyncDocumentSubresourceFilterTest, ActivationStateIsReported) { + dealer_handle()->SetRulesetFile(testing::TestRuleset::Open(ruleset())); + auto ruleset_handle = CreateRulesetHandle(); + + AsyncDocumentSubresourceFilter::InitializationParams params( + GURL("http://example.com"), ActivationLevel::ENABLED, false); + + TestActivationStateCallbackReceiver activation_state; + auto filter = base::MakeUnique<AsyncDocumentSubresourceFilter>( + ruleset_handle.get(), std::move(params), activation_state.callback(), + base::OnceClosure()); + + RunUntilIdle(); + activation_state.ExpectReceivedOnce( + ActivationState(ActivationLevel::ENABLED)); +} + +TEST_F(AsyncDocumentSubresourceFilterTest, ActivationStateIsComputedCorrectly) { + dealer_handle()->SetRulesetFile(testing::TestRuleset::Open(ruleset())); + auto ruleset_handle = CreateRulesetHandle(); + + AsyncDocumentSubresourceFilter::InitializationParams params( + GURL("http://whitelisted.subframe.com"), ActivationLevel::ENABLED, false); + params.parent_document_origin = url::Origin(GURL("http://example.com")); + + TestActivationStateCallbackReceiver activation_state; + auto filter = base::MakeUnique<AsyncDocumentSubresourceFilter>( + ruleset_handle.get(), std::move(params), activation_state.callback(), + base::OnceClosure()); + + RunUntilIdle(); + + ActivationState expected_activation_state(ActivationLevel::ENABLED); + expected_activation_state.generic_blocking_rules_disabled = true; + activation_state.ExpectReceivedOnce(expected_activation_state); +} + +TEST_F(AsyncDocumentSubresourceFilterTest, DisabledForCorruptRuleset) { + testing::TestRuleset::CorruptByFilling(ruleset(), 0, 100, 0xFF); + dealer_handle()->SetRulesetFile(testing::TestRuleset::Open(ruleset())); + + auto ruleset_handle = CreateRulesetHandle(); + + AsyncDocumentSubresourceFilter::InitializationParams params( + GURL("http://example.com"), ActivationLevel::ENABLED, false); + + TestActivationStateCallbackReceiver activation_state; + auto filter = base::MakeUnique<AsyncDocumentSubresourceFilter>( + ruleset_handle.get(), std::move(params), activation_state.callback(), + base::OnceClosure()); + + RunUntilIdle(); + activation_state.ExpectReceivedOnce( + ActivationState(ActivationLevel::DISABLED)); +} + +TEST_F(AsyncDocumentSubresourceFilterTest, GetLoadPolicyForSubdocument) { + dealer_handle()->SetRulesetFile(testing::TestRuleset::Open(ruleset())); + auto ruleset_handle = CreateRulesetHandle(); + + AsyncDocumentSubresourceFilter::InitializationParams params( + GURL("http://example.com"), ActivationLevel::ENABLED, false); + + TestActivationStateCallbackReceiver activation_state; + auto filter = base::MakeUnique<AsyncDocumentSubresourceFilter>( + ruleset_handle.get(), std::move(params), activation_state.callback(), + base::OnceClosure()); + + LoadPolicyCallbackReceiver load_policy_1; + LoadPolicyCallbackReceiver load_policy_2; + filter->GetLoadPolicyForSubdocument(GURL("http://example.com/allowed.html"), + load_policy_1.callback()); + filter->GetLoadPolicyForSubdocument( + GURL("http://example.com/disallowed.html"), load_policy_2.callback()); + + RunUntilIdle(); + load_policy_1.ExpectReceivedOnce(LoadPolicy::ALLOW); + load_policy_2.ExpectReceivedOnce(LoadPolicy::DISALLOW); +} + +TEST_F(AsyncDocumentSubresourceFilterTest, FirstDisallowedLoadIsReported) { + dealer_handle()->SetRulesetFile(testing::TestRuleset::Open(ruleset())); + auto ruleset_handle = CreateRulesetHandle(); + + TestCallbackReceiver first_disallowed_load_receiver; + AsyncDocumentSubresourceFilter::InitializationParams params( + GURL("http://example.com"), ActivationLevel::ENABLED, false); + + TestActivationStateCallbackReceiver activation_state; + auto filter = base::MakeUnique<AsyncDocumentSubresourceFilter>( + ruleset_handle.get(), std::move(params), activation_state.callback(), + first_disallowed_load_receiver.closure()); + + LoadPolicyCallbackReceiver load_policy_1; + filter->GetLoadPolicyForSubdocument(GURL("http://example.com/allowed.html"), + load_policy_1.callback()); + RunUntilIdle(); + load_policy_1.ExpectReceivedOnce(LoadPolicy::ALLOW); + EXPECT_EQ(0, first_disallowed_load_receiver.callback_count()); + + LoadPolicyCallbackReceiver load_policy_2; + filter->GetLoadPolicyForSubdocument( + GURL("http://example.com/disallowed.html"), load_policy_2.callback()); + RunUntilIdle(); + load_policy_2.ExpectReceivedOnce(LoadPolicy::DISALLOW); + EXPECT_EQ(0, first_disallowed_load_receiver.callback_count()); + + filter->ReportDisallowedLoad(); + EXPECT_EQ(1, first_disallowed_load_receiver.callback_count()); + RunUntilIdle(); +} + +} // namespace subresource_filter
diff --git a/components/subresource_filter/content/browser/verified_ruleset_dealer.h b/components/subresource_filter/content/browser/verified_ruleset_dealer.h index e3e248a6..b49246b 100644 --- a/components/subresource_filter/content/browser/verified_ruleset_dealer.h +++ b/components/subresource_filter/content/browser/verified_ruleset_dealer.h
@@ -141,6 +141,9 @@ void GetRulesetAsync(base::Callback<void(VerifiedRuleset*)> callback); private: + // This is to allow ADSF to post |ruleset_.get()| pointer to |task_runner_|. + friend class AsyncDocumentSubresourceFilter; + // Note: Raw pointer, |ruleset_| already holds a reference to |task_runner_|. base::SequencedTaskRunner* task_runner_; std::unique_ptr<VerifiedRuleset, base::OnTaskRunnerDeleter> ruleset_;
diff --git a/components/subresource_filter/core/common/indexed_ruleset.cc b/components/subresource_filter/core/common/indexed_ruleset.cc index 75ac717..b5455cc 100644 --- a/components/subresource_filter/core/common/indexed_ruleset.cc +++ b/components/subresource_filter/core/common/indexed_ruleset.cc
@@ -470,10 +470,10 @@ } // namespace +// static bool IndexedRulesetMatcher::Verify(const uint8_t* buffer, size_t size) { - const auto* indexed_ruleset = flat::GetIndexedRuleset(buffer); flatbuffers::Verifier verifier(buffer, size); - return indexed_ruleset->Verify(verifier); + return flat::VerifyIndexedRulesetBuffer(verifier); } IndexedRulesetMatcher::IndexedRulesetMatcher(const uint8_t* buffer, size_t size)
diff --git a/content/browser/frame_host/navigation_entry_impl.cc b/content/browser/frame_host/navigation_entry_impl.cc index 04c07a467..880d0a21 100644 --- a/content/browser/frame_host/navigation_entry_impl.cc +++ b/content/browser/frame_host/navigation_entry_impl.cc
@@ -702,6 +702,8 @@ RequestNavigationParams NavigationEntryImpl::ConstructRequestNavigationParams( const FrameNavigationEntry& frame_entry, + const GURL& original_url, + const std::string& original_method, bool is_history_navigation_in_new_child, const std::map<std::string, bool>& subframe_unique_names, bool has_committed_real_load, @@ -733,8 +735,8 @@ user_gesture = has_user_gesture(); #endif RequestNavigationParams request_params( - GetIsOverridingUserAgent(), redirects, GetCanLoadLocalResources(), - frame_entry.page_state(), GetUniqueID(), + GetIsOverridingUserAgent(), redirects, original_url, original_method, + GetCanLoadLocalResources(), frame_entry.page_state(), GetUniqueID(), is_history_navigation_in_new_child, subframe_unique_names, has_committed_real_load, intended_as_new_entry, pending_offset_to_send, current_offset_to_send, current_length_to_send, IsViewSourceMode(),
diff --git a/content/browser/frame_host/navigation_entry_impl.h b/content/browser/frame_host/navigation_entry_impl.h index 96f7ef8..4f3183b 100644 --- a/content/browser/frame_host/navigation_entry_impl.h +++ b/content/browser/frame_host/navigation_entry_impl.h
@@ -186,6 +186,8 @@ StartNavigationParams ConstructStartNavigationParams() const; RequestNavigationParams ConstructRequestNavigationParams( const FrameNavigationEntry& frame_entry, + const GURL& original_url, + const std::string& original_method, bool is_history_navigation_in_new_child, const std::map<std::string, bool>& subframe_unique_names, bool has_committed_real_load,
diff --git a/content/browser/frame_host/navigation_request.cc b/content/browser/frame_host/navigation_request.cc index cce1817..263a9475 100644 --- a/content/browser/frame_host/navigation_request.cc +++ b/content/browser/frame_host/navigation_request.cc
@@ -206,10 +206,12 @@ // the renderer in the first place as part of OpenURL. bool browser_initiated = !entry.is_renderer_initiated(); + CommonNavigationParams common_params = entry.ConstructCommonNavigationParams( + frame_entry, request_body, dest_url, dest_referrer, navigation_type, + previews_state, navigation_start); + std::unique_ptr<NavigationRequest> navigation_request(new NavigationRequest( - frame_tree_node, entry.ConstructCommonNavigationParams( - frame_entry, request_body, dest_url, dest_referrer, - navigation_type, previews_state, navigation_start), + frame_tree_node, common_params, BeginNavigationParams(entry.extra_headers(), net::LOAD_NORMAL, false, // has_user_gestures false, // skip_service_worker @@ -217,7 +219,8 @@ blink::WebMixedContentContextType::Blockable, initiator), entry.ConstructRequestNavigationParams( - frame_entry, is_history_navigation_in_new_child, + frame_entry, common_params.url, common_params.method, + is_history_navigation_in_new_child, entry.GetSubframeUniqueNames(frame_tree_node), frame_tree_node->has_committed_real_load(), controller->GetPendingEntryIndex() == -1, @@ -254,8 +257,9 @@ // renderer and sent to the browser instead of being measured here. // TODO(clamy): The pending history list offset should be properly set. RequestNavigationParams request_params( - false, // is_overriding_user_agent - std::vector<GURL>(), // redirects + false, // is_overriding_user_agent + std::vector<GURL>(), // redirects + common_params.url, common_params.method, false, // can_load_local_resources PageState(), // page_state 0, // nav_entry_id @@ -432,6 +436,7 @@ request_params_.navigation_timing.fetch_start = base::TimeTicks::Now(); request_params_.redirect_response.push_back(response->head); + request_params_.redirect_infos.push_back(redirect_info); request_params_.redirects.push_back(common_params_.url); common_params_.url = redirect_info.new_url;
diff --git a/content/browser/frame_host/navigator_impl.cc b/content/browser/frame_host/navigator_impl.cc index 19f822f..b9e03c5 100644 --- a/content/browser/frame_host/navigator_impl.cc +++ b/content/browser/frame_host/navigator_impl.cc
@@ -455,7 +455,8 @@ previews_state, navigation_start), entry.ConstructStartNavigationParams(), entry.ConstructRequestNavigationParams( - frame_entry, is_history_navigation_in_new_child, + frame_entry, GURL(), std::string(), + is_history_navigation_in_new_child, entry.GetSubframeUniqueNames(frame_tree_node), frame_tree_node->has_committed_real_load(), controller_->GetPendingEntryIndex() == -1,
diff --git a/content/child/web_url_loader_impl.cc b/content/child/web_url_loader_impl.cc index 7ed0fab..454cbd7d 100644 --- a/content/child/web_url_loader_impl.cc +++ b/content/child/web_url_loader_impl.cc
@@ -710,29 +710,24 @@ stream_override_->response.encoded_data_length - initial_info.encoded_data_length; info = stream_override_->response; + + // Replay the redirects that happened during navigation. + DCHECK_EQ(stream_override_->redirect_responses.size(), + stream_override_->redirect_infos.size()); + for (size_t i = 0; i < stream_override_->redirect_responses.size(); ++i) { + bool result = OnReceivedRedirect(stream_override_->redirect_infos[i], + stream_override_->redirect_responses[i]); + if (!result) { + NOTREACHED(); + return; + } + } } WebURLResponse response; GURL url(request_.url()); PopulateURLResponse(url, info, &response, request_.reportRawHeaders()); - if (stream_override_.get()) { - CHECK(IsBrowserSideNavigationEnabled()); - DCHECK(stream_override_->redirect_responses.size() == - stream_override_->redirects.size()); - for (size_t i = 0; i < stream_override_->redirects.size(); ++i) { - WebURLResponse previous_response; - // TODO(arthursonzogni) Once Devtool is supported by PlzNavigate, the - // |report_raw_header| argument must be checked. - WebURLLoaderImpl::PopulateURLResponse( - stream_override_->redirects[i], - stream_override_->redirect_responses[i], - &previous_response, - request_.reportRawHeaders()); - response.appendRedirectResponse(previous_response); - } - } - bool show_raw_listing = false; if (info.mime_type == "text/vnd.chromium.ftp-dir") { if (url.query_piece() == "raw") { @@ -1191,6 +1186,10 @@ new_request.setHTTPMethod(WebString::fromUTF8(redirect_info.new_method)); if (redirect_info.new_method == old_method) new_request.setHTTPBody(request.httpBody()); + + new_request.setCheckForBrowserSideNavigation( + request.checkForBrowserSideNavigation()); + return new_request; }
diff --git a/content/child/web_url_loader_impl.h b/content/child/web_url_loader_impl.h index c516452..27b4b2f 100644 --- a/content/child/web_url_loader_impl.h +++ b/content/child/web_url_loader_impl.h
@@ -30,6 +30,7 @@ ResourceResponseHead response; std::vector<GURL> redirects; std::vector<ResourceResponseInfo> redirect_responses; + std::vector<net::RedirectInfo> redirect_infos; // The delta between the actual transfer size and the one reported by the // AsyncResourceLoader due to not having the ResourceResponse.
diff --git a/content/common/frame_messages.h b/content/common/frame_messages.h index 35126af..b0528d68 100644 --- a/content/common/frame_messages.h +++ b/content/common/frame_messages.h
@@ -371,6 +371,9 @@ IPC_STRUCT_TRAITS_MEMBER(is_overriding_user_agent) IPC_STRUCT_TRAITS_MEMBER(redirects) IPC_STRUCT_TRAITS_MEMBER(redirect_response) + IPC_STRUCT_TRAITS_MEMBER(redirect_infos) + IPC_STRUCT_TRAITS_MEMBER(original_url) + IPC_STRUCT_TRAITS_MEMBER(original_method) IPC_STRUCT_TRAITS_MEMBER(can_load_local_resources) IPC_STRUCT_TRAITS_MEMBER(page_state) IPC_STRUCT_TRAITS_MEMBER(nav_entry_id)
diff --git a/content/common/navigation_params.cc b/content/common/navigation_params.cc index b232ce3..613918e 100644 --- a/content/common/navigation_params.cc +++ b/content/common/navigation_params.cc
@@ -148,6 +148,8 @@ RequestNavigationParams::RequestNavigationParams( bool is_overriding_user_agent, const std::vector<GURL>& redirects, + const GURL& original_url, + const std::string& original_method, bool can_load_local_resources, const PageState& page_state, int nav_entry_id, @@ -163,6 +165,8 @@ bool has_user_gesture) : is_overriding_user_agent(is_overriding_user_agent), redirects(redirects), + original_url(original_url), + original_method(original_method), can_load_local_resources(can_load_local_resources), page_state(page_state), nav_entry_id(nav_entry_id), @@ -178,8 +182,7 @@ should_create_service_worker(false), service_worker_provider_id(kInvalidServiceWorkerProviderId), appcache_host_id(kAppCacheNoHostId), - has_user_gesture(has_user_gesture) { -} + has_user_gesture(has_user_gesture) {} RequestNavigationParams::RequestNavigationParams( const RequestNavigationParams& other) = default;
diff --git a/content/common/navigation_params.h b/content/common/navigation_params.h index c47da6b8..1051307 100644 --- a/content/common/navigation_params.h +++ b/content/common/navigation_params.h
@@ -22,6 +22,7 @@ #include "content/public/common/referrer.h" #include "content/public/common/request_context_type.h" #include "content/public/common/resource_response.h" +#include "net/url_request/redirect_info.h" #include "third_party/WebKit/public/platform/WebMixedContentContextType.h" #include "ui/base/page_transition_types.h" #include "url/gurl.h" @@ -228,6 +229,8 @@ RequestNavigationParams(); RequestNavigationParams(bool is_overriding_user_agent, const std::vector<GURL>& redirects, + const GURL& original_url, + const std::string& original_method, bool can_load_local_resources, const PageState& page_state, int nav_entry_id, @@ -254,6 +257,15 @@ // The ResourceResponseInfos received during redirects. std::vector<ResourceResponseInfo> redirect_response; + // PlzNavigate + // The RedirectInfos received during redirects. + std::vector<net::RedirectInfo> redirect_infos; + + // PlzNavigate + // The original URL & method for this navigation. + GURL original_url; + std::string original_method; + // Whether or not this url should be allowed to access local file:// // resources. bool can_load_local_resources;
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index 092fac7..6e997a6 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -561,15 +561,28 @@ WebURLRequest CreateURLRequestForNavigation( const CommonNavigationParams& common_params, + const RequestNavigationParams& request_params, std::unique_ptr<StreamOverrideParameters> stream_override, bool is_view_source_mode_enabled, - bool is_same_document_navigation, - int nav_entry_id) { - WebURLRequest request(common_params.url); + bool is_same_document_navigation) { + // PlzNavigate: use the original navigation url to construct the + // WebURLRequest. The WebURLloaderImpl will replay the redirects afterwards + // and will eventually commit the final url. + const GURL navigation_url = IsBrowserSideNavigationEnabled() && + !request_params.original_url.is_empty() + ? request_params.original_url + : common_params.url; + const std::string navigation_method = + IsBrowserSideNavigationEnabled() && + !request_params.original_method.empty() + ? request_params.original_method + : common_params.method; + WebURLRequest request(navigation_url); + request.setHTTPMethod(WebString::fromUTF8(navigation_method)); + if (is_view_source_mode_enabled) request.setCachePolicy(WebCachePolicy::ReturnCacheDataElseLoad); - request.setHTTPMethod(WebString::fromUTF8(common_params.method)); if (common_params.referrer.url.is_valid()) { WebString web_referrer = WebSecurityPolicy::generateReferrerHeader( common_params.referrer.policy, common_params.url, @@ -587,7 +600,8 @@ RequestExtraData* extra_data = new RequestExtraData(); extra_data->set_stream_override(std::move(stream_override)); - extra_data->set_navigation_initiated_by_renderer(nav_entry_id == 0); + extra_data->set_navigation_initiated_by_renderer( + request_params.nav_entry_id == 0); request.setExtraData(extra_data); // Set the ui timestamp for this navigation. Currently the timestamp here is @@ -3347,7 +3361,7 @@ bool content_initiated = !pending_navigation_params_.get(); // Make sure any previous redirect URLs end up in our new data source. - if (pending_navigation_params_.get()) { + if (pending_navigation_params_.get() && !IsBrowserSideNavigationEnabled()) { for (const auto& i : pending_navigation_params_->request_params.redirects) { datasource->appendRedirect(i); @@ -3404,12 +3418,10 @@ navigation_state->request_params().navigation_timing.redirect_end); double fetch_start = ConvertToBlinkTime( navigation_state->request_params().navigation_timing.fetch_start); - std::vector<GURL> redirectChain = - navigation_state->request_params().redirects; - redirectChain.push_back(navigation_state->common_params().url); - datasource->updateNavigation(redirect_start, redirect_end, fetch_start, - redirectChain); + datasource->updateNavigation( + redirect_start, redirect_end, fetch_start, + !navigation_state->request_params().redirects.empty()); // TODO(clamy) We need to provide additional timing values for the // Navigation Timing API to work with browser-side navigations. // UnloadEventStart and UnloadEventEnd are still missing. @@ -5140,6 +5152,7 @@ stream_override->response = response; stream_override->redirects = request_params.redirects; stream_override->redirect_responses = request_params.redirect_response; + stream_override->redirect_infos = request_params.redirect_infos; // If the request was initiated in the context of a user gesture then make // sure that the navigation also executes in the context of a user gesture. @@ -5183,11 +5196,11 @@ // Send the provisional load failure. blink::WebURLError error = CreateWebURLError(common_params.url, has_stale_copy_in_cache, error_code); - WebURLRequest failed_request = CreateURLRequestForNavigation( - common_params, std::unique_ptr<StreamOverrideParameters>(), - frame_->isViewSourceModeEnabled(), - false, // is_same_document_navigation - request_params.nav_entry_id); + WebURLRequest failed_request = + CreateURLRequestForNavigation(common_params, request_params, + std::unique_ptr<StreamOverrideParameters>(), + frame_->isViewSourceModeEnabled(), + false); // is_same_document_navigation if (!ShouldDisplayErrorPageForFailedLoad(error_code, common_params.url)) { // The browser expects this frame to be loading an error page. Inform it @@ -5890,9 +5903,8 @@ FrameMsg_Navigate_Type::IsSameDocument(common_params.navigation_type); WebURLRequest request = CreateURLRequestForNavigation( - common_params, std::move(stream_params), - frame_->isViewSourceModeEnabled(), is_same_document, - request_params.nav_entry_id); + common_params, request_params, std::move(stream_params), + frame_->isViewSourceModeEnabled(), is_same_document); request.setFrameType(IsTopLevelNavigation(frame_) ? blink::WebURLRequest::FrameTypeTopLevel : blink::WebURLRequest::FrameTypeNested);
diff --git a/extensions/browser/api/web_request/web_request_resource_type.cc b/extensions/browser/api/web_request/web_request_resource_type.cc index e92a5b2..c0329c38 100644 --- a/extensions/browser/api/web_request/web_request_resource_type.cc +++ b/extensions/browser/api/web_request/web_request_resource_type.cc
@@ -26,6 +26,7 @@ {"object", WebRequestResourceType::OBJECT}, {"xmlhttprequest", WebRequestResourceType::XHR}, {"ping", WebRequestResourceType::PING}, + {"csp_report", WebRequestResourceType::CSP_REPORT}, {"media", WebRequestResourceType::MEDIA}, {"websocket", WebRequestResourceType::WEB_SOCKET}, {"other", WebRequestResourceType::OTHER}, @@ -73,7 +74,7 @@ case content::RESOURCE_TYPE_SERVICE_WORKER: return WebRequestResourceType::SCRIPT; case content::RESOURCE_TYPE_CSP_REPORT: - return WebRequestResourceType::OTHER; + return WebRequestResourceType::CSP_REPORT; case content::RESOURCE_TYPE_PLUGIN_RESOURCE: return WebRequestResourceType::OBJECT; case content::RESOURCE_TYPE_LAST_TYPE:
diff --git a/extensions/browser/api/web_request/web_request_resource_type.h b/extensions/browser/api/web_request/web_request_resource_type.h index 9cecc2f..af24532b 100644 --- a/extensions/browser/api/web_request/web_request_resource_type.h +++ b/extensions/browser/api/web_request/web_request_resource_type.h
@@ -27,6 +27,7 @@ OBJECT, XHR, PING, + CSP_REPORT, MEDIA, WEB_SOCKET,
diff --git a/extensions/common/api/web_request.json b/extensions/common/api/web_request.json index b676a02..1fe511a 100644 --- a/extensions/common/api/web_request.json +++ b/extensions/common/api/web_request.json
@@ -16,7 +16,7 @@ { "id": "ResourceType", "type": "string", - "enum": ["main_frame", "sub_frame", "stylesheet", "script", "image", "font", "object", "xmlhttprequest", "ping", "media", "websocket", "other"] + "enum": ["main_frame", "sub_frame", "stylesheet", "script", "image", "font", "object", "xmlhttprequest", "ping", "csp_report", "media", "websocket", "other"] }, { "id": "OnBeforeRequestOptions",
diff --git a/headless/lib/browser/headless_browser_impl.h b/headless/lib/browser/headless_browser_impl.h index b108fad8..e622227 100644 --- a/headless/lib/browser/headless_browser_impl.h +++ b/headless/lib/browser/headless_browser_impl.h
@@ -21,9 +21,6 @@ #include "headless/lib/browser/headless_window_tree_host.h" #endif -// Note: unused but needed to make sure this header gets generated. -#include "headless/public/version.h" - namespace headless { class HeadlessBrowserContextImpl;
diff --git a/ios/chrome/app/application_delegate/BUILD.gn b/ios/chrome/app/application_delegate/BUILD.gn index cf22cd0b..0bc6858 100644 --- a/ios/chrome/app/application_delegate/BUILD.gn +++ b/ios/chrome/app/application_delegate/BUILD.gn
@@ -18,6 +18,7 @@ } source_set("unit_tests") { + configs += [ "//build/config/compiler:enable_arc" ] testonly = true sources = [ "app_state_unittest.mm",
diff --git a/ios/chrome/app/application_delegate/app_state_unittest.mm b/ios/chrome/app/application_delegate/app_state_unittest.mm index 1be7e7e..76ae229 100644 --- a/ios/chrome/app/application_delegate/app_state_unittest.mm +++ b/ios/chrome/app/application_delegate/app_state_unittest.mm
@@ -8,7 +8,6 @@ #include "base/ios/block_types.h" #include "base/mac/scoped_block.h" -#import "base/mac/scoped_nsobject.h" #include "base/memory/ptr_util.h" #include "base/synchronization/lock.h" #import "ios/chrome/app/application_delegate/app_navigation.h" @@ -44,6 +43,10 @@ #import "third_party/ocmock/OCMock/OCMock.h" #include "third_party/ocmock/gtest_support.h" +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + #pragma mark - Class definition. namespace { @@ -159,9 +162,9 @@ } void swizzleSafeModeShouldStart(BOOL shouldStart) { - safe_mode_swizzle_block_.reset([^BOOL(id self) { + safe_mode_swizzle_block_ = ^BOOL(id self) { return shouldStart; - } copy]); + }; safe_mode_swizzler_.reset(new ScopedBlockSwizzler( [SafeModeCoordinator class], @selector(shouldStart), safe_mode_swizzle_block_)); @@ -170,9 +173,9 @@ void swizzleMetricsMediatorDisableReporting() { metrics_mediator_called_ = NO; - metrics_mediator_swizzle_block_.reset([^(id self) { + metrics_mediator_swizzle_block_ = ^() { metrics_mediator_called_ = YES; - } copy]); + }; metrics_mediator_swizzler_.reset(new ScopedBlockSwizzler( [MetricsMediator class], @selector(disableReporting), @@ -182,15 +185,14 @@ void swizzleHandleStartupParameters( id<TabOpening> expectedTabOpener, id<BrowserViewInformation> expectedBrowserViewInformation) { - handle_startup_swizzle_block_.reset( + handle_startup_swizzle_block_ = ^(id self, id<TabOpening> tabOpener, id<StartupInformation> startupInformation, id<BrowserViewInformation> browserViewInformation) { ASSERT_EQ(startup_information_mock_, startupInformation); ASSERT_EQ(expectedTabOpener, tabOpener); ASSERT_EQ(expectedBrowserViewInformation, browserViewInformation); - }, - base::scoped_policy::RETAIN); + }; handle_startup_swizzler_.reset(new ScopedBlockSwizzler( [UserActivityHandler class], @@ -242,10 +244,10 @@ AppState* getAppStateWithMock() { if (!app_state_) { - app_state_.reset([[AppState alloc] - initWithBrowserLauncher:browser_launcher_mock_ - startupInformation:startup_information_mock_ - applicationDelegate:main_application_delegate_]); + app_state_ = + [[AppState alloc] initWithBrowserLauncher:browser_launcher_mock_ + startupInformation:startup_information_mock_ + applicationDelegate:main_application_delegate_]; [app_state_ setWindow:window_]; } return app_state_; @@ -253,10 +255,10 @@ AppState* getAppStateWithRealWindow(UIWindow* window) { if (!app_state_) { - app_state_.reset([[AppState alloc] - initWithBrowserLauncher:browser_launcher_mock_ - startupInformation:startup_information_mock_ - applicationDelegate:main_application_delegate_]); + app_state_ = + [[AppState alloc] initWithBrowserLauncher:browser_launcher_mock_ + startupInformation:startup_information_mock_ + applicationDelegate:main_application_delegate_]; [app_state_ setWindow:window]; } return app_state_; @@ -271,15 +273,15 @@ BOOL metricsMediatorHasBeenCalled() { return metrics_mediator_called_; } private: - base::scoped_nsobject<AppState> app_state_; + AppState* app_state_; id browser_launcher_mock_; id startup_information_mock_; id main_application_delegate_; id window_; id browser_view_information_; - base::mac::ScopedBlock<DecisionBlock> safe_mode_swizzle_block_; - base::mac::ScopedBlock<HandleStartupParam> handle_startup_swizzle_block_; - base::mac::ScopedBlock<ProceduralBlock> metrics_mediator_swizzle_block_; + DecisionBlock safe_mode_swizzle_block_; + HandleStartupParam handle_startup_swizzle_block_; + ProceduralBlock metrics_mediator_swizzle_block_; std::unique_ptr<ScopedBlockSwizzler> safe_mode_swizzler_; std::unique_ptr<ScopedBlockSwizzler> handle_startup_swizzler_; std::unique_ptr<ScopedBlockSwizzler> metrics_mediator_swizzler_; @@ -468,14 +470,14 @@ [OCMockObject mockForClass:[MainApplicationDelegate class]]; id window = [OCMockObject mockForClass:[UIWindow class]]; - base::scoped_nsobject<FakeStartupInformation> startupInformation( - [[FakeStartupInformation alloc] init]); + FakeStartupInformation* startupInformation = + [[FakeStartupInformation alloc] init]; [startupInformation setIsColdStart:YES]; - base::scoped_nsobject<AppState> appState([[AppState alloc] - initWithBrowserLauncher:browserLauncher - startupInformation:startupInformation - applicationDelegate:applicationDelegate]); + AppState* appState = + [[AppState alloc] initWithBrowserLauncher:browserLauncher + startupInformation:startupInformation + applicationDelegate:applicationDelegate]; [appState setWindow:window]; ASSERT_TRUE([startupInformation isColdStart]); @@ -521,10 +523,10 @@ [OCMockObject mockForProtocol:@protocol(StartupInformation)]; [[startupInformation expect] stopChromeMain]; - base::scoped_nsobject<AppState> appState([[AppState alloc] - initWithBrowserLauncher:browserLauncher - startupInformation:startupInformation - applicationDelegate:applicationDelegate]); + AppState* appState = + [[AppState alloc] initWithBrowserLauncher:browserLauncher + startupInformation:startupInformation + applicationDelegate:applicationDelegate]; [appState setWindow:window]; id application = [OCMockObject mockForClass:[UIApplication class]]; @@ -579,7 +581,7 @@ // Swizzle Startup Parameters. swizzleHandleStartupParameters(tabOpener, browserViewInformation); - UIWindow* window = [[[UIWindow alloc] init] autorelease]; + UIWindow* window = [[UIWindow alloc] init]; AppState* appState = getAppStateWithOpenNTPAndIncognitoBlock(NO, window); ASSERT_EQ(NSUInteger(1), [window subviews].count); @@ -621,7 +623,7 @@ id tabSwitcher = [OCMockObject mockForProtocol:@protocol(TabSwitching)]; [[[tabSwitcher stub] andReturnValue:@YES] openNewTabFromTabSwitcher]; - UIWindow* window = [[[UIWindow alloc] init] autorelease]; + UIWindow* window = [[UIWindow alloc] init]; AppState* appState = getAppStateWithOpenNTPAndIncognitoBlock(YES, window); ASSERT_EQ(NSUInteger(1), [window subviews].count); @@ -668,7 +670,7 @@ id tabSwitcher = [OCMockObject mockForProtocol:@protocol(TabSwitching)]; [[[tabSwitcher stub] andReturnValue:@NO] openNewTabFromTabSwitcher]; - UIWindow* window = [[[UIWindow alloc] init] autorelease]; + UIWindow* window = [[UIWindow alloc] init]; AppState* appState = getAppStateWithOpenNTPAndIncognitoBlock(YES, window); // incognitoBlocker. @@ -816,9 +818,9 @@ AppState* appState = getAppStateWithMock(); - UIWindow* window = [[[UIWindow alloc] init] autorelease]; + UIWindow* window = [[UIWindow alloc] init]; appState.safeModeCoordinator = - [[[SafeModeCoordinator alloc] initWithWindow:window] autorelease]; + [[SafeModeCoordinator alloc] initWithWindow:window]; ASSERT_TRUE([appState isInSafeMode]); @@ -833,7 +835,7 @@ // Tests that -applicationDidEnterBackground creates an incognito blocker. TEST_F(AppStateTest, applicationDidEnterBackgroundIncognito) { // Setup. - UIWindow* window = [[[UIWindow alloc] init] autorelease]; + UIWindow* window = [[UIWindow alloc] init]; id application = [OCMockObject niceMockForClass:[UIApplication class]]; id memoryHelper = [OCMockObject mockForClass:[MemoryWarningHelper class]]; id browserViewInformation = getBrowserViewInformationMock(); @@ -873,7 +875,7 @@ // never been in a Foreground stage. TEST_F(AppStateTest, applicationDidEnterBackgroundStageBackground) { // Setup. - UIWindow* window = [[[UIWindow alloc] init] autorelease]; + UIWindow* window = [[UIWindow alloc] init]; id application = [OCMockObject mockForClass:[UIApplication class]]; id memoryHelper = [OCMockObject mockForClass:[MemoryWarningHelper class]]; id browserLauncher = getBrowserLauncherMock(); @@ -896,7 +898,7 @@ // blocker if there is no incognito tab. TEST_F(AppStateTest, applicationDidEnterBackgroundNoIncognitoBlocker) { // Setup. - UIWindow* window = [[[UIWindow alloc] init] autorelease]; + UIWindow* window = [[UIWindow alloc] init]; id application = [OCMockObject niceMockForClass:[UIApplication class]]; id memoryHelper = [OCMockObject mockForClass:[MemoryWarningHelper class]]; id browserViewInformation = getBrowserViewInformationMock();
diff --git a/ios/chrome/app/application_delegate/background_activity_unittest.mm b/ios/chrome/app/application_delegate/background_activity_unittest.mm index d9f4788..2c6a5d3 100644 --- a/ios/chrome/app/application_delegate/background_activity_unittest.mm +++ b/ios/chrome/app/application_delegate/background_activity_unittest.mm
@@ -14,6 +14,10 @@ #import "third_party/ocmock/OCMock/OCMock.h" #import "third_party/ocmock/gtest_support.h" +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + // Verifies that -application:performFetchWithCompletionHandler: calls the // browser launcher in background state and uploads the report. TEST(BackgroundActivityTest, performFetchWithCompletionHandler) {
diff --git a/ios/chrome/app/application_delegate/memory_warning_helper_unittest.mm b/ios/chrome/app/application_delegate/memory_warning_helper_unittest.mm index 8052c01..718f19d 100644 --- a/ios/chrome/app/application_delegate/memory_warning_helper_unittest.mm +++ b/ios/chrome/app/application_delegate/memory_warning_helper_unittest.mm
@@ -5,7 +5,6 @@ #import "ios/chrome/app/application_delegate/memory_warning_helper.h" #include "base/mac/bind_objc_block.h" -#import "base/mac/scoped_nsobject.h" #include "base/memory/memory_pressure_listener.h" #include "base/message_loop/message_loop.h" #include "base/run_loop.h" @@ -13,6 +12,10 @@ #import "ios/chrome/browser/metrics/previous_session_info.h" #include "testing/platform_test.h" +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + using previous_session_info_constants:: kDidSeeMemoryWarningShortlyBeforeTerminating; @@ -34,7 +37,7 @@ MemoryWarningHelper* GetMemoryHelper() { if (!memory_helper_) { - memory_helper_.reset([[MemoryWarningHelper alloc] init]); + memory_helper_ = [[MemoryWarningHelper alloc] init]; } return memory_helper_; } @@ -53,7 +56,7 @@ base::RunLoop run_loop_; base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level_; std::unique_ptr<base::MemoryPressureListener> memory_pressure_listener_; - base::scoped_nsobject<MemoryWarningHelper> memory_helper_; + MemoryWarningHelper* memory_helper_; DISALLOW_COPY_AND_ASSIGN(MemoryWarningHelperTest); };
diff --git a/ios/chrome/app/application_delegate/metrics_mediator_unittest.mm b/ios/chrome/app/application_delegate/metrics_mediator_unittest.mm index 67b1ca2..8c03bd4c 100644 --- a/ios/chrome/app/application_delegate/metrics_mediator_unittest.mm +++ b/ios/chrome/app/application_delegate/metrics_mediator_unittest.mm
@@ -8,7 +8,6 @@ #import <Foundation/Foundation.h> #include "base/mac/scoped_block.h" -#include "base/mac/scoped_nsobject.h" #import "breakpad/src/client/ios/BreakpadController.h" #include "components/metrics/metrics_service.h" #import "ios/chrome/app/application_delegate/startup_information.h" @@ -24,6 +23,10 @@ #import "third_party/ocmock/OCMock/OCMock.h" #include "third_party/ocmock/gtest_support.h" +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + #pragma mark - connectionTypeChanged tests. // Mock class for testing MetricsMediator. @@ -93,8 +96,7 @@ // uploading in the breakpad and in the metrics service. TEST(MetricsMediatorTest, connectionTypeChanged) { [[PreviousSessionInfo sharedInstance] setIsFirstSessionAfterUpgrade:NO]; - base::scoped_nsobject<MetricsMediatorMock> mock_metrics_helper( - [[MetricsMediatorMock alloc] init]); + MetricsMediatorMock* mock_metrics_helper = [[MetricsMediatorMock alloc] init]; // Checks all different scenarios. for (int i = 0; i < 8; ++i) { @@ -126,11 +128,11 @@ [OCMockObject mockForProtocol:@protocol(BrowserViewInformation)]; [[[browser_view_information_ stub] andReturn:mainTabModel] mainTabModel]; - swizzle_block_.reset([^(id self, int numTab) { + swizzle_block_ = [^(id self, int numTab) { has_been_called_ = YES; // Tests. EXPECT_EQ(tabCount, numTab); - } copy]); + } copy]; if (coldStart) { uma_histogram_swizzler_.reset(new ScopedBlockSwizzler( [MetricsMediator class], @selector(recordNumTabAtStartup:), @@ -149,7 +151,7 @@ private: id browser_view_information_; __block BOOL has_been_called_; - base::mac::ScopedBlock<logLaunchMetricsBlock> swizzle_block_; + logLaunchMetricsBlock swizzle_block_; std::unique_ptr<ScopedBlockSwizzler> uma_histogram_swizzler_; }; @@ -245,17 +247,16 @@ // count waiting to be processed. TEST_P(MetricsMediatorShutdownTypeTest, ProcessCrashReportsPresentAtStartup) { // Create a MainController. - base::scoped_nsobject<MetricsMediator> metric_helper( - [[MetricsMediator alloc] init]); + MetricsMediator* metric_helper = [[MetricsMediator alloc] init]; // Create a mock for BreakpadController and swizzle // +[BreakpadController sharedInstance] to return the mock instead of the // normal singleton instance. - base::scoped_nsobject<id> mock_breakpad_controller( - [[OCMockObject mockForClass:[BreakpadController class]] retain]); + id mock_breakpad_controller = + [OCMockObject mockForClass:[BreakpadController class]]; id implementation_block = ^BreakpadController*(id self) { - return mock_breakpad_controller.get(); + return mock_breakpad_controller; }; ScopedBlockSwizzler breakpad_controller_shared_instance_swizzler( [BreakpadController class], @selector(sharedInstance), @@ -268,7 +269,7 @@ // Now call the method under test and verify that the Breakpad controller got // called appropriately. [metric_helper processCrashReportsPresentAtStartup]; - EXPECT_OCMOCK_VERIFY(mock_breakpad_controller.get()); + EXPECT_OCMOCK_VERIFY(mock_breakpad_controller); } INSTANTIATE_TEST_CASE_P(/* No InstantiationName */,
diff --git a/ios/chrome/app/application_delegate/url_opener_unittest.mm b/ios/chrome/app/application_delegate/url_opener_unittest.mm index 481213c..b2aee14 100644 --- a/ios/chrome/app/application_delegate/url_opener_unittest.mm +++ b/ios/chrome/app/application_delegate/url_opener_unittest.mm
@@ -6,7 +6,6 @@ #import <Foundation/Foundation.h> -#include "base/mac/scoped_nsobject.h" #include "ios/chrome/app/application_delegate/app_state.h" #include "ios/chrome/app/application_delegate/app_state_testing.h" #include "ios/chrome/app/application_delegate/mock_tab_opener.h" @@ -24,6 +23,10 @@ #import "third_party/ocmock/OCMock/OCMock.h" #include "third_party/ocmock/gtest_support.h" +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + #pragma mark - Tab Switcher Mock // This mocks either a iPad tab switcher controller or a iPhone stack view @@ -112,8 +115,8 @@ class URLOpenerTest : public PlatformTest { protected: MainController* GetMainController() { - if (!main_controller_.get()) { - main_controller_.reset([[MainController alloc] init]); + if (!main_controller_) { + main_controller_ = [[MainController alloc] init]; [main_controller_ setUpAsForegrounded]; id mainTabModel = [OCMockObject mockForClass:[TabModel class]]; [[mainTabModel stub] resetSessionMetrics]; @@ -122,34 +125,34 @@ [[mainTabModel stub] removeObserver:[OCMArg any]]; [[main_controller_ browserViewInformation] setMainTabModel:mainTabModel]; } - return main_controller_.get(); + return main_controller_; } private: - base::scoped_nsobject<MainController> main_controller_; + MainController* main_controller_; }; TEST_F(URLOpenerTest, HandleOpenURLWithNoOpenTab) { // The tab switcher controller should be dismissed with a new tab containing // the external URL. NSURL* url = [NSURL URLWithString:@"chromium://www.google.com"]; - base::scoped_nsobject<ChromeAppStartupParameters> params( + ChromeAppStartupParameters* params = [ChromeAppStartupParameters newChromeAppStartupParametersWithURL:url - fromSourceApplication:nil]); + fromSourceApplication:nil]; - base::scoped_nsobject<id> bvcMock([[URLOpenerMockBVC alloc] init]); + id bvcMock = [[URLOpenerMockBVC alloc] init]; - base::scoped_nsobject<id> tabSwitcherController; - tabSwitcherController.reset([[URLOpenerOCMockComplexTypeHandler alloc] + id tabSwitcherController; + tabSwitcherController = [[URLOpenerOCMockComplexTypeHandler alloc] initWithRepresentedObject:[OCMockObject - mockForProtocol:@protocol(UrlLoader)]]); + mockForProtocol:@protocol(UrlLoader)]]; - base::scoped_nsobject<id> block([(id) ^ (const GURL& url, NSUInteger position, - ui::PageTransition transition) { + id block = [(id) ^ (const GURL& url, NSUInteger position, + ui::PageTransition transition) { EXPECT_EQ(url, [params externalURL]); EXPECT_EQ(NSNotFound, static_cast<NSInteger>(position)); EXPECT_TRUE(PageTransitionCoreTypeIs(transition, ui::PAGE_TRANSITION_LINK)); - } copy]); + } copy]; SEL dismissSelector = @selector(dismissWithNewTabAnimationToModel:withURL:atIndex:transition:); [tabSwitcherController onSelector:dismissSelector callBlockExpectation:block]; @@ -164,11 +167,11 @@ [OCMockObject mockForClass:[MainApplicationDelegate class]]; AppState* appState = - [[[AppState alloc] initWithBrowserLauncher:controller - startupInformation:controller - applicationDelegate:mainApplicationDelegate - window:controller.window - shouldOpenNTP:YES] autorelease]; + [[AppState alloc] initWithBrowserLauncher:controller + startupInformation:controller + applicationDelegate:mainApplicationDelegate + window:controller.window + shouldOpenNTP:YES]; controller.appState = appState; NSDictionary<NSString*, id>* options = nil; @@ -183,21 +186,19 @@ TEST_F(URLOpenerTest, HandleOpenURLWithOpenTabs) { NSURL* url = [NSURL URLWithString:@"chromium://www.google.com"]; - base::scoped_nsobject<URLOpenerMockBVC> bvc_mock( - [[URLOpenerMockBVC alloc] init]); - base::scoped_nsobject<URLOpenerMockBVC> otr_bvc_mock( - [[URLOpenerMockBVC alloc] init]); + URLOpenerMockBVC* bvc_mock = [[URLOpenerMockBVC alloc] init]; + URLOpenerMockBVC* otr_bvc_mock = [[URLOpenerMockBVC alloc] init]; TestChromeBrowserState::Builder main_browser_state_builder; std::unique_ptr<TestChromeBrowserState> chrome_browser_state = main_browser_state_builder.Build(); - bvc_mock.get().browserState = chrome_browser_state.get(); + bvc_mock.browserState = chrome_browser_state.get(); // Setup main controller. MainController* controller = GetMainController(); controller.browserViewInformation.mainBVC = - static_cast<BrowserViewController*>(bvc_mock.get()); + static_cast<BrowserViewController*>(bvc_mock); controller.browserViewInformation.otrBVC = - static_cast<BrowserViewController*>(otr_bvc_mock.get()); + static_cast<BrowserViewController*>(otr_bvc_mock); NSDictionary<NSString*, id>* options = nil; [URLOpener openURL:url @@ -225,7 +226,7 @@ NSArray* applicationStatesToTest = @[ @YES, @NO ]; // Mock of TabOpening, preventing the creation of a new tab. - base::scoped_nsobject<MockTabOpener> tabOpener([[MockTabOpener alloc] init]); + MockTabOpener* tabOpener = [[MockTabOpener alloc] init]; // The keys for this dictionary is the URL to call openURL:. The value // from the key is either YES or NO to indicate if this is a valid URL @@ -281,8 +282,7 @@ ? nil : [NSURL URLWithString:urlString]; BOOL isValid = [[urlsToTest objectForKey:urlString] boolValue]; - base::scoped_nsobject<NSMutableDictionary> options( - [[NSMutableDictionary alloc] init]); + NSMutableDictionary* options = [[NSMutableDictionary alloc] init]; if (source != [NSNull null]) { [options setObject:source forKey:UIApplicationOpenURLOptionsSourceApplicationKey]; @@ -291,10 +291,9 @@ [options setObject:annotation forKey:UIApplicationOpenURLOptionsAnnotationKey]; } - base::scoped_nsobject<ChromeAppStartupParameters> params( - [ChromeAppStartupParameters - newChromeAppStartupParametersWithURL:testUrl - fromSourceApplication:nil]); + ChromeAppStartupParameters* params = [ChromeAppStartupParameters + newChromeAppStartupParametersWithURL:testUrl + fromSourceApplication:nil]; // Action. BOOL result = [URLOpener openURL:testUrl
diff --git a/ios/chrome/app/application_delegate/user_activity_handler_unittest.mm b/ios/chrome/app/application_delegate/user_activity_handler_unittest.mm index d1125e1..6cedf957 100644 --- a/ios/chrome/app/application_delegate/user_activity_handler_unittest.mm +++ b/ios/chrome/app/application_delegate/user_activity_handler_unittest.mm
@@ -10,7 +10,6 @@ #include "base/ios/ios_util.h" #include "base/mac/scoped_block.h" -#include "base/mac/scoped_nsobject.h" #include "base/strings/sys_string_conversions.h" #include "base/test/scoped_command_line.h" #include "components/handoff/handoff_utility.h" @@ -38,13 +37,17 @@ #include "ui/base/page_transition_types.h" #include "url/gurl.h" +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + #pragma mark - Tab Mock // Tab mock for using in UserActivity tests. @interface UserActivityHandlerTabMock : NSObject @property(nonatomic, readonly) GURL url; -@property(nonatomic, readonly) NSString* tabId; +@property(nonatomic, copy, readonly) NSString* tabId; @end @@ -63,7 +66,7 @@ // TabModel mock for using in UserActivity tests. @interface UserActivityHandlerTabModelMock : NSObject<NSFastEnumeration> { @private - base::scoped_nsobject<NSMutableArray> _tabs; + NSMutableArray* _tabs; } - (void)addTab:(Tab*)tab; @@ -76,13 +79,14 @@ - (instancetype)init { if ((self = [super init])) { - _tabs.reset([[NSMutableArray alloc] init]); + _tabs = [[NSMutableArray alloc] init]; } return self; } - (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState*)state - objects:(id*)stackbuf + objects: + (__unsafe_unretained id _Nonnull*)stackbuf count:(NSUInteger)len { return [_tabs countByEnumeratingWithState:state objects:stackbuf count:len]; } @@ -117,9 +121,9 @@ protected: void swizzleHandleStartupParameters() { handle_startup_parameters_has_been_called_ = NO; - swizzle_block_.reset([^(id self) { + swizzle_block_ = [^(id self) { handle_startup_parameters_has_been_called_ = YES; - } copy]); + } copy]; user_activity_handler_swizzler_.reset(new ScopedBlockSwizzler( [UserActivityHandler class], @selector(handleStartupParametersWithTabOpener: @@ -139,10 +143,10 @@ conditionBlock getCompletionHandler() { if (!completion_block_) { block_executed_ = NO; - completion_block_.reset([^(BOOL arg) { + completion_block_ = [^(BOOL arg) { block_executed_ = YES; block_argument_ = arg; - } copy]); + } copy]; } return completion_block_; } @@ -155,8 +159,8 @@ __block BOOL block_executed_; __block BOOL block_argument_; std::unique_ptr<ScopedBlockSwizzler> user_activity_handler_swizzler_; - base::mac::ScopedBlock<startupParameterBlock> swizzle_block_; - base::mac::ScopedBlock<conditionBlock> completion_block_; + startupParameterBlock swizzle_block_; + conditionBlock completion_block_; __block BOOL handle_startup_parameters_has_been_called_; }; @@ -203,8 +207,8 @@ @"thisIsGarbage", @"it.does.not.work", handoffWithSuffix, handoffWithPrefix ]; for (NSString* userActivityType in userActivityTypes) { - base::scoped_nsobject<NSUserActivity> userActivity( - [[NSUserActivity alloc] initWithActivityType:userActivityType]); + NSUserActivity* userActivity = + [[NSUserActivity alloc] initWithActivityType:userActivityType]; [userActivity setWebpageURL:[NSURL URLWithString:@"http://www.google.com"]]; // The test will fail is a method of those objects is called. @@ -228,8 +232,8 @@ // set. TEST(UserActivityHandlerNoFixtureTest, continueUserActivityNoWebpage) { // Setup. - base::scoped_nsobject<NSUserActivity> userActivity([[NSUserActivity alloc] - initWithActivityType:handoff::kChromeHandoffActivityType]); + NSUserActivity* userActivity = [[NSUserActivity alloc] + initWithActivityType:handoff::kChromeHandoffActivityType]; // The test will fail is a method of those objects is called. id tabOpenerMock = [OCMockObject mockForProtocol:@protocol(TabOpening)]; @@ -256,8 +260,8 @@ return; } // Setup. - base::scoped_nsobject<NSUserActivity> userActivity( - [[NSUserActivity alloc] initWithActivityType:CSSearchableItemActionType]); + NSUserActivity* userActivity = + [[NSUserActivity alloc] initWithActivityType:CSSearchableItemActionType]; NSString* invalidAction = [NSString stringWithFormat:@"%@.invalidAction", spotlight::StringFromSpotlightDomain( @@ -290,8 +294,8 @@ // by saving the url to startupParameters. TEST(UserActivityHandlerNoFixtureTest, continueUserActivityBackground) { // Setup. - base::scoped_nsobject<NSUserActivity> userActivity([[NSUserActivity alloc] - initWithActivityType:handoff::kChromeHandoffActivityType]); + NSUserActivity* userActivity = [[NSUserActivity alloc] + initWithActivityType:handoff::kChromeHandoffActivityType]; NSURL* nsurl = [NSURL URLWithString:@"http://www.google.com"]; [userActivity setWebpageURL:nsurl]; @@ -325,20 +329,19 @@ // by opening a new tab. TEST(UserActivityHandlerNoFixtureTest, continueUserActivityForeground) { // Setup. - base::scoped_nsobject<NSUserActivity> userActivity([[NSUserActivity alloc] - initWithActivityType:handoff::kChromeHandoffActivityType]); + NSUserActivity* userActivity = [[NSUserActivity alloc] + initWithActivityType:handoff::kChromeHandoffActivityType]; NSURL* nsurl = [NSURL URLWithString:@"http://www.google.com"]; [userActivity setWebpageURL:nsurl]; - base::scoped_nsobject<MockTabOpener> tabOpener([[MockTabOpener alloc] init]); + MockTabOpener* tabOpener = [[MockTabOpener alloc] init]; id startupInformationMock = [OCMockObject mockForProtocol:@protocol(StartupInformation)]; [[[startupInformationMock stub] andReturnValue:@NO] isPresentingFirstRunUI]; - base::scoped_nsobject<AppStartupParameters> startupParams( - [[AppStartupParameters alloc] - initWithExternalURL:(GURL("http://www.google.com"))]); + AppStartupParameters* startupParams = [[AppStartupParameters alloc] + initWithExternalURL:(GURL("http://www.google.com"))]; [[[startupInformationMock stub] andReturn:startupParams] startupParameters]; // Action. @@ -356,18 +359,18 @@ // Tests that a new tab is created when application is started via Universal // Link. TEST_F(UserActivityHandlerTest, continueUserActivityBrowsingWeb) { - base::scoped_nsobject<NSUserActivity> userActivity([[NSUserActivity alloc] - initWithActivityType:NSUserActivityTypeBrowsingWeb]); + NSUserActivity* userActivity = [[NSUserActivity alloc] + initWithActivityType:NSUserActivityTypeBrowsingWeb]; // This URL is passed to application by iOS but is not used in this part // of application logic. NSURL* nsurl = [NSURL URLWithString:@"http://goo.gl/foo/bar"]; [userActivity setWebpageURL:nsurl]; - base::scoped_nsobject<MockTabOpener> tabOpener([[MockTabOpener alloc] init]); + MockTabOpener* tabOpener = [[MockTabOpener alloc] init]; // Use an object to capture the startup paramters set by UserActivityHandler. - base::scoped_nsobject<FakeStartupInformation> fakeStartupInformation( - [[FakeStartupInformation alloc] init]); + FakeStartupInformation* fakeStartupInformation = + [[FakeStartupInformation alloc] init]; [fakeStartupInformation setIsPresentingFirstRunUI:NO]; BOOL result = @@ -395,8 +398,8 @@ } // Setup. GURL gurlNewTab(kChromeUINewTabURL); - base::scoped_nsobject<FakeStartupInformation> fakeStartupInformation( - [[FakeStartupInformation alloc] init]); + FakeStartupInformation* fakeStartupInformation = + [[FakeStartupInformation alloc] init]; NSArray* parametersToTest = @[ @[ @@ -422,8 +425,8 @@ switches::kEnableSpotlightActions); for (id parameters in parametersToTest) { - base::scoped_nsobject<NSUserActivity> userActivity([[NSUserActivity alloc] - initWithActivityType:CSSearchableItemActionType]); + NSUserActivity* userActivity = [[NSUserActivity alloc] + initWithActivityType:CSSearchableItemActionType]; NSString* action = [NSString stringWithFormat:@"%@.%@", spotlight::StringFromSpotlightDomain( spotlight::DOMAIN_ACTIONS), @@ -458,8 +461,8 @@ // Setup. GURL gurl("http://www.google.com"); - base::scoped_nsobject<AppStartupParameters> startupParams( - [[AppStartupParameters alloc] initWithExternalURL:gurl]); + AppStartupParameters* startupParams = + [[AppStartupParameters alloc] initWithExternalURL:gurl]; [startupParams setLaunchInIncognito:YES]; id startupInformationMock = @@ -468,7 +471,7 @@ [[[startupInformationMock stub] andReturn:startupParams] startupParameters]; [[startupInformationMock expect] setStartupParameters:nil]; - base::scoped_nsobject<MockTabOpener> tabOpener([[MockTabOpener alloc] init]); + MockTabOpener* tabOpener = [[MockTabOpener alloc] init]; // The test will fail is a method of this object is called. id browserViewMock = @@ -493,18 +496,18 @@ GURL gurl("chromium://u2f-callback?isU2F=1&tabID=B05B1860"); NSString* tabID = [U2FController tabIDFromResponseURL:gurl]; - base::scoped_nsobject<AppStartupParameters> startupParams( - [[AppStartupParameters alloc] initWithExternalURL:gurl]); + AppStartupParameters* startupParams = + [[AppStartupParameters alloc] initWithExternalURL:gurl]; [startupParams setLaunchInIncognito:YES]; - base::scoped_nsobject<UserActivityHandlerTabMock> tabMock( - [[UserActivityHandlerTabMock alloc] init]); + UserActivityHandlerTabMock* tabMock = + [[UserActivityHandlerTabMock alloc] init]; id tabOCMock = [OCMockObject partialMockForObject:tabMock]; [[[tabOCMock stub] andReturn:tabID] tabId]; - base::scoped_nsobject<UserActivityHandlerTabModelMock> tabModel( - [[UserActivityHandlerTabModelMock alloc] init]); - [tabModel addTab:(Tab*)tabMock.get()]; + UserActivityHandlerTabModelMock* tabModel = + [[UserActivityHandlerTabModelMock alloc] init]; + [tabModel addTab:(Tab*)tabMock]; id startupInformationMock = [OCMockObject mockForProtocol:@protocol(StartupInformation)]; @@ -514,12 +517,12 @@ id browserViewInformationMock = [OCMockObject mockForProtocol:@protocol(BrowserViewInformation)]; - [[[browserViewInformationMock stub] andReturn:(TabModel*)tabModel.get()] + [[[browserViewInformationMock stub] andReturn:(TabModel*)tabModel] mainTabModel]; - [[[browserViewInformationMock stub] andReturn:(TabModel*)tabModel.get()] + [[[browserViewInformationMock stub] andReturn:(TabModel*)tabModel] otrTabModel]; - base::scoped_nsobject<MockTabOpener> tabOpener([[MockTabOpener alloc] init]); + MockTabOpener* tabOpener = [[MockTabOpener alloc] init]; // Action. [UserActivityHandler @@ -538,8 +541,8 @@ // Setup. GURL gurlNewTab("chrome://newtab/"); - base::scoped_nsobject<FakeStartupInformation> fakeStartupInformation( - [[FakeStartupInformation alloc] init]); + FakeStartupInformation* fakeStartupInformation = + [[FakeStartupInformation alloc] init]; [fakeStartupInformation setIsPresentingFirstRunUI:NO]; NSArray* parametersToTest = @[ @@ -551,9 +554,9 @@ swizzleHandleStartupParameters(); for (id parameters in parametersToTest) { - base::scoped_nsobject<UIApplicationShortcutItem> shortcut( + UIApplicationShortcutItem* shortcut = [[UIApplicationShortcutItem alloc] initWithType:parameters[0] - localizedTitle:parameters[0]]); + localizedTitle:parameters[0]]; resetHandleStartupParametersHasBeenCalled(); @@ -593,9 +596,9 @@ [OCMockObject mockForProtocol:@protocol(StartupInformation)]; [[[startupInformationMock stub] andReturnValue:@YES] isPresentingFirstRunUI]; - base::scoped_nsobject<UIApplicationShortcutItem> shortcut( + UIApplicationShortcutItem* shortcut = [[UIApplicationShortcutItem alloc] initWithType:@"OpenNewTab" - localizedTitle:@""]); + localizedTitle:@""]; swizzleHandleStartupParameters();
diff --git a/ios/chrome/app/spotlight/BUILD.gn b/ios/chrome/app/spotlight/BUILD.gn index b872afa..5a49178 100644 --- a/ios/chrome/app/spotlight/BUILD.gn +++ b/ios/chrome/app/spotlight/BUILD.gn
@@ -3,6 +3,7 @@ # found in the LICENSE file. source_set("spotlight") { + configs += [ "//build/config/compiler:enable_arc" ] sources = [ "actions_spotlight_manager.h", "actions_spotlight_manager.mm",
diff --git a/ios/chrome/app/spotlight/actions_spotlight_manager.mm b/ios/chrome/app/spotlight/actions_spotlight_manager.mm index 5702538..1d453c5 100644 --- a/ios/chrome/app/spotlight/actions_spotlight_manager.mm +++ b/ios/chrome/app/spotlight/actions_spotlight_manager.mm
@@ -6,7 +6,6 @@ #import <CoreSpotlight/CoreSpotlight.h> -#include "base/ios/weak_nsobject.h" #include "base/mac/foundation_util.h" #include "base/metrics/histogram_macros.h" #include "base/strings/sys_string_conversions.h" @@ -18,6 +17,10 @@ #include "ui/base/l10n/l10n_util.h" #include "url/gurl.h" +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + namespace { NSString* SpotlightActionFromString(NSString* query) { @@ -108,20 +111,19 @@ @implementation ActionsSpotlightManager + (ActionsSpotlightManager*)actionsSpotlightManager { - return [[[ActionsSpotlightManager alloc] + return [[ActionsSpotlightManager alloc] initWithLargeIconService:nil - domain:spotlight::DOMAIN_ACTIONS] autorelease]; + domain:spotlight::DOMAIN_ACTIONS]; } #pragma mark public methods - (void)indexActions { - base::WeakNSObject<ActionsSpotlightManager> weakSelf(self); + __weak ActionsSpotlightManager* weakSelf = self; dispatch_after( dispatch_time(DISPATCH_TIME_NOW, static_cast<int64_t>(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ - base::scoped_nsobject<ActionsSpotlightManager> strongSelf( - [weakSelf retain]); + ActionsSpotlightManager* strongSelf = weakSelf; [strongSelf clearAndAddSpotlightActions]; }); } @@ -133,13 +135,12 @@ if (!experimental_flags::IsSpotlightActionsEnabled()) { return; } - base::WeakNSObject<ActionsSpotlightManager> weakSelf(self); + __weak ActionsSpotlightManager* weakSelf = self; dispatch_after( dispatch_time(DISPATCH_TIME_NOW, static_cast<int64_t>(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ - base::scoped_nsobject<ActionsSpotlightManager> strongSelf( - [weakSelf retain]); + ActionsSpotlightManager* strongSelf = weakSelf; if (!strongSelf) { return; @@ -181,10 +182,10 @@ } - (CSSearchableItem*)getItemForAction:(NSString*)action title:(NSString*)title { - base::scoped_nsobject<CSSearchableItemAttributeSet> attributeSet( + CSSearchableItemAttributeSet* attributeSet = [[CSSearchableItemAttributeSet alloc] initWithItemContentType:spotlight::StringFromSpotlightDomain( - spotlight::DOMAIN_ACTIONS)]); + spotlight::DOMAIN_ACTIONS)]; [attributeSet setTitle:title]; [attributeSet setDisplayName:title];
diff --git a/ios/chrome/app/spotlight/base_spotlight_manager.mm b/ios/chrome/app/spotlight/base_spotlight_manager.mm index 4d497c1..6fb7759 100644 --- a/ios/chrome/app/spotlight/base_spotlight_manager.mm +++ b/ios/chrome/app/spotlight/base_spotlight_manager.mm
@@ -7,7 +7,6 @@ #import <CommonCrypto/CommonCrypto.h> #import <MobileCoreServices/MobileCoreServices.h> -#include "base/ios/weak_nsobject.h" #include "base/mac/bind_objc_block.h" #include "base/strings/sys_string_conversions.h" #include "base/task/cancelable_task_tracker.h" @@ -23,6 +22,10 @@ #include "skia/ext/skia_utils_ios.h" #include "ui/base/l10n/l10n_util.h" +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + namespace { // Minimum size of the icon to be used in Spotlight. const NSInteger kMinIconSize = 32; @@ -48,7 +51,7 @@ base::CancelableTaskTracker _largeIconTaskTracker; // Dictionary to track the tasks querying the large icons. - base::scoped_nsobject<NSMutableDictionary> _pendingTasks; + NSMutableDictionary* _pendingTasks; } // Compute a hash consisting of the first 8 bytes of the MD5 hash of a string @@ -75,7 +78,7 @@ if (self) { _spotlightDomain = domain; _largeIconService = largeIconService; - _pendingTasks.reset([[NSMutableDictionary alloc] init]); + _pendingTasks = [[NSMutableDictionary alloc] init]; } return self; } @@ -117,21 +120,20 @@ - (CSSearchableItem*)spotlightItemWithItemID:(NSString*)itemID attributeSet:(CSSearchableItemAttributeSet*) attributeSet { - CSCustomAttributeKey* key = [[[CSCustomAttributeKey alloc] + CSCustomAttributeKey* key = [[CSCustomAttributeKey alloc] initWithKeyName:spotlight::GetSpotlightCustomAttributeItemID() searchable:YES searchableByDefault:YES unique:YES - multiValued:NO] autorelease]; + multiValued:NO]; [attributeSet setValue:itemID forCustomKey:key]; attributeSet.keywords = [self keywordsForSpotlightItems]; NSString* domainID = spotlight::StringFromSpotlightDomain(_spotlightDomain); - return [[[CSSearchableItem alloc] initWithUniqueIdentifier:itemID - domainIdentifier:domainID - attributeSet:attributeSet] - autorelease]; + return [[CSSearchableItem alloc] initWithUniqueIdentifier:itemID + domainIdentifier:domainID + attributeSet:attributeSet]; } - (NSArray*)spotlightItemsWithURL:(const GURL&)indexedURL @@ -143,9 +145,9 @@ ? indexedURL.GetOrigin().spec() : indexedURL.spec(); - base::scoped_nsobject<CSSearchableItemAttributeSet> attributeSet( + CSSearchableItemAttributeSet* attributeSet = [[CSSearchableItemAttributeSet alloc] - initWithItemContentType:(NSString*)kUTTypeURL]); + initWithItemContentType:(NSString*)kUTTypeURL]; [attributeSet setTitle:defaultTitle]; [attributeSet setDisplayName:defaultTitle]; [attributeSet setURL:nsURL]; @@ -174,11 +176,10 @@ font = [font fontWithSize:(kFallbackIconSize / 2)]; CGRect textRect = CGRectMake(0, (kFallbackIconSize - [font lineHeight]) / 2, kFallbackIconSize, [font lineHeight]); - base::scoped_nsobject<NSMutableParagraphStyle> paragraphStyle( - [[NSMutableParagraphStyle alloc] init]); + NSMutableParagraphStyle* paragraphStyle = + [[NSMutableParagraphStyle alloc] init]; [paragraphStyle setAlignment:NSTextAlignmentCenter]; - base::scoped_nsobject<NSMutableDictionary> attributes( - [[NSMutableDictionary alloc] init]); + NSMutableDictionary* attributes = [[NSMutableDictionary alloc] init]; [attributes setValue:font forKey:NSFontAttributeName]; [attributes setValue:textColor forKey:NSForegroundColorAttributeName]; [attributes setValue:paragraphStyle forKey:NSParagraphStyleAttributeName]; @@ -196,15 +197,15 @@ return; } - base::WeakNSObject<BaseSpotlightManager> weakSelf(self); + __weak BaseSpotlightManager* weakSelf = self; GURL URL = URLToRefresh; void (^faviconBlock)(const favicon_base::LargeIconResult&) = ^( const favicon_base::LargeIconResult& result) { - base::scoped_nsobject<BaseSpotlightManager> strongSelf([weakSelf retain]); + BaseSpotlightManager* strongSelf = weakSelf; if (!strongSelf) { return; } - [strongSelf.get()->_pendingTasks removeObjectForKey:NSURL]; + [strongSelf->_pendingTasks removeObjectForKey:NSURL]; UIImage* favicon; if (result.bitmap.is_valid()) { scoped_refptr<base::RefCountedMemory> data = @@ -237,7 +238,7 @@ _largeIconService->GetLargeIconOrFallbackStyle( URL, kMinIconSize * [UIScreen mainScreen].scale, kIconSize * [UIScreen mainScreen].scale, - base::BindBlock(faviconBlock), &_largeIconTaskTracker); + base::BindBlockArc(faviconBlock), &_largeIconTaskTracker); [_pendingTasks setObject:[NSNumber numberWithLongLong:taskID] forKey:NSURL]; }
diff --git a/ios/chrome/app/spotlight/bookmarks_spotlight_manager.h b/ios/chrome/app/spotlight/bookmarks_spotlight_manager.h index 31534ed..30e46e2 100644 --- a/ios/chrome/app/spotlight/bookmarks_spotlight_manager.h +++ b/ios/chrome/app/spotlight/bookmarks_spotlight_manager.h
@@ -29,7 +29,7 @@ @interface BookmarksSpotlightManager : BaseSpotlightManager // The delegate notified when a bookmark is updated. -@property(nonatomic, assign) id<BookmarkUpdatedDelegate> delegate; +@property(nonatomic, weak) id<BookmarkUpdatedDelegate> delegate; + (BookmarksSpotlightManager*)bookmarksSpotlightManagerWithBrowserState: (ios::ChromeBrowserState*)browserState;
diff --git a/ios/chrome/app/spotlight/bookmarks_spotlight_manager.mm b/ios/chrome/app/spotlight/bookmarks_spotlight_manager.mm index 7cee4eb9..c096c432 100644 --- a/ios/chrome/app/spotlight/bookmarks_spotlight_manager.mm +++ b/ios/chrome/app/spotlight/bookmarks_spotlight_manager.mm
@@ -8,7 +8,6 @@ #import <CoreSpotlight/CoreSpotlight.h> -#include "base/ios/weak_nsobject.h" #include "base/metrics/histogram_macros.h" #include "base/strings/sys_string_conversions.h" #include "base/version.h" @@ -17,6 +16,10 @@ #include "ios/chrome/browser/bookmarks/bookmark_model_factory.h" #include "ios/chrome/browser/favicon/ios_chrome_large_icon_service_factory.h" +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + namespace { // Limit the size of the initial indexing. This will not limit the size of the // index as new bookmarks can be added afterwards. @@ -31,7 +34,7 @@ // Called from the BrowserBookmarkModelBridge from C++ -> ObjC. @interface BookmarksSpotlightManager () { - base::WeakNSProtocol<id<BookmarkUpdatedDelegate>> _delegate; + __weak id<BookmarkUpdatedDelegate> _delegate; // Bridge to register for bookmark changes. std::unique_ptr<SpotlightBookmarkModelBridge> _bookmarkModelBridge; @@ -141,18 +144,18 @@ }; private: - __unsafe_unretained BookmarksSpotlightManager* owner_; // Weak. + __weak BookmarksSpotlightManager* owner_; }; @implementation BookmarksSpotlightManager + (BookmarksSpotlightManager*)bookmarksSpotlightManagerWithBrowserState: (ios::ChromeBrowserState*)browserState { - return [[[BookmarksSpotlightManager alloc] + return [[BookmarksSpotlightManager alloc] initWithLargeIconService:IOSChromeLargeIconServiceFactory:: GetForBrowserState(browserState) bookmarkModel:ios::BookmarkModelFactory::GetForBrowserState( - browserState)] autorelease]; + browserState)]; } - (instancetype) @@ -170,7 +173,6 @@ - (void)dealloc { [self detachBookmarkModel]; - [super dealloc]; } - (void)detachBookmarkModel { @@ -186,7 +188,7 @@ } - (void)setDelegate:(id<BookmarkUpdatedDelegate>)delegate { - _delegate.reset(delegate); + _delegate = delegate; } - (void)getParentKeywordsForNode:(const bookmarks::BookmarkNode*)node @@ -205,7 +207,7 @@ GURL url(node->url()); NSString* title = base::SysUTF16ToNSString(node->GetTitle()); NSString* spotlightID = [self spotlightIDForURL:url title:title]; - base::WeakNSObject<BookmarksSpotlightManager> weakself(self); + __weak BookmarksSpotlightManager* weakself = self; BlockWithError completion = ^(NSError* error) { dispatch_async(dispatch_get_main_queue(), ^{ [weakself refreshItemsWithURL:url title:nil]; @@ -284,8 +286,7 @@ - (NSArray*)spotlightItemsWithURL:(const GURL&)URL favicon:(UIImage*)favicon defaultTitle:(NSString*)defaultTitle { - base::scoped_nsobject<NSMutableDictionary> spotlightItems( - [[NSMutableDictionary alloc] init]); + NSMutableDictionary* spotlightItems = [[NSMutableDictionary alloc] init]; std::vector<const bookmarks::BookmarkNode*> nodes; _bookmarkModel->GetNodesByURL(URL, &nodes); for (auto node : nodes) { @@ -297,9 +298,8 @@ favicon:favicon defaultTitle:nodeTitle] objectAtIndex:0]; } - base::scoped_nsobject<NSMutableArray> nodeKeywords( - [[NSMutableArray alloc] init]); - [self getParentKeywordsForNode:node inArray:nodeKeywords.get()]; + NSMutableArray* nodeKeywords = [[NSMutableArray alloc] init]; + [self getParentKeywordsForNode:node inArray:nodeKeywords]; [self addKeywords:nodeKeywords toSearchableItem:item]; [spotlightItems setObject:item forKey:spotlightID]; } @@ -308,20 +308,18 @@ - (void)clearAndReindexModel { [self cancelAllLargeIconPendingTasks]; - base::WeakNSObject<BookmarksSpotlightManager> weakself(self); + __weak BookmarksSpotlightManager* weakself = self; BlockWithError completion = ^(NSError* error) { if (!error) { dispatch_async(dispatch_get_main_queue(), ^{ - base::scoped_nsobject<BookmarksSpotlightManager> strongSelf( - [weakself retain]); + BookmarksSpotlightManager* strongSelf = weakself; if (!strongSelf) return; NSDate* startOfReindexing = [NSDate date]; - strongSelf.get()->_nodesIndexed = 0; - [strongSelf - refreshNodeInIndex:strongSelf.get()->_bookmarkModel->root_node() - initial:YES]; + strongSelf->_nodesIndexed = 0; + [strongSelf refreshNodeInIndex:strongSelf->_bookmarkModel->root_node() + initial:YES]; NSDate* endOfReindexing = [NSDate date]; NSTimeInterval indexingDuration = [endOfReindexing timeIntervalSinceDate:startOfReindexing];
diff --git a/ios/chrome/app/spotlight/spotlight_manager.mm b/ios/chrome/app/spotlight/spotlight_manager.mm index b4d05739..3baf66b 100644 --- a/ios/chrome/app/spotlight/spotlight_manager.mm +++ b/ios/chrome/app/spotlight/spotlight_manager.mm
@@ -5,17 +5,20 @@ #import "ios/chrome/app/spotlight/spotlight_manager.h" #include "base/logging.h" -#include "base/mac/scoped_nsobject.h" #include "ios/chrome/app/spotlight/actions_spotlight_manager.h" #include "ios/chrome/app/spotlight/bookmarks_spotlight_manager.h" #include "ios/chrome/app/spotlight/topsites_spotlight_manager.h" #include "ios/chrome/browser/experimental_flags.h" +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + // Called from the BrowserBookmarkModelBridge from C++ -> ObjC. @interface SpotlightManager ()<BookmarkUpdatedDelegate> { - base::scoped_nsobject<BookmarksSpotlightManager> _bookmarkManager; - base::scoped_nsobject<TopSitesSpotlightManager> _topSitesManager; - base::scoped_nsobject<ActionsSpotlightManager> _actionsManager; + BookmarksSpotlightManager* _bookmarkManager; + TopSitesSpotlightManager* _topSitesManager; + ActionsSpotlightManager* _actionsManager; } - (instancetype)initWithBrowserState:(ios::ChromeBrowserState*)browserState @@ -29,8 +32,7 @@ + (SpotlightManager*)spotlightManagerWithBrowserState: (ios::ChromeBrowserState*)browserState { if (spotlight::IsSpotlightAvailable()) { - return [[[SpotlightManager alloc] initWithBrowserState:browserState] - autorelease]; + return [[SpotlightManager alloc] initWithBrowserState:browserState]; } return nil; } @@ -39,13 +41,12 @@ DCHECK(spotlight::IsSpotlightAvailable()); self = [super init]; if (self) { - _topSitesManager.reset([[TopSitesSpotlightManager - topSitesSpotlightManagerWithBrowserState:browserState] retain]); - _bookmarkManager.reset([[BookmarksSpotlightManager - bookmarksSpotlightManagerWithBrowserState:browserState] retain]); + _topSitesManager = [TopSitesSpotlightManager + topSitesSpotlightManagerWithBrowserState:browserState]; + _bookmarkManager = [BookmarksSpotlightManager + bookmarksSpotlightManagerWithBrowserState:browserState]; [_bookmarkManager setDelegate:self]; - _actionsManager.reset( - [[ActionsSpotlightManager actionsSpotlightManager] retain]); + _actionsManager = [ActionsSpotlightManager actionsSpotlightManager]; } return self; } @@ -55,9 +56,6 @@ return nil; } -- (void)dealloc { - [super dealloc]; -} - (void)resyncIndex { [_bookmarkManager reindexBookmarksIfNeeded];
diff --git a/ios/chrome/app/spotlight/spotlight_util.mm b/ios/chrome/app/spotlight/spotlight_util.mm index fd33c146..6bd9e55 100644 --- a/ios/chrome/app/spotlight/spotlight_util.mm +++ b/ios/chrome/app/spotlight/spotlight_util.mm
@@ -12,6 +12,10 @@ #include "ios/public/provider/chrome/browser/spotlight/spotlight_provider.h" #include "url/gurl.h" +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + namespace { // This enum is used for Histogram. Items should not be removed or reordered and // this enum should be kept synced with histograms.xml.
diff --git a/ios/chrome/app/spotlight/topsites_spotlight_manager.mm b/ios/chrome/app/spotlight/topsites_spotlight_manager.mm index 33bb2315..58b45fe 100644 --- a/ios/chrome/app/spotlight/topsites_spotlight_manager.mm +++ b/ios/chrome/app/spotlight/topsites_spotlight_manager.mm
@@ -6,7 +6,6 @@ #include <memory> -#include "base/ios/weak_nsobject.h" #include "base/memory/ref_counted.h" #include "base/strings/sys_string_conversions.h" #include "components/bookmarks/browser/bookmark_model.h" @@ -23,6 +22,10 @@ #include "ios/chrome/browser/sync/sync_observer_bridge.h" #include "ios/chrome/browser/ui/ntp/google_landing_controller.h" +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + class SpotlightTopSitesBridge; class SpotlightTopSitesCallbackBridge; class SpotlightSuggestionsBridge; @@ -97,7 +100,7 @@ } private: - __unsafe_unretained TopSitesSpotlightManager* owner_; // weak, owns us + __weak TopSitesSpotlightManager* owner_; }; class SpotlightTopSitesBridge : public history::TopSitesObserver { @@ -119,7 +122,7 @@ } private: - __unsafe_unretained TopSitesSpotlightManager* owner_; // weak + __weak TopSitesSpotlightManager* owner_; }; class SpotlightSuggestionsBridge @@ -136,7 +139,7 @@ } private: - __unsafe_unretained TopSitesSpotlightManager* owner_; // weak, owns us + __weak TopSitesSpotlightManager* owner_; }; @implementation TopSitesSpotlightManager @@ -144,7 +147,7 @@ + (TopSitesSpotlightManager*)topSitesSpotlightManagerWithBrowserState: (ios::ChromeBrowserState*)browserState { - return [[[TopSitesSpotlightManager alloc] + return [[TopSitesSpotlightManager alloc] initWithLargeIconService:IOSChromeLargeIconServiceFactory:: GetForBrowserState(browserState) topSites:ios::TopSitesFactory::GetForBrowserState( @@ -154,8 +157,7 @@ profileSyncService:IOSChromeProfileSyncServiceFactory:: GetForBrowserState(browserState) suggestionsService:suggestions::SuggestionsServiceFactory:: - GetForBrowserState(browserState)] - autorelease]; + GetForBrowserState(browserState)]; } - (instancetype) @@ -186,7 +188,7 @@ } - (void)updateAllTopSitesSpotlightItems { - base::WeakNSObject<TopSitesSpotlightManager> weakSelf(self); + __weak TopSitesSpotlightManager* weakSelf = self; [self clearAllSpotlightItems:^(NSError* error) { dispatch_async(dispatch_get_main_queue(), ^{ [weakSelf addAllTopSitesSpotlightItems]; @@ -269,12 +271,16 @@ return; } _isReindexPending = true; - base::WeakNSObject<TopSitesSpotlightManager> weakSelf(self); + __weak TopSitesSpotlightManager* weakSelf = self; dispatch_after( dispatch_time(DISPATCH_TIME_NOW, static_cast<int64_t>(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ - [weakSelf updateAllTopSitesSpotlightItems]; - weakSelf.get()->_isReindexPending = false; + TopSitesSpotlightManager* strongSelf = weakSelf; + if (!strongSelf) { + return; + } + [strongSelf updateAllTopSitesSpotlightItems]; + strongSelf->_isReindexPending = false; }); }
diff --git a/ios/chrome/browser/reading_list/reading_list_distiller_page.mm b/ios/chrome/browser/reading_list/reading_list_distiller_page.mm index b456e90..e774a3c2 100644 --- a/ios/chrome/browser/reading_list/reading_list_distiller_page.mm +++ b/ios/chrome/browser/reading_list/reading_list_distiller_page.mm
@@ -72,6 +72,20 @@ FetchFavicon(url); DistillerPageIOS::DistillPageImpl(url, script); + + // WKWebView sets the document.hidden property to true and the + // document.visibilityState to prerender if the page is not added to a view + // hierarchy. Some pages may not render their content in these conditions. + // Add the view and move it out of the screen far in the top left corner of + // the coordinate space. + CGRect frame = [[[UIApplication sharedApplication] keyWindow] frame]; + frame.origin.x = -5 * std::max(frame.size.width, frame.size.height); + frame.origin.y = frame.origin.x; + DCHECK(![CurrentWebState()->GetView() superview]); + [CurrentWebState()->GetView() setFrame:frame]; + [[[UIApplication sharedApplication] keyWindow] + insertSubview:CurrentWebState()->GetView() + atIndex:0]; } void ReadingListDistillerPage::FetchFavicon(const GURL& page_url) { @@ -88,6 +102,7 @@ const base::Value* value) { std::unique_ptr<web::WebState> old_web_state = DetachWebState(); if (old_web_state) { + [old_web_state->GetView() removeFromSuperview]; web_state_dispatcher_->ReturnWebState(std::move(old_web_state)); } DistillerPageIOS::OnDistillationDone(page_url, value);
diff --git a/ios/chrome/browser/reading_list/reading_list_download_service.cc b/ios/chrome/browser/reading_list/reading_list_download_service.cc index 7b9c4f5..e44d1a7d 100644 --- a/ios/chrome/browser/reading_list/reading_list_download_service.cc +++ b/ios/chrome/browser/reading_list/reading_list_download_service.cc
@@ -235,43 +235,46 @@ const base::FilePath& distilled_path, const std::string& title) { DCHECK(reading_list_model_->loaded()); - if ((success == URLDownloader::DOWNLOAD_SUCCESS || - success == URLDownloader::DOWNLOAD_EXISTS) && - !distilled_path.empty()) { - reading_list_model_->SetEntryDistilledInfo(url, distilled_path, - distilled_url); + URLDownloader::SuccessState real_success_value = success; + if (distilled_path.empty()) { + real_success_value = URLDownloader::ERROR; + } + switch (real_success_value) { + case URLDownloader::DOWNLOAD_SUCCESS: + case URLDownloader::DOWNLOAD_EXISTS: { + reading_list_model_->SetEntryDistilledInfo(url, distilled_path, + distilled_url); - std::string trimmed_title = base::CollapseWhitespaceASCII(title, false); - if (!trimmed_title.empty()) - reading_list_model_->SetEntryTitle(url, trimmed_title); + std::string trimmed_title = base::CollapseWhitespaceASCII(title, false); + if (!trimmed_title.empty()) + reading_list_model_->SetEntryTitle(url, trimmed_title); - const ReadingListEntry* entry = reading_list_model_->GetEntryByURL(url); - if (entry) - UMA_HISTOGRAM_COUNTS_100("ReadingList.Download.Failures", - entry->FailedDownloadCounter()); - UMA_HISTOGRAM_ENUMERATION("ReadingList.Download.Status", SUCCESS, - STATUS_MAX); - - } else if (success == URLDownloader::ERROR_RETRY) { - reading_list_model_->SetEntryDistilledState(url, - ReadingListEntry::WILL_RETRY); - ScheduleDownloadEntry(url); - - const ReadingListEntry* entry = reading_list_model_->GetEntryByURL(url); - if (entry) { - if (entry->FailedDownloadCounter() < kNumberOfFailsBeforeStop) { + const ReadingListEntry* entry = reading_list_model_->GetEntryByURL(url); + if (entry) + UMA_HISTOGRAM_COUNTS_100("ReadingList.Download.Failures", + entry->FailedDownloadCounter()); + UMA_HISTOGRAM_ENUMERATION("ReadingList.Download.Status", SUCCESS, + STATUS_MAX); + break; + } + case URLDownloader::ERROR: { + const ReadingListEntry* entry = reading_list_model_->GetEntryByURL(url); + // Add this failure to the total failure count. + if (entry && + entry->FailedDownloadCounter() + 1 < kNumberOfFailsBeforeStop) { + reading_list_model_->SetEntryDistilledState( + url, ReadingListEntry::WILL_RETRY); + ScheduleDownloadEntry(url); UMA_HISTOGRAM_ENUMERATION("ReadingList.Download.Status", RETRY, STATUS_MAX); } else { UMA_HISTOGRAM_ENUMERATION("ReadingList.Download.Status", FAILURE, STATUS_MAX); + reading_list_model_->SetEntryDistilledState(url, + ReadingListEntry::ERROR); } + break; } - - } else if (success == URLDownloader::ERROR_PERMANENT) { - reading_list_model_->SetEntryDistilledState(url, ReadingListEntry::ERROR); - UMA_HISTOGRAM_ENUMERATION("ReadingList.Download.Status", FAILURE, - STATUS_MAX); } }
diff --git a/ios/chrome/browser/reading_list/url_downloader.cc b/ios/chrome/browser/reading_list/url_downloader.cc index b73616b..d458867 100644 --- a/ios/chrome/browser/reading_list/url_downloader.cc +++ b/ios/chrome/browser/reading_list/url_downloader.cc
@@ -112,7 +112,7 @@ base::Unretained(this), url, title, offline_path, success); // If downloading failed, clean up any partial download. - if (success == ERROR_RETRY || success == ERROR_PERMANENT) { + if (success == ERROR) { base::FilePath directory_path = reading_list::OfflineURLDirectoryAbsolutePath(base_directory_, url); task_tracker_.PostTaskAndReply( @@ -202,7 +202,7 @@ fetcher_->GetResponseHeaders()->GetMimeType(&mime_type); } if (!fetcher_->GetStatus().is_success() || mime_type != mime_type_) { - return DownloadCompletionHandler(original_url_, "", path, ERROR_RETRY); + return DownloadCompletionHandler(original_url_, "", path, ERROR); } base::FilePath temporary_path; // Do not take ownership of the file until the file is moved. This ensures @@ -240,11 +240,11 @@ if (base::Move(temporary_path, absolute_path)) { return DOWNLOAD_SUCCESS; } else { - return ERROR_PERMANENT; + return ERROR; } } - return ERROR_PERMANENT; + return ERROR; } void URLDownloader::DistillerCallback( @@ -262,8 +262,7 @@ return; } // This content cannot be processed, return an error value to the client. - DownloadCompletionHandler(page_url, std::string(), base::FilePath(), - ERROR_RETRY); + DownloadCompletionHandler(page_url, std::string(), base::FilePath(), ERROR); return; } @@ -288,9 +287,9 @@ if (CreateOfflineURLDirectory(url)) { return SaveHTMLForURL(SaveAndReplaceImagesInHTML(url, html, images), url) ? DOWNLOAD_SUCCESS - : ERROR_PERMANENT; + : ERROR; } - return ERROR_PERMANENT; + return ERROR; } bool URLDownloader::CreateOfflineURLDirectory(const GURL& url) {
diff --git a/ios/chrome/browser/reading_list/url_downloader.h b/ios/chrome/browser/reading_list/url_downloader.h index 862df2a..793bd3c 100644 --- a/ios/chrome/browser/reading_list/url_downloader.h +++ b/ios/chrome/browser/reading_list/url_downloader.h
@@ -48,12 +48,9 @@ DOWNLOAD_SUCCESS, // The URL was already available offline. No action was done. DOWNLOAD_EXISTS, - // The URL could not be downloaded because of a temporary error. Client may - // want to try again later. - ERROR_RETRY, - // The URL could not be dowmloaded and URLDownloader thinks a retry would - // end with the same result. There is no need to retry. - ERROR_PERMANENT + // The URL could not be downloaded because of an error. Client may want to + // try again later. + ERROR, }; // A completion callback that takes a GURL and a bool indicating the
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_edit_view_controller.mm b/ios/chrome/browser/ui/bookmarks/bookmark_edit_view_controller.mm index 1c01fe30..96a88858 100644 --- a/ios/chrome/browser/ui/bookmarks/bookmark_edit_view_controller.mm +++ b/ios/chrome/browser/ui/bookmarks/bookmark_edit_view_controller.mm
@@ -357,8 +357,8 @@ self.nameItem.delegate = self; [model addItem:self.nameItem toSectionWithIdentifier:SectionIdentifierInfo]; - self.folderItem = - [[BookmarkParentFolderItem alloc] initWithType:ItemTypeFolder]; + self.folderItem = [[[BookmarkParentFolderItem alloc] + initWithType:ItemTypeFolder] autorelease]; self.folderItem.title = bookmark_utils_ios::TitleForBookmarkNode(self.folder); [model addItem:self.folderItem toSectionWithIdentifier:SectionIdentifierInfo];
diff --git a/ios/clean/chrome/browser/ui/commands/tab_commands.h b/ios/clean/chrome/browser/ui/commands/tab_commands.h index 0f62ecb..6094c6ca 100644 --- a/ios/clean/chrome/browser/ui/commands/tab_commands.h +++ b/ios/clean/chrome/browser/ui/commands/tab_commands.h
@@ -15,6 +15,9 @@ // Display the tab corresponding to |indexPath|. The receiver determines how // this correspondence relates to the tab model(s) it knows about. - (void)showTabAtIndexPath:(NSIndexPath*)indexPath; + +// Remove tab from the tab model(s) the receiver knows about. +- (void)closeTabAtIndexPath:(NSIndexPath*)indexPath; @end #endif // IOS_CLEAN_CHROME_BROWSER_UI_COMMANDS_TAB_COMMANDS_H_
diff --git a/ios/clean/chrome/browser/ui/tab_grid/tab_grid_coordinator.mm b/ios/clean/chrome/browser/ui/tab_grid/tab_grid_coordinator.mm index 51a42f85..8fd156fa 100644 --- a/ios/clean/chrome/browser/ui/tab_grid/tab_grid_coordinator.mm +++ b/ios/clean/chrome/browser/ui/tab_grid/tab_grid_coordinator.mm
@@ -108,6 +108,12 @@ _activeWebStateIndex = index; } +- (void)closeTabAtIndexPath:(NSIndexPath*)indexPath { + size_t index = static_cast<size_t>(indexPath.item); + DCHECK(index < _webStates.size()); + _webStates.erase(_webStates.begin() + index); +} + #pragma mark - TabGridCommands - (void)showTabGrid {
diff --git a/ios/clean/chrome/browser/ui/tab_grid/tab_grid_view_controller.mm b/ios/clean/chrome/browser/ui/tab_grid/tab_grid_view_controller.mm index e5a8980..6296bbe1 100644 --- a/ios/clean/chrome/browser/ui/tab_grid/tab_grid_view_controller.mm +++ b/ios/clean/chrome/browser/ui/tab_grid/tab_grid_view_controller.mm
@@ -157,7 +157,12 @@ } - (void)deleteButtonPressedForCell:(UICollectionViewCell*)cell { - // PLACEHOLDER: handle close tab button. + auto updateBlock = ^{ + NSIndexPath* indexPath = [self.grid indexPathForCell:cell]; + [self.tabCommandHandler closeTabAtIndexPath:indexPath]; + [self.grid deleteItemsAtIndexPaths:@[ indexPath ]]; + }; + [self.grid performBatchUpdates:updateBlock completion:nil]; } @end
diff --git a/ios/showcase/README.md b/ios/showcase/README.md new file mode 100644 index 0000000..2f985f3 --- /dev/null +++ b/ios/showcase/README.md
@@ -0,0 +1,221 @@ +# Chrome for iOS Showcase development app + +This folder holds the code for a dev-only, standalone app for Chrome for iOS +development. It showcases (and is restricted to) UI elements used and developed +for Chrome for iOS. +Goals for this app are to be as simple, as easy to maintain, and as useful as +possible. + +## Detailed Design + +This is a standalone app that is built by the bots, much like `ios_web_shell` +and `chrome_clean_skeleton`. + +### src/ios/showcase + +``` +ios/chrome/app:app +ios/chrome/app:chrome_clean_skeleton +ios/showcase:showcase +ios/showcase:all_tests +ios/web/shell:ios_web_shell +``` + +Much like `experimental/`, the app lives in its own folder. It depends on +Chrome UI code for the production code, but the architecture of the Showcase app +is separate. + +### Language and build + +* **Objective-C++** needed to interact with the view controller classes likely + to be in Objective-C++ as well. + +* **ARC** + +* **GN and Ninja.** The showcase and `showcase:all_tests` targets are linked to + `gn_all`. + +### Features + +* **Class and use cases** +Table of use cases demoing view controller classes under different sets of entry +data. There can be several use cases for the same class so each gets an entry. +Cells on homepage display the use case name and the class name of the view +controller they link to. + +* **Search** +Search box at the top to filter the cells based on the class and use case name. + +* **Simple, tailor-made coordinators** +Coordinators handle flow, so Showcase shouldn't host any of Chrome's +coordinators. Instead, simple and lightweight coordinators will be used in +Showcase. They will handle the initialization of a production view controller, +and setup all mock data needed to display this view controller. + +### Isolation from Chrome + +View controllers in the New Architecture shouldn't need the BrowserProfile, etc. +So mocking the inputs and outputs of a single VC should be easy and not require +the core of Chrome. + +### Non-goals + +* ~~Table views with TableViewModel/CollectionViewModel?~~ + * We want to make the app as small and simple as possible. The fewer + dependencies the better. + +* ~~Can we configure from within the app what these inputs and outputs are?~~ + * Not desirable. Too complex for what we want to achieve. + +## How do I showcase a Chrome UI feature? + +The following nomenclature is used: + +* A **feature** is a Chrome UI feature such as a full-screen or partial-screen + view controller, a cell, a view, or a UI control (such as a custom button). + +### To add a feature to Showcase + +1. Add an entry to the Showcase configuration file, which requires 3 pieces of + information: + + 1. **_ClassForDisplay_** - The UI feature that you want to showcase, such + as a SettingsViewController, or AccountCell, or TabContainer. It appears + as the title of the cell in Showcase. + + 1. **_ClassForInstantiation_** - The actual class that is instantiated + by Showcase. This is either a view controller or a custom + coordinator. (*More information below*). + + 2. **_UseCase_** - A short description that is helpful to the user about + what is being showcased. + + ``` + @{ + showcase::kClassForDisplayKey : @"SettingsViewController", + showcase::kClassForInstantiationKey : @"SettingsCoordinator", + showcase::kUseCaseKey : @"Main settings screen", + }, + ``` + +2. Add the target that contains *ClassForInstantiation* to `showcase/BUILD.gn`. + + ``` + group("features") { + deps = [ + "//ios/chrome/browser/ui/tools:tools_ui", + "//ios/showcase/settings", + "//ios/showcase/tab_bottom", + "//ios/showcase/tab_grid", + "//ios/showcase/tab_top", + "//ios/showcase/uikit_table_view_cell", + # Insert additional feature targets here. + ] + } + ``` + +3. Add the target that contains Earl Grey tests (if any) to `showcase/BUILD.gn`. + + ``` + ios_eg_test("ios_showcase_egtests") { + deps = [ + "//ios/showcase/core:eg_tests", + "//ios/showcase/tab_grid:eg_tests", + # Insert additional feature eg_tests targets here. + ] + } + ``` + +### More on ClassForInstantiation + +There are 3 scenarios for adding features to Showcase: + +* Directly use the ClassForDisplay when it can be fully initialized with a call + to `-init`. + + ``` + showcase::kClassForDisplayKey : @"FeatureViewController", + showcase::kClassForInstantiationKey : @"FeatureViewController", + ``` + +* Use a custom coordinator when you need to showcase a view controller that + requires special initialization or setup (e.g., requires model objects). + + ``` + showcase::kClassForDisplayKey : @"FeatureViewController", + showcase::kClassForInstantiationKey : @"FeatureCoordinator", + ``` + +* Use a custom view controller when you need to showcase a cell, view, or UI + control. + + ``` + showcase::kClassForDisplayKey : @"FeatureView", + showcase::kClassForInstantiationKey : @"FeatureViewViewController", + ``` + +### How to create a custom coordinator + +See example: `SettingsCoordinator - Main settings screen` + +1. Create a folder for `/showcase/feature/`. + +2. Create `feature_use_case_coordinator.h|mm`. + + * Must conform to the `Coordinator` protocol provided under + `/showcase/common/`. + + * Must support being initialized with `-init`. + + * In the `-start` method, instantiate and setup your `FeatureViewController` + with all the mock data necessary to recreate the use case you are + showcasing. Then the view controller is pushed onto the navigation + controller. + +3. Create `/showcase/feature/BUILD.gn`. + + ``` + source_set("feature) { + sources = [ + "feature_use_case_coordinator.h", + "feature_use_case_coordinator.mm", + ] + deps = [ + "//ios/showcase/common", + # Insert target for ClassForDisplay here. + ] + libs = [ "UIKit.framework" ] + configs += [ "//build/config/compiler:enable_arc" ] + } + ``` + +### How to showcase a view (not view controller) + +See example: `UIKitTableViewCellViewController - UIKit Table Cells` + +You will need a glue view controller. + +1. Create a folder for `/showcase/feature_view/`. + +2. Create `feature_view_view_controller.h|mm`. + + 1. Must support being initialized with `-init`. + + 2. Add your view to the view controller and set it up the way you want + (usually in `-viewDidLoad`). + +3. Create `/showcase/feature/BUILD.gn`. + + ``` + source_set("feature) { + sources = [ + "feature_view_view_controller.h", + "feature_view_view_controller.mm", + ] + deps = [ + # Insert target for ClassForDisplay here. + ] + libs = [ "UIKit.framework" ] + configs += [ "//build/config/compiler:enable_arc" ] + } + ```
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-browser-side-navigation b/third_party/WebKit/LayoutTests/FlagExpectations/enable-browser-side-navigation index 20de8a1..fa4bb572 100644 --- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-browser-side-navigation +++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-browser-side-navigation
@@ -8,10 +8,7 @@ crbug.com/551000 http/tests/inspector/console-resource-errors.html [ Failure ] crbug.com/551000 virtual/mojo-loading/http/tests/inspector/console-resource-errors.html [ Failure ] -# Forward redirect info to the renderer. Fixed by https://codereview.chromium.org/2653953005/. -crbug.com/551000 http/tests/inspector/extensions-network-redirect.html [ Timeout ] -crbug.com/551000 virtual/mojo-loading/http/tests/inspector/extensions-network-redirect.html [ Timeout ] -# These ones have an additional issue with a flipped order between diStartProvisionalLoad & willSendRequest +# Flipped order between diStartProvisionalLoad & willSendRequest crbug.com/625765 virtual/mojo-loading/http/tests/loading/redirect-methods.html [ Crash Failure ] crbug.com/625765 http/tests/loading/redirect-methods.html [ Crash Failure ]
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations index f4f1d110..e7457a2 100644 --- a/third_party/WebKit/LayoutTests/TestExpectations +++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -145,6 +145,10 @@ crbug.com/681471 paint/invalidation/media-audio-no-spurious-repaints.html [ Failure Pass Timeout ] crbug.com/681471 virtual/disable-spinvalidation/paint/invalidation/media-audio-no-spurious-repaints.html [ Failure Pass Timeout ] +# Added 2017-02-20 +crbug.com/693510 compositing/reflections/nested-reflection-anchor-point.html [ Failure Pass ] +crbug.com/693510 compositing/reflections/nested-reflection-animated.html [ Failure Pass ] + # ====== Paint team owned tests to here ====== # ====== LayoutNG-only failures from here ====== @@ -1918,6 +1922,7 @@ crbug.com/626703 external/wpt/streams/writable-streams/close.html [ Timeout ] crbug.com/626703 external/wpt/streams/writable-streams/close.serviceworker.https.html [ Timeout ] crbug.com/626703 external/wpt/service-workers/service-worker/registration-useCache.https.html [ Timeout ] +crbug.com/626703 external/wpt/service-workers/service-worker/multi-globals/url-parsing.https.html [ Pass Failure ] crbug.com/626703 external/wpt/streams/writable-streams/close.sharedworker.html [ Timeout ] crbug.com/626703 external/wpt/html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/allow-scripts-flag-changing-2.html [ Timeout ] crbug.com/626703 external/wpt/html/semantics/embedded-content/the-iframe-element/cross_origin_parentage.html [ Timeout ]
diff --git a/third_party/WebKit/LayoutTests/external/wpt/selection/deleteFromDocument-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/selection/deleteFromDocument-expected.txt deleted file mode 100644 index 86c25d5..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/selection/deleteFromDocument-expected.txt +++ /dev/null
@@ -1,101 +0,0 @@ -CONSOLE ERROR: line 66: The given range isn't in document. -CONSOLE ERROR: line 66: The given range isn't in document. -CONSOLE ERROR: line 66: The given range isn't in document. -CONSOLE ERROR: line 66: The given range isn't in document. -CONSOLE ERROR: line 66: The given range isn't in document. -CONSOLE ERROR: line 66: The given range isn't in document. -CONSOLE ERROR: line 66: The given range isn't in document. -CONSOLE ERROR: line 66: The given range isn't in document. -CONSOLE ERROR: line 66: The given range isn't in document. -This is a testharness.js-based test. -Found 60 tests; 38 PASS, 22 FAIL, 0 TIMEOUT, 0 NOTRUN. -PASS Selection.prototype.deleteFromDocument.length must equal 0 -PASS Range 0: empty -PASS Range 1: [paras[0].firstChild, 0, paras[0].firstChild, 0] -FAIL Range 2: [paras[0].firstChild, 0, paras[0].firstChild, 1] assert_true: First differing node: expected Text node "̈b̈c̈d̈ëf̈g̈ḧ -", got Text node "b̈c̈d̈ëf̈g̈ḧ -" expected true got false -PASS Range 3: [paras[0].firstChild, 2, paras[0].firstChild, 8] -FAIL Range 4: [paras[0].firstChild, 2, paras[0].firstChild, 9] assert_true: First differing node: expected Text node "Ä̈f̈g̈ḧ -", got Text node "Äf̈g̈ḧ -" expected true got false -PASS Range 5: [paras[1].firstChild, 0, paras[1].firstChild, 0] -FAIL Range 6: [paras[1].firstChild, 0, paras[1].firstChild, 1] assert_true: First differing node: expected Text node "jklmnop -", got Text node "Ijklmnop -" expected true got false -FAIL Range 7: [paras[1].firstChild, 2, paras[1].firstChild, 8] assert_true: First differing node: expected Text node "Ij -", got Text node "Ijklmnop -" expected true got false -FAIL Range 8: [paras[1].firstChild, 2, paras[1].firstChild, 9] assert_true: First differing node: expected Text node "Ij", got Text node "Ijklmnop -" expected true got false -PASS Range 9: [detachedPara1.firstChild, 0, detachedPara1.firstChild, 0] -PASS Range 10: [detachedPara1.firstChild, 0, detachedPara1.firstChild, 1] -PASS Range 11: [detachedPara1.firstChild, 2, detachedPara1.firstChild, 8] -PASS Range 12: [foreignPara1.firstChild, 0, foreignPara1.firstChild, 0] -PASS Range 13: [foreignPara1.firstChild, 0, foreignPara1.firstChild, 1] -PASS Range 14: [foreignPara1.firstChild, 2, foreignPara1.firstChild, 8] -FAIL Range 15: [document.documentElement, 0, document.documentElement, 1] assert_true: First differing node: expected Element node <html><body><div id="test"><p id="a">Äb̈c̈d̈ëf̈g̈ḧ -</p..., got Element node <html><head><title>Selection test iframe</title> -<link re... expected true got false -FAIL Range 16: [document.documentElement, 0, document.documentElement, 2] assert_true: First differing node: expected Element node <html></html>, got Element node <html><head><title>Selection test iframe</title> -<link re... expected true got false -FAIL Range 17: [document.documentElement, 1, document.documentElement, 2] assert_true: First differing node: expected Element node <html><head><title>Selection test iframe</title> -<link re..., got Element node <html><head><title>Selection test iframe</title> -<link re... expected true got false -PASS Range 18: [document.head, 1, document.head, 1] -FAIL Range 19: [document.body, 0, document.body, 1] assert_true: First differing node: expected Element node <body> - - -</body>, got Element node <body><div id="test"><p id="a"></p><p id="c"></p><p id="d... expected true got false -PASS Range 20: [foreignDoc.documentElement, 0, foreignDoc.documentElement, 1] -PASS Range 21: [foreignDoc.head, 1, foreignDoc.head, 1] -PASS Range 22: [foreignDoc.body, 0, foreignDoc.body, 0] -PASS Range 23: [paras[0], 0, paras[0], 0] -FAIL Range 24: [paras[0], 0, paras[0], 1] assert_true: First differing node: expected Element node <p id="a"></p>, got Element node <p id="a"> -</p> expected true got false -PASS Range 25: [detachedPara1, 0, detachedPara1, 0] -PASS Range 26: [detachedPara1, 0, detachedPara1, 1] -FAIL Range 27: [paras[0].firstChild, 0, paras[1].firstChild, 0] assert_true: First differing node: expected Element node <div id="test"><p id="a"></p><p id="b" style="display:non..., got Element node <div id="test"><p id="a"></p><p id="c">Qrstuvwx</p><p id=... expected true got false -FAIL Range 28: [paras[0].firstChild, 0, paras[1].firstChild, 8] assert_true: First differing node: expected Element node <div id="test"><p id="a"></p><p id="b" style="display:non..., got Element node <div id="test"><p id="a"></p><p id="c">Qrstuvwx</p><p id=... expected true got false -FAIL Range 29: [paras[0].firstChild, 3, paras[3], 1] assert_true: First differing node: expected Element node <div id="test"><p id="a">Äb</p><p id="d" style="display:..., got Element node <div id="test"><p id="a">Äb̈</p><p id="c"></p><p id="d" ... expected true got false -FAIL Range 30: [paras[0], 0, paras[0].firstChild, 7] assert_true: First differing node: expected Text node "̈ëf̈g̈ḧ -", got Text node "ëf̈g̈ḧ -" expected true got false -FAIL Range 31: [testDiv, 2, paras[4], 1] assert_true: First differing node: expected Element node <div id="test"><p id="a">Äb̈c̈d̈ëf̈g̈ḧ -</p><p id="b" s..., got Element node <div id="test"><p id="a">Äb̈c̈d̈ëf̈g̈ḧ -</p><p id="b" s... expected true got false -FAIL Range 32: [testDiv, 1, paras[2].firstChild, 5] assert_true: First differing node: expected Element node <div id="test"><p id="a">Äb̈c̈d̈ëf̈g̈ḧ -</p><p id="c">v..., got Element node <div id="test"><p id="a">Äb̈c̈d̈ëf̈g̈ḧ -</p><p id="b" s... expected true got false -PASS Range 33: [document.documentElement, 1, document.body, 0] -PASS Range 34: [foreignDoc.documentElement, 1, foreignDoc.body, 0] -FAIL Range 35: [document, 0, document, 1] assert_true: First differing node: expected Document node with 1 child, got Document node with 2 children expected true got false -FAIL Range 36: [document, 0, document, 2] assert_true: First differing node: expected Document node with 0 children, got Document node with 2 children expected true got false -FAIL Range 37: [document, 1, document, 2] assert_true: First differing node: expected Document node with 1 child, got Document node with 2 children expected true got false -FAIL Range 38: [testDiv, 0, comment, 5] assert_true: First differing node: expected Element node <div id="test"><!--bet soup?--></div>, got Element node <div id="test"><p id="a"></p><p id="c"></p><p id="d" styl... expected true got false -FAIL Range 39: [paras[2].firstChild, 4, comment, 2] assert_true: First differing node: expected Element node <div id="test"><p id="a">Äb̈c̈d̈ëf̈g̈ḧ -</p><p id="b" s..., got Element node <div id="test"><p id="a">Äb̈c̈d̈ëf̈g̈ḧ -</p><p id="b" s... expected true got false -FAIL Range 40: [paras[3], 1, comment, 8] assert_true: First differing node: expected Element node <div id="test"><p id="a">Äb̈c̈d̈ëf̈g̈ḧ -</p><p id="b" s..., got Element node <div id="test"><p id="a">Äb̈c̈d̈ëf̈g̈ḧ -</p><p id="b" s... expected true got false -PASS Range 41: [foreignDoc, 0, foreignDoc, 0] -PASS Range 42: [foreignDoc, 1, foreignComment, 2] -PASS Range 43: [foreignDoc.body, 0, foreignTextNode, 36] -PASS Range 44: [xmlDoc, 0, xmlDoc, 0] -PASS Range 45: [xmlDoc, 1, xmlComment, 0] -PASS Range 46: [detachedTextNode, 0, detachedTextNode, 8] -PASS Range 47: [detachedForeignTextNode, 7, detachedForeignTextNode, 7] -PASS Range 48: [detachedForeignTextNode, 0, detachedForeignTextNode, 8] -PASS Range 49: [detachedXmlTextNode, 7, detachedXmlTextNode, 7] -PASS Range 50: [detachedXmlTextNode, 0, detachedXmlTextNode, 8] -PASS Range 51: [detachedComment, 3, detachedComment, 4] -PASS Range 52: [detachedComment, 5, detachedComment, 5] -PASS Range 53: [detachedForeignComment, 0, detachedForeignComment, 1] -PASS Range 54: [detachedForeignComment, 4, detachedForeignComment, 4] -PASS Range 55: [detachedXmlComment, 2, detachedXmlComment, 6] -PASS Range 56: [docfrag, 0, docfrag, 0] -PASS Range 57: [foreignDocfrag, 0, foreignDocfrag, 0] -PASS Range 58: [xmlDocfrag, 0, xmlDocfrag, 0] -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/base-uri-self.html b/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/base-uri-self.html new file mode 100644 index 0000000..e2bbfd3 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/base-uri-self.html
@@ -0,0 +1,49 @@ +<!DOCTYPE html> +<html> +<head> + <meta http-equiv="Content-Security-Policy" content="base-uri 'self'"> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script src="/security/contentSecurityPolicy/resources/testharness-helper.js"></script> +</head> +<body> + <script> + async_test(t => { + assert_equals(document.baseURI, window.location.href); + + var b = document.createElement("base"); + b.href = "http://127.0.0.1:8000/"; + document.head.appendChild(b); + + document.addEventListener("securitypolicyviolation", e => t.unreached_func()); + + // Wait until the next frame to give the report time to fire + requestAnimationFrame(t.step_func_done(_ => { + assert_equals(document.baseURI, "http://127.0.0.1:8000/"); + })); + }, "'self' works at top-level."); + + async_test(t => { + var i = document.createElement("iframe"); + i.sandbox = "allow-scripts"; + i.srcdoc = ` + <script> + document.addEventListener("securitypolicyviolation", e => top.postMessage("FAIL", "*")); + </scr` + `ipt> + <base href="http://127.0.0.1:8000/"> + <script> + requestAnimationFrame(_ => { + top.postMessage(document.baseURI, "*"); + }); + </scr` + `ipt>`; + + waitUntilEvent(window, "message") + .then(t.step_func_done(e => { + assert_equals(e.data, "http://127.0.0.1:8000/"); + })); + + document.body.appendChild(i); + }, "'self' works in a sandbox."); + </script> +</body> +</html>
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8ScriptRunner.cpp b/third_party/WebKit/Source/bindings/core/v8/V8ScriptRunner.cpp index 5391482..41c662e 100644 --- a/third_party/WebKit/Source/bindings/core/v8/V8ScriptRunner.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/V8ScriptRunner.cpp
@@ -25,6 +25,7 @@ #include "bindings/core/v8/V8ScriptRunner.h" +#include "bindings/core/v8/BindingSecurity.h" #include "bindings/core/v8/ScriptSourceCode.h" #include "bindings/core/v8/ScriptStreamer.h" #include "bindings/core/v8/V8Binding.h" @@ -32,6 +33,7 @@ #include "bindings/core/v8/V8ThrowException.h" #include "core/dom/Document.h" #include "core/dom/ExecutionContext.h" +#include "core/frame/LocalDOMWindow.h" #include "core/frame/LocalFrame.h" #include "core/frame/PerformanceMonitor.h" #include "core/inspector/InspectorTraceEvents.h" @@ -630,8 +632,9 @@ int argc, v8::Local<v8::Value> args[], v8::Isolate* isolate) { - ScopedFrameBlamer frameBlamer( - context->isDocument() ? toDocument(context)->frame() : nullptr); + LocalFrame* frame = + context->isDocument() ? toDocument(context)->frame() : nullptr; + ScopedFrameBlamer frameBlamer(frame); TRACE_EVENT0("v8", "v8.callFunction"); int depth = v8::MicrotasksScope::GetCurrentDepth(isolate); @@ -649,6 +652,11 @@ TRACE_EVENT_BEGIN1("devtools.timeline", "FunctionCall", "data", InspectorFunctionCallEvent::data(context, function)); + if (frame) { + CHECK(BindingSecurity::shouldAllowAccessToFrame( + toDOMWindow(function->CreationContext())->toLocalDOMWindow(), frame, + BindingSecurity::ErrorReportOption::DoNotReport)); + } CHECK(!ThreadState::current()->isWrapperTracingForbidden()); v8::MicrotasksScope microtasksScope(isolate, v8::MicrotasksScope::kRunMicrotasks);
diff --git a/third_party/WebKit/Source/core/clipboard/DataTransferItem.cpp b/third_party/WebKit/Source/core/clipboard/DataTransferItem.cpp index f57a136..1e81a96 100644 --- a/third_party/WebKit/Source/core/clipboard/DataTransferItem.cpp +++ b/third_party/WebKit/Source/core/clipboard/DataTransferItem.cpp
@@ -86,7 +86,7 @@ ExecutionContext* context = scriptState->getExecutionContext(); InspectorInstrumentation::asyncTaskScheduled( context, "DataTransferItem.getAsString", callback); - TaskRunnerHelper::get(TaskType::UserInteraction, context) + TaskRunnerHelper::get(TaskType::UserInteraction, scriptState) ->postTask(BLINK_FROM_HERE, WTF::bind(&runGetAsStringTask, wrapWeakPersistent(context), wrapPersistent(callback), m_item->getAsString()));
diff --git a/third_party/WebKit/Source/core/editing/DOMSelection.cpp b/third_party/WebKit/Source/core/editing/DOMSelection.cpp index b359dfe..3ab41952 100644 --- a/third_party/WebKit/Source/core/editing/DOMSelection.cpp +++ b/third_party/WebKit/Source/core/editing/DOMSelection.cpp
@@ -648,10 +648,24 @@ UseCounter::SelectionAddRangeIntersect); } +// https://www.w3.org/TR/selection-api/#dom-selection-deletefromdocument void DOMSelection::deleteFromDocument() { if (!isAvailable()) return; + // The method must invoke deleteContents() ([DOM4]) on the context object's + // range if the context object is not empty. Otherwise the method must do + // nothing. + if (Range* range = documentCachedRange()) { + range->deleteContents(ASSERT_NO_EXCEPTION); + return; + } + + // The following code is necessary for + // editing/selection/deleteFromDocument-crash.html, which assumes + // deleteFromDocument() for text selection in a TEXTAREA deletes the TEXTAREA + // value. + FrameSelection& selection = frame()->selection(); if (selection.isNone())
diff --git a/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.cpp b/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.cpp index 78d0920..2064ac7 100644 --- a/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.cpp +++ b/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.cpp
@@ -157,11 +157,15 @@ DCHECK(m_executionContext && m_executionContext->securityContext().getSecurityOrigin()); - setupSelf(*m_executionContext->securityContext().getSecurityOrigin()); // If we're in a Document, set mixed content checking and sandbox // flags, then dump all the parsing error messages, then poke at histograms. if (Document* document = this->document()) { + // We use the origin of the document's base URL in order to deal correctly + // with things like 'about:srcdoc' and 'about:blank', which look to their + // parents for a reasonable URL. + setupSelf(*SecurityOrigin::create(document->baseURL())); + if (m_sandboxMask != SandboxNone) { UseCounter::count(document, UseCounter::SandboxViaCSP); document->enforceSandboxFlags(m_sandboxMask); @@ -186,6 +190,9 @@ if (policy->allowDynamic()) UseCounter::count(*document, UseCounter::CSPWithStrictDynamic); } + } else { + // If we're not in a document, set up 'self' with the Worker's origin: + setupSelf(*m_executionContext->securityContext().getSecurityOrigin()); } // We disable 'eval()' even in the case of report-only policies, and rely on
diff --git a/third_party/WebKit/Source/core/frame/csp/SourceListDirectiveTest.cpp b/third_party/WebKit/Source/core/frame/csp/SourceListDirectiveTest.cpp index 643f57d..0a596c56 100644 --- a/third_party/WebKit/Source/core/frame/csp/SourceListDirectiveTest.cpp +++ b/third_party/WebKit/Source/core/frame/csp/SourceListDirectiveTest.cpp
@@ -33,6 +33,7 @@ KURL secureURL(ParsedURLString, "https://example.test/image.png"); RefPtr<SecurityOrigin> secureOrigin(SecurityOrigin::create(secureURL)); document = Document::create(); + document->setURL(secureURL); document->setSecurityOrigin(secureOrigin); csp->bindToExecutionContext(document.get()); } @@ -41,6 +42,7 @@ KURL secureURL(ParsedURLString, origin); RefPtr<SecurityOrigin> secureOrigin(SecurityOrigin::create(secureURL)); Document* document = Document::create(); + document->setURL(secureURL); document->setSecurityOrigin(secureOrigin); ContentSecurityPolicy* csp = ContentSecurityPolicy::create(); csp->bindToExecutionContext(document);
diff --git a/third_party/WebKit/Source/core/loader/DocumentLoader.cpp b/third_party/WebKit/Source/core/loader/DocumentLoader.cpp index c527aa4..bf36005 100644 --- a/third_party/WebKit/Source/core/loader/DocumentLoader.cpp +++ b/third_party/WebKit/Source/core/loader/DocumentLoader.cpp
@@ -227,15 +227,6 @@ return resource; } -void DocumentLoader::didRedirect(const KURL& oldURL, const KURL& newURL) { - timing().addRedirect(oldURL, newURL); - - // If a redirection happens during a back/forward navigation, don't restore - // any state from the old HistoryItem. There is a provisional history item for - // back/forward navigation only. In the other case, clearing it is a no-op. - frameLoader().clearProvisionalHistoryItem(); -} - void DocumentLoader::dispatchLinkHeaderPreloads( ViewportDescriptionWrapper* viewport, LinkLoader::MediaPreloadPolicy mediaPolicy) { @@ -382,7 +373,13 @@ DCHECK(timing().fetchStart()); appendRedirect(requestURL); - didRedirect(redirectResponse.url(), requestURL); + timing().addRedirect(redirectResponse.url(), requestURL); + + // If a redirection happens during a back/forward navigation, don't restore + // any state from the old HistoryItem. There is a provisional history item for + // back/forward navigation only. In the other case, clearing it is a no-op. + frameLoader().clearProvisionalHistoryItem(); + frameLoaderClient().dispatchDidReceiveServerRedirectForProvisionalLoad(); return true;
diff --git a/third_party/WebKit/Source/core/loader/DocumentLoader.h b/third_party/WebKit/Source/core/loader/DocumentLoader.h index 8023984b..2c12953 100644 --- a/third_party/WebKit/Source/core/loader/DocumentLoader.h +++ b/third_party/WebKit/Source/core/loader/DocumentLoader.h
@@ -190,8 +190,6 @@ const SubstituteData&, ClientRedirectPolicy); - void didRedirect(const KURL& oldURL, const KURL& newURL); - Vector<KURL> m_redirectChain; private:
diff --git a/third_party/WebKit/Source/core/loader/PingLoader.cpp b/third_party/WebKit/Source/core/loader/PingLoader.cpp index b17334d..e138e8b 100644 --- a/third_party/WebKit/Source/core/loader/PingLoader.cpp +++ b/third_party/WebKit/Source/core/loader/PingLoader.cpp
@@ -528,7 +528,7 @@ : "application/json"); request.setHTTPBody(std::move(report)); finishPingRequestInitialization(request, frame, - WebURLRequest::RequestContextPing); + WebURLRequest::RequestContextCSPReport); StoredCredentials credentialsAllowed = SecurityOrigin::create(reportURL)->isSameSchemeHostPort(
diff --git a/third_party/WebKit/Source/modules/quota/DeprecatedStorageInfo.cpp b/third_party/WebKit/Source/modules/quota/DeprecatedStorageInfo.cpp index 0fc83ca..715a428 100644 --- a/third_party/WebKit/Source/modules/quota/DeprecatedStorageInfo.cpp +++ b/third_party/WebKit/Source/modules/quota/DeprecatedStorageInfo.cpp
@@ -54,8 +54,7 @@ DeprecatedStorageQuota* storageQuota = getStorageQuota(storageType); if (!storageQuota) { // Unknown storage type is requested. - TaskRunnerHelper::get(TaskType::MiscPlatformAPI, - scriptState->getExecutionContext()) + TaskRunnerHelper::get(TaskType::MiscPlatformAPI, scriptState) ->postTask(BLINK_FROM_HERE, StorageErrorCallback::createSameThreadTask( errorCallback, NotSupportedError)); return; @@ -73,8 +72,7 @@ DeprecatedStorageQuota* storageQuota = getStorageQuota(storageType); if (!storageQuota) { // Unknown storage type is requested. - TaskRunnerHelper::get(TaskType::MiscPlatformAPI, - scriptState->getExecutionContext()) + TaskRunnerHelper::get(TaskType::MiscPlatformAPI, scriptState) ->postTask(BLINK_FROM_HERE, StorageErrorCallback::createSameThreadTask( errorCallback, NotSupportedError)); return;
diff --git a/third_party/WebKit/Source/modules/quota/DeprecatedStorageQuota.cpp b/third_party/WebKit/Source/modules/quota/DeprecatedStorageQuota.cpp index f24868ab..ac25430 100644 --- a/third_party/WebKit/Source/modules/quota/DeprecatedStorageQuota.cpp +++ b/third_party/WebKit/Source/modules/quota/DeprecatedStorageQuota.cpp
@@ -62,7 +62,7 @@ if (storageType != WebStorageQuotaTypeTemporary && storageType != WebStorageQuotaTypePersistent) { // Unknown storage type is requested. - TaskRunnerHelper::get(TaskType::MiscPlatformAPI, executionContext) + TaskRunnerHelper::get(TaskType::MiscPlatformAPI, scriptState) ->postTask(BLINK_FROM_HERE, StorageErrorCallback::createSameThreadTask( errorCallback, NotSupportedError)); return; @@ -70,7 +70,7 @@ SecurityOrigin* securityOrigin = executionContext->getSecurityOrigin(); if (securityOrigin->isUnique()) { - TaskRunnerHelper::get(TaskType::MiscPlatformAPI, executionContext) + TaskRunnerHelper::get(TaskType::MiscPlatformAPI, scriptState) ->postTask(BLINK_FROM_HERE, StorageErrorCallback::createSameThreadTask( errorCallback, NotSupportedError)); return; @@ -95,7 +95,7 @@ if (storageType != WebStorageQuotaTypeTemporary && storageType != WebStorageQuotaTypePersistent) { // Unknown storage type is requested. - TaskRunnerHelper::get(TaskType::MiscPlatformAPI, executionContext) + TaskRunnerHelper::get(TaskType::MiscPlatformAPI, scriptState) ->postTask(BLINK_FROM_HERE, StorageErrorCallback::createSameThreadTask( errorCallback, NotSupportedError)); return; @@ -103,7 +103,7 @@ StorageQuotaClient* client = StorageQuotaClient::from(executionContext); if (!client) { - TaskRunnerHelper::get(TaskType::MiscPlatformAPI, executionContext) + TaskRunnerHelper::get(TaskType::MiscPlatformAPI, scriptState) ->postTask(BLINK_FROM_HERE, StorageErrorCallback::createSameThreadTask( errorCallback, NotSupportedError)); return;
diff --git a/third_party/WebKit/Source/web/WebDataSourceImpl.cpp b/third_party/WebKit/Source/web/WebDataSourceImpl.cpp index 10f8721..0934e36 100644 --- a/third_party/WebKit/Source/web/WebDataSourceImpl.cpp +++ b/third_party/WebKit/Source/web/WebDataSourceImpl.cpp
@@ -74,16 +74,13 @@ DocumentLoader::appendRedirect(url); } -void WebDataSourceImpl::updateNavigation( - double redirectStartTime, - double redirectEndTime, - double fetchStartTime, - const WebVector<WebURL>& redirectChain) { +void WebDataSourceImpl::updateNavigation(double redirectStartTime, + double redirectEndTime, + double fetchStartTime, + bool hasRedirect) { // Updates the redirection timing if there is at least one redirection // (between two URLs). - if (redirectChain.size() >= 2) { - for (size_t i = 0; i + 1 < redirectChain.size(); ++i) - didRedirect(redirectChain[i], redirectChain[i + 1]); + if (hasRedirect) { timing().setRedirectStart(redirectStartTime); timing().setRedirectEnd(redirectEndTime); }
diff --git a/third_party/WebKit/Source/web/WebDataSourceImpl.h b/third_party/WebKit/Source/web/WebDataSourceImpl.h index 672b784..f0f464d 100644 --- a/third_party/WebKit/Source/web/WebDataSourceImpl.h +++ b/third_party/WebKit/Source/web/WebDataSourceImpl.h
@@ -71,7 +71,7 @@ void updateNavigation(double redirectStartTime, double redirectEndTime, double fetchStartTime, - const WebVector<WebURL>& redirectChain) override; + bool hasRedirect) override; void setSubresourceFilter(WebDocumentSubresourceFilter*) override; static WebNavigationType toWebNavigationType(NavigationType);
diff --git a/third_party/WebKit/public/web/WebDataSource.h b/third_party/WebKit/public/web/WebDataSource.h index 7756cc86..c2b118a 100644 --- a/third_party/WebKit/public/web/WebDataSource.h +++ b/third_party/WebKit/public/web/WebDataSource.h
@@ -112,7 +112,7 @@ virtual void updateNavigation(double redirectStartTime, double redirectEndTime, double fetchStartTime, - const WebVector<WebURL>& redirectChain) = 0; + bool hasRedirect) = 0; // Allows the embedder to inject a filter that will be consulted for each // subsequent subresource load, and gets the final say in deciding whether
diff --git a/tools/android/customtabs_benchmark/scripts/customtabs_benchmark.py b/tools/android/customtabs_benchmark/scripts/customtabs_benchmark.py index 5d46217..5805345 100755 --- a/tools/android/customtabs_benchmark/scripts/customtabs_benchmark.py +++ b/tools/android/customtabs_benchmark/scripts/customtabs_benchmark.py
@@ -35,7 +35,7 @@ # Local build of Chrome (not Chromium). _CHROME_PACKAGE = 'com.google.android.apps.chrome' -_COMMAND_LINE_PATH = '/data/local/tmp/chrome-command-line' +_COMMAND_LINE_FILE = 'chrome-command-line' _TEST_APP_PACKAGE_NAME = 'org.chromium.customtabsclient.test' _INVALID_VALUE = -1 @@ -99,7 +99,7 @@ logcat_timeout = int(timeout_s + delay_to_may_launch_url / 1000. + delay_to_launch_url / 1000.) + 3; - with device_setup.FlagReplacer(device, _COMMAND_LINE_PATH, chrome_args): + with device_setup.FlagReplacer(device, _COMMAND_LINE_FILE, chrome_args): launch_intent = intent.Intent( action='android.intent.action.MAIN', package=_TEST_APP_PACKAGE_NAME, @@ -186,13 +186,13 @@ chrome_args.extend([ '--force-fieldtrials=trial/group', '--force-fieldtrial-params=trial.group:mode/no_state_prefetch', - '--enable-features="NoStatePrefetch<trial"']) + '--enable-features=NoStatePrefetch<trial']) elif config['speculation_mode'] == 'speculative_prefetch': # Speculative Prefetch is enabled through an experiment. chrome_args.extend([ '--force-fieldtrials=trial/group', '--force-fieldtrial-params=trial.group:mode/external-prefetching', - '--enable-features="SpeculativeResourcePrefetching<trial"']) + '--enable-features=SpeculativeResourcePrefetching<trial']) result = RunOnce(device, config['url'], config['warmup'], config['speculation_mode'],
diff --git a/tools/android/loading/controller.py b/tools/android/loading/controller.py index bbd4799a..ace200b03 100644 --- a/tools/android/loading/controller.py +++ b/tools/android/loading/controller.py
@@ -339,13 +339,9 @@ assert self._wpr_attributes.chrome_env_override == {}, \ 'Remote controller doesn\'t support chrome environment variables.' package_info = OPTIONS.ChromePackage() - command_line_path = '/data/local/tmp/chrome-command-line' self._device.ForceStop(package_info.package) - chrome_args = self._GetChromeArguments() - logging.info('Launching %s with flags: %s' % (package_info.package, - subprocess.list2cmdline(chrome_args))) with device_setup.FlagReplacer( - self._device, command_line_path, self._GetChromeArguments()): + self._device, package_info.cmdline_file, self._GetChromeArguments()): self._DismissCrashDialogIfNeeded() start_intent = intent.Intent( package=package_info.package, activity=package_info.activity,
diff --git a/tools/android/loading/device_setup.py b/tools/android/loading/device_setup.py index fc22bdcb5..954ae09 100644 --- a/tools/android/loading/device_setup.py +++ b/tools/android/loading/device_setup.py
@@ -234,16 +234,12 @@ ' without a specified archive.') -def _FormatWPRRelatedChromeArgumentFor(http_port, https_port, escape): +def _FormatWPRRelatedChromeArgumentFor(http_port, https_port): HOST_RULES='MAP * 127.0.0.1,EXCLUDE localhost' - chrome_args = [ + return [ '--testing-fixed-http-port={}'.format(http_port), - '--testing-fixed-https-port={}'.format(https_port)] - if escape: - chrome_args.append('--host-resolver-rules="{}"'.format(HOST_RULES)) - else: - chrome_args.append('--host-resolver-rules={}'.format(HOST_RULES)) - return chrome_args + '--testing-fixed-https-port={}'.format(https_port), + '--host-resolver-rules={}'.format(HOST_RULES)] @contextlib.contextmanager @@ -286,8 +282,7 @@ disable_script_injection=disable_script_injection, wpr_ca_cert_path=private_ca_cert_path, out_log_path=out_log_path) as (http_port, https_port): - chrome_args = _FormatWPRRelatedChromeArgumentFor(http_port, https_port, - escape=False) + chrome_args = _FormatWPRRelatedChromeArgumentFor(http_port, https_port) yield WprAttribute(chrome_args=chrome_args, chrome_env_override={'HOME': temp_home_dir}) @@ -340,8 +335,7 @@ device_https_port = forwarder.Forwarder.DevicePortForHostPort(https_port) try: chrome_args = _FormatWPRRelatedChromeArgumentFor(device_http_port, - device_https_port, - escape=True) + device_https_port) yield WprAttribute(chrome_args=chrome_args, chrome_env_override={}) finally: # Tear down the forwarder.
diff --git a/tools/cygprofile/profile_android_startup.py b/tools/cygprofile/profile_android_startup.py index b4d011f1..96d1b4c 100755 --- a/tools/cygprofile/profile_android_startup.py +++ b/tools/cygprofile/profile_android_startup.py
@@ -178,7 +178,7 @@ self._flag_changer = flag_changer.FlagChanger( self._device, self._cmdline_file) self._flag_changer.AddFlags([ - '--host-resolver-rules="MAP * 127.0.0.1,EXCLUDE localhost"', + '--host-resolver-rules=MAP * 127.0.0.1,EXCLUDE localhost', '--testing-fixed-http-port=%s' % device_http, '--testing-fixed-https-port=%s' % device_https]) @@ -416,4 +416,3 @@ if __name__ == '__main__': sys.exit(main()) -
diff --git a/tools/resource_prefetch_predictor/generate_test_data.py b/tools/resource_prefetch_predictor/generate_test_data.py index 58dd1da1..89986f1 100755 --- a/tools/resource_prefetch_predictor/generate_test_data.py +++ b/tools/resource_prefetch_predictor/generate_test_data.py
@@ -36,7 +36,7 @@ _LEARNING_FLAGS = [ '--force-fieldtrials=trial/group', '--force-fieldtrial-params=trial.group:mode/learning', - '--enable-features="SpeculativeResourcePrefetching<trial"'] + '--enable-features=SpeculativeResourcePrefetching<trial'] def _CreateArgumentParser():
diff --git a/tools/resource_prefetch_predictor/prefetch_benchmark.py b/tools/resource_prefetch_predictor/prefetch_benchmark.py index 586c2ebb..e31bd1d1 100755 --- a/tools/resource_prefetch_predictor/prefetch_benchmark.py +++ b/tools/resource_prefetch_predictor/prefetch_benchmark.py
@@ -59,7 +59,7 @@ def _Setup(device, database_filename): """Sets up a device and returns an instance of RemoteChromeController.""" - chrome_controller = prefetch_predictor_common.Setup(device, ['']) + chrome_controller = prefetch_predictor_common.Setup(device) chrome_package = OPTIONS.ChromePackage() device.ForceStop(chrome_package.package) chrome_controller.ResetBrowserState() @@ -68,9 +68,8 @@ # Make sure that the speculative prefetch predictor is enabled to ensure # that the disk database is re-created. - command_line_path = '/data/local/tmp/chrome-command-line' with device_setup.FlagReplacer( - device, command_line_path, ['--disable-fre']): + device, chrome_package.cmdline_file, ['--disable-fre']): # Launch Chrome for the first time to recreate the local state. launch_intent = intent.Intent( action='android.intent.action.MAIN', @@ -104,7 +103,7 @@ chrome_args.extend([ '--force-fieldtrials=trial/group', '--force-fieldtrial-params=trial.group:mode/external-prefetching', - '--enable-features="SpeculativeResourcePrefetching<trial"']) + '--enable-features=SpeculativeResourcePrefetching<trial']) chrome_controller = controller.RemoteChromeController(device) device.ForceStop(OPTIONS.ChromePackage().package)