diff --git a/DEPS b/DEPS index afc8be0..8e502fd 100644 --- a/DEPS +++ b/DEPS
@@ -40,15 +40,15 @@ # 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': '3befb84efc3deba472849d76af96c6f56060b918', + 'skia_revision': 'e14349a7545e7bd1e93f4c3095db8f481939b053', # 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': '150b8be0e459ff9d420868443cfdc32317e93b5e', + 'v8_revision': 'b90dca90177970979a5c9083b7ee861ddd9cdbd4', # 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. - 'swarming_revision': 'ebc8dab6f8b8d79ec221c94de39a921145abd404', + 'swarming_revision': '11e31afa5d330756ff87aa12064bb5d032896cb5', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ANGLE # and whatever else without interference from each other.
diff --git a/base/debug/activity_tracker.h b/base/debug/activity_tracker.h index fcd3175..719a318 100644 --- a/base/debug/activity_tracker.h +++ b/base/debug/activity_tracker.h
@@ -162,7 +162,7 @@ // Helper function to access an object allocated using this instance. template <typename T> T* GetAsObject(Reference ref) { - return allocator_->GetAsObject<T>(ref, object_type_); + return allocator_->GetAsObject<T>(ref); } // Similar to GetAsObject() but converts references to arrays of objects. @@ -198,6 +198,12 @@ // the |data| field. All fields must be explicitly sized types to ensure no // interoperability problems between 32-bit and 64-bit systems. struct Activity { + // SHA1(base::debug::Activity): Increment this if structure changes! + static constexpr uint32_t kPersistentTypeId = 0x99425159 + 1; + // Expected size for 32/64-bit check. Update this if structure changes! + static constexpr size_t kExpectedInstanceSize = + 48 + 8 * kActivityCallStackSize; + // The type of an activity on the stack. Activities are broken into // categories with the category ID taking the top 4 bits and the lower // bits representing an action within that category. This combination
diff --git a/base/task_scheduler/post_task.h b/base/task_scheduler/post_task.h index 163d06d..8b3e7df 100644 --- a/base/task_scheduler/post_task.h +++ b/base/task_scheduler/post_task.h
@@ -26,7 +26,7 @@ // TaskScheduler must have been registered for the current process via // TaskScheduler::SetInstance() before the functions below are valid. // -// To post a simple one-off task: +// To post a simple one-off task with default traits: // PostTask(FROM_HERE, Bind(...)); // // To post a high priority one-off task to respond to a user interaction: @@ -35,7 +35,7 @@ // TaskTraits().WithPriority(TaskPriority::USER_BLOCKING), // Bind(...)); // -// To post tasks that must run in sequence: +// To post tasks that must run in sequence with default traits: // scoped_refptr<SequencedTaskRunner> task_runner = // CreateSequencedTaskRunnerWithTraits(TaskTraits()); // task_runner.PostTask(FROM_HERE, Bind(...)); @@ -50,17 +50,18 @@ // task_runner.PostTask(FROM_HERE, Bind(...)); // task_runner.PostTask(FROM_HERE, Bind(...)); // -// The default TaskTraits apply to tasks that: +// The default traits apply to tasks that: // (1) don't block (ref. MayBlock() and WithBaseSyncPrimitives()), // (2) prefer inheriting the current priority to specifying their own, and // (3) can either block shutdown or be skipped on shutdown -// (barring current TaskScheduler default). -// If those loose requirements are sufficient for your task, use -// PostTask[AndReply], otherwise override these with explicit traits via -// PostTaskWithTraits[AndReply]. +// (TaskScheduler implementation is free to choose a fitting default). +// Explicit traits must be specified for tasks for which these loose +// requirements are not sufficient. // -// Tasks posted to TaskScheduler with a delay may be coalesced (i.e. delays may -// be adjusted to reduce the number of wakeups and hence power consumption). +// Tasks posted through functions below will run on threads owned by the +// registered TaskScheduler (i.e. not on the main thread). Tasks posted through +// functions below with a delay may be coalesced (i.e. delays may be adjusted to +// reduce the number of wakeups and hence power consumption). // Posts |task| to the TaskScheduler. Calling this is equivalent to calling // PostTaskWithTraits with plain TaskTraits.
diff --git a/base/task_scheduler/task_traits.h b/base/task_scheduler/task_traits.h index 8354650..c2e3728 100644 --- a/base/task_scheduler/task_traits.h +++ b/base/task_scheduler/task_traits.h
@@ -79,9 +79,10 @@ class BASE_EXPORT TaskTraits { public: // Constructs a default TaskTraits for tasks that - // (1) do not make blocking calls - // (2) can inherit their priority from the calling context, and - // (3) may block shutdown or be skipped on shutdown. + // (1) don't block (ref. MayBlock() and WithBaseSyncPrimitives()), + // (2) prefer inheriting the current priority to specifying their own, and + // (3) can either block shutdown or be skipped on shutdown + // (TaskScheduler implementation is free to choose a fitting default). // Tasks that require stricter guarantees and/or know the specific // TaskPriority appropriate for them should highlight those by requesting // explicit traits below.
diff --git a/base/test/scoped_task_scheduler.h b/base/test/scoped_task_scheduler.h index a371647e..4ac2bb541b 100644 --- a/base/test/scoped_task_scheduler.h +++ b/base/test/scoped_task_scheduler.h
@@ -21,6 +21,12 @@ // thread where the ScopedTaskScheduler lives. The destructor runs remaining // BLOCK_SHUTDOWN tasks synchronously. // +// Note: ScopedTaskScheduler intentionally breaks the TaskScheduler contract of +// always running its tasks on threads it owns, instead opting to run its tasks +// on the main thread for determinism in tests. Components that depend on +// TaskScheduler using independent threads should use ScopedAsyncTaskScheduler +// for testing. +// // Example usage: // // In this snippet, RunUntilIdle() returns after "A" is run.
diff --git a/base/time/OWNERS b/base/time/OWNERS index 02bdb39..ff0520a6 100644 --- a/base/time/OWNERS +++ b/base/time/OWNERS
@@ -1 +1,3 @@ miu@chromium.org + +# COMPONENT: Internals>Core
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageView.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageView.java index 546bb0dbb..19942200 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageView.java
@@ -71,6 +71,11 @@ private static final String PARAM_NTP_MAX_TILE_ROWS = "ntp_max_tile_rows"; /** + * Experiment parameter for the number of tile title lines to show. + */ + private static final String PARAM_NTP_TILE_TITLE_LINES = "ntp_tile_title_lines"; + + /** * The maximum number of tiles to try and fit in a row. On smaller screens, there may not be * enough space to fit all of them. */ @@ -800,6 +805,15 @@ ChromeFeatureList.NTP_CONDENSED_LAYOUT, PARAM_NTP_MAX_TILE_ROWS, defaultValue); } + private static int getTileTitleLines() { + int defaultValue = 2; + if (ChromeFeatureList.isEnabled(ChromeFeatureList.NTP_CONDENSED_LAYOUT)) { + defaultValue = 1; + } + return ChromeFeatureList.getFieldTrialParamByFeatureAsInt( + ChromeFeatureList.NTP_CONDENSED_LAYOUT, PARAM_NTP_TILE_TITLE_LINES, defaultValue); + } + @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { if (mNewTabPageLayout != null) { @@ -841,7 +855,7 @@ @Override public void onTileDataChanged() { - mTileGroup.renderTileViews(mTileGridLayout, !mLoadHasCompleted); + mTileGroup.renderTileViews(mTileGridLayout, !mLoadHasCompleted, getTileTitleLines()); mSnapshotTileGridChanged = true; // The page contents are initially hidden; otherwise they'll be drawn centered on the page
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/TileGrid.java b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/TileGrid.java index 123e01b..90d366d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/TileGrid.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/TileGrid.java
@@ -29,6 +29,11 @@ */ private static final String PARAM_CHROME_HOME_MAX_TILE_ROWS = "chrome_home_max_tile_rows"; + /** + * Experiment parameter for the number of tile title lines to show. + */ + private static final String PARAM_CHROME_HOME_TILE_TITLE_LINES = "chrome_home_tile_title_lines"; + private final TileGroup mTileGroup; public TileGrid(SuggestionsUiDelegate uiDelegate, ContextMenuManager contextMenuManager, @@ -78,6 +83,12 @@ ChromeFeatureList.CHROME_HOME, PARAM_CHROME_HOME_MAX_TILE_ROWS, defaultValue); } + private static int getTileTitleLines() { + int defaultValue = 1; + return ChromeFeatureList.getFieldTrialParamByFeatureAsInt( + ChromeFeatureList.CHROME_HOME, PARAM_CHROME_HOME_TILE_TITLE_LINES, defaultValue); + } + /** * The {@code ViewHolder} for the {@link TileGrid}. */ @@ -92,7 +103,7 @@ public void onBindViewHolder(TileGroup tileGroup) { mLayout.setMaxRows(getMaxTileRows()); - tileGroup.renderTileViews(mLayout, /* trackLoadTasks = */ false); + tileGroup.renderTileViews(mLayout, /* trackLoadTasks = */ false, getTileTitleLines()); } public void updateIconView(Tile tile) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/TileGroup.java b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/TileGroup.java index 22f3541..af1c4a2 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/TileGroup.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/TileGroup.java
@@ -192,8 +192,10 @@ * possible because view inflation and icon loading are slow. * @param tileGridLayout The layout to render the tile views into. * @param trackLoadTasks Whether to track load tasks. + * @param titleLines The number of text lines to use for each tile title. */ - public void renderTileViews(TileGridLayout tileGridLayout, boolean trackLoadTasks) { + public void renderTileViews( + TileGridLayout tileGridLayout, boolean trackLoadTasks, int titleLines) { // Map the old tile views by url so they can be reused later. Map<String, TileView> oldTileViews = new HashMap<>(); int childCount = tileGridLayout.getChildCount(); @@ -227,7 +229,7 @@ } // No view was reused, create a new one. - TileView tileView = buildTileView(tile, tileGridLayout, trackLoadTasks); + TileView tileView = buildTileView(tile, tileGridLayout, trackLoadTasks, titleLines); tileView.setOnClickListener(new OnClickListener() { @Override @@ -303,12 +305,14 @@ * @param tile The tile that holds the data to populate the new tile view. * @param parentView The parent of the new tile view. * @param trackLoadTask Whether to track a load task. + * @param titleLines The number of text lines to use for each tile title. * @return The new tile view. */ - private TileView buildTileView(Tile tile, ViewGroup parentView, boolean trackLoadTask) { + private TileView buildTileView( + Tile tile, ViewGroup parentView, boolean trackLoadTask, int titleLines) { TileView tileView = (TileView) LayoutInflater.from(parentView.getContext()) .inflate(R.layout.tile_view, parentView, false); - tileView.initialize(tile); + tileView.initialize(tile, titleLines); LargeIconCallback iconCallback = new LargeIconCallbackImpl(tile, trackLoadTask); if (trackLoadTask) mObserver.onLoadTaskAdded();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/TileView.java b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/TileView.java index b9bde01af..535489c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/TileView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/TileView.java
@@ -35,11 +35,13 @@ * Initializes the view using the data held by {@code tile}. This should be called immediately * after inflation. * @param tile The tile that holds the data to populate this view. + * @param titleLines The number of text lines to use for the tile title. */ - public void initialize(Tile tile) { + public void initialize(Tile tile, int titleLines) { mTile = tile; - ((TextView) findViewById(R.id.tile_view_title)) - .setText(TitleUtil.getTitleForDisplay(mTile.getTitle(), mTile.getUrl())); + TextView titleView = (TextView) findViewById(R.id.tile_view_title); + titleView.setLines(titleLines); + titleView.setText(TitleUtil.getTitleForDisplay(mTile.getTitle(), mTile.getUrl())); renderIcon(); findViewById(R.id.offline_badge) .setVisibility(mTile.isOfflineAvailable() ? View.VISIBLE : View.GONE);
diff --git a/chrome/browser/android/history/browsing_history_bridge.cc b/chrome/browser/android/history/browsing_history_bridge.cc index 5e45e13..9fcd8a0 100644 --- a/chrome/browser/android/history/browsing_history_bridge.cc +++ b/chrome/browser/android/history/browsing_history_bridge.cc
@@ -94,8 +94,6 @@ j_history_service_obj_.obj(), j_query_result_obj_.obj(), !(query_results_info->reached_beginning)); - - j_query_result_obj_.Release(); } void BrowsingHistoryBridge::MarkItemForRemoval(
diff --git a/chrome/browser/browser_about_handler_unittest.cc b/chrome/browser/browser_about_handler_unittest.cc index f9df2da..321fd720 100644 --- a/chrome/browser/browser_about_handler_unittest.cc +++ b/chrome/browser/browser_about_handler_unittest.cc
@@ -82,6 +82,9 @@ // Chrome OS defaults to showing Options in a window and including About in // Options. TEST_F(BrowserAboutHandlerTest, WillHandleBrowserAboutURLForOptionsChromeOS) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndDisableFeature(features::kMaterialDesignSettings); + std::string chrome_prefix(content::kChromeUIScheme); chrome_prefix.append(url::kStandardSchemeSeparator); std::vector<AboutURLTestCase> test_cases( @@ -95,6 +98,9 @@ #else TEST_F(BrowserAboutHandlerTest, WillHandleBrowserAboutURLForOptions) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndDisableFeature(features::kMaterialDesignSettings); + std::string chrome_prefix(content::kChromeUIScheme); chrome_prefix.append(url::kStandardSchemeSeparator); std::vector<AboutURLTestCase> test_cases(
diff --git a/chrome/browser/chrome_content_browser_client_browsertest.cc b/chrome/browser/chrome_content_browser_client_browsertest.cc index fa57c299..e0e82fe9 100644 --- a/chrome/browser/chrome_content_browser_client_browsertest.cc +++ b/chrome/browser/chrome_content_browser_client_browsertest.cc
@@ -4,10 +4,12 @@ #include "base/command_line.h" #include "base/macros.h" +#include "base/test/scoped_feature_list.h" #include "build/build_config.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" +#include "chrome/common/chrome_features.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/pref_names.h" #include "chrome/common/url_constants.h" @@ -32,11 +34,19 @@ GetController().GetLastCommittedEntry(); } + void SetUpInProcessBrowserTestFixture() override { + disable_md_settings_.InitAndDisableFeature( + features::kMaterialDesignSettings); + } + #if defined(OS_CHROMEOS) void SetUpCommandLine(base::CommandLine* command_line) override { command_line->AppendSwitch(switches::kDisableSettingsWindow); } #endif + + private: + base::test::ScopedFeatureList disable_md_settings_; }; IN_PROC_BROWSER_TEST_F(ChromeContentBrowserClientBrowserTest,
diff --git a/chrome/browser/chromeos/arc/arc_session_manager.cc b/chrome/browser/chromeos/arc/arc_session_manager.cc index 6ae5cb9..7eab36a 100644 --- a/chrome/browser/chromeos/arc/arc_session_manager.cc +++ b/chrome/browser/chromeos/arc/arc_session_manager.cc
@@ -118,8 +118,12 @@ registry->RegisterBooleanPref(prefs::kArcEnabled, false); registry->RegisterBooleanPref(prefs::kArcSignedIn, false); registry->RegisterBooleanPref(prefs::kArcTermsAccepted, false); - registry->RegisterBooleanPref(prefs::kArcBackupRestoreEnabled, true); - registry->RegisterBooleanPref(prefs::kArcLocationServiceEnabled, true); + // Note that ArcBackupRestoreEnabled and ArcLocationServiceEnabled prefs have + // to be off by default, until an explicit gesture from the user to enable + // them is received. This is crucial in the cases when these prefs transition + // from a previous managed state to the unmanaged. + registry->RegisterBooleanPref(prefs::kArcBackupRestoreEnabled, false); + registry->RegisterBooleanPref(prefs::kArcLocationServiceEnabled, false); } // static @@ -706,18 +710,30 @@ return; } + PrefService* const prefs = profile_->GetPrefs(); + // For ARC Kiosk we skip ToS because it is very likely that near the device // there will be no one who is eligible to accept them. // TODO(poromov): Move to more Kiosk dedicated set-up phase. if (IsArcKioskMode()) - profile_->GetPrefs()->SetBoolean(prefs::kArcTermsAccepted, true); + prefs->SetBoolean(prefs::kArcTermsAccepted, true); + + // Skip to show UI asking users to enable/disable their preference for + // backup-restore and location-service, if both are managed by the admin + // policy. Note that the ToS agreement is anyway not shown in the case of the + // managed ARC. + if (IsArcManaged() && + prefs->IsManagedPreference(prefs::kArcBackupRestoreEnabled) && + prefs->IsManagedPreference(prefs::kArcLocationServiceEnabled)) { + prefs->SetBoolean(prefs::kArcTermsAccepted, true); + } // If it is marked that sign in has been successfully done, then directly // start ARC. - // For testing, and for Kisok mode, we also skip ToS negotiation procedure. + // For testing, and for Kiosk mode, we also skip ToS negotiation procedure. // For backward compatibility, this check needs to be prior to the // kArcTermsAccepted check below. - if (profile_->GetPrefs()->GetBoolean(prefs::kArcSignedIn) || + if (prefs->GetBoolean(prefs::kArcSignedIn) || IsArcOptInVerificationDisabled() || IsArcKioskMode()) { StartArc(); @@ -751,10 +767,12 @@ // 1) User accepted the Terms of service on OOBE flow. // 2) User accepted the Terms of service on Opt-in flow, but logged out // before ARC sign in procedure was done. Then, logs in again. - if (profile_->GetPrefs()->GetBoolean(prefs::kArcTermsAccepted)) { + if (prefs->GetBoolean(prefs::kArcTermsAccepted)) { // Don't show UI for this progress if it was not shown. - if (support_host_->ui_page() != ArcSupportHost::UIPage::NO_PAGE) + if (support_host_ && + support_host_->ui_page() != ArcSupportHost::UIPage::NO_PAGE) { support_host_->ShowArcLoading(); + } StartArcAndroidManagementCheck(); return; }
diff --git a/chrome/browser/chromeos/arc/arc_session_manager_unittest.cc b/chrome/browser/chromeos/arc/arc_session_manager_unittest.cc index a2ae503..98d8e147 100644 --- a/chrome/browser/chromeos/arc/arc_session_manager_unittest.cc +++ b/chrome/browser/chromeos/arc/arc_session_manager_unittest.cc
@@ -4,6 +4,7 @@ #include <memory> #include <string> +#include <tuple> #include <vector> #include "base/bind.h" @@ -11,10 +12,12 @@ #include "base/files/file_path.h" #include "base/files/file_util.h" #include "base/files/scoped_temp_dir.h" +#include "base/logging.h" #include "base/macros.h" #include "base/memory/ptr_util.h" #include "base/observer_list.h" #include "base/run_loop.h" +#include "base/values.h" #include "chrome/browser/chromeos/arc/arc_optin_uma.h" #include "chrome/browser/chromeos/arc/arc_session_manager.h" #include "chrome/browser/chromeos/arc/optin/arc_terms_of_service_oobe_negotiator.h" @@ -42,6 +45,7 @@ #include "components/arc/arc_util.h" #include "components/arc/test/fake_arc_session.h" #include "components/prefs/pref_service.h" +#include "components/prefs/testing_pref_service.h" #include "components/signin/core/account_id/account_id.h" #include "components/sync/model/fake_sync_change_processor.h" #include "components/sync/model/sync_error_factory_mock.h" @@ -567,6 +571,75 @@ arc_session_manager()->Shutdown(); } +class ArcSessionManagerPolicyTest + : public ArcSessionManagerTest, + public testing::WithParamInterface<std::tuple<base::Value, base::Value>> { + public: + const base::Value& backup_restore_pref_value() const { + return std::get<0>(GetParam()); + } + + const base::Value& location_service_pref_value() const { + return std::get<1>(GetParam()); + } +}; + +TEST_P(ArcSessionManagerPolicyTest, SkippingTerms) { + sync_preferences::TestingPrefServiceSyncable* const prefs = + profile()->GetTestingPrefService(); + + // Backup-restore and location-service prefs are off by default. + EXPECT_FALSE(prefs->GetBoolean(prefs::kArcSignedIn)); + EXPECT_FALSE(prefs->GetBoolean(prefs::kArcTermsAccepted)); + + // Set ARC to be managed. + prefs->SetManagedPref(prefs::kArcEnabled, new base::Value(true)); + + // Assign test values to the prefs. + if (backup_restore_pref_value().is_bool()) { + prefs->SetManagedPref(prefs::kArcBackupRestoreEnabled, + backup_restore_pref_value().DeepCopy()); + } + if (location_service_pref_value().is_bool()) { + prefs->SetManagedPref(prefs::kArcLocationServiceEnabled, + location_service_pref_value().DeepCopy()); + } + + arc_session_manager()->OnPrimaryUserProfilePrepared(profile()); + EXPECT_TRUE(arc_session_manager()->IsArcPlayStoreEnabled()); + EXPECT_TRUE(arc_session_manager()->IsArcManaged()); + + // Terms of Service should be skipped if both ArcBackupRestoreEnabled and + // ArcLocationServiceEnabled are managed. + const ArcSessionManager::State expected_state = + backup_restore_pref_value().is_bool() && + location_service_pref_value().is_bool() + ? ArcSessionManager::State::ACTIVE + : ArcSessionManager::State::SHOWING_TERMS_OF_SERVICE; + EXPECT_EQ(expected_state, arc_session_manager()->state()); + + // Managed values for the prefs are unset. + prefs->RemoveManagedPref(prefs::kArcBackupRestoreEnabled); + prefs->RemoveManagedPref(prefs::kArcLocationServiceEnabled); + + // The ARC state is preserved. The prefs return to the default false values. + EXPECT_EQ(expected_state, arc_session_manager()->state()); + EXPECT_FALSE(prefs->GetBoolean(prefs::kArcBackupRestoreEnabled)); + EXPECT_FALSE(prefs->GetBoolean(prefs::kArcLocationServiceEnabled)); + + // Stop ARC and shutdown the service. + prefs->RemoveManagedPref(prefs::kArcEnabled); + WaitForDataRemoved(ArcSessionManager::State::STOPPED); + arc_session_manager()->Shutdown(); +} + +INSTANTIATE_TEST_CASE_P( + ArcSessionManagerPolicyTest, + ArcSessionManagerPolicyTest, + testing::Combine( + testing::Values(base::Value(), base::Value(false), base::Value(true)), + testing::Values(base::Value(), base::Value(false), base::Value(true)))); + class ArcSessionManagerKioskTest : public ArcSessionManagerTestBase { public: ArcSessionManagerKioskTest() = default;
diff --git a/chrome/browser/chromeos/arc/extensions/fake_arc_support.h b/chrome/browser/chromeos/arc/extensions/fake_arc_support.h index a0af1b5..f34b0ee0 100644 --- a/chrome/browser/chromeos/arc/extensions/fake_arc_support.h +++ b/chrome/browser/chromeos/arc/extensions/fake_arc_support.h
@@ -32,6 +32,10 @@ // Emulates clicking Agree button. void ClickAgreeButton(); + bool metrics_mode() const { return metrics_mode_; } + bool backup_and_restore_mode() const { return backup_and_restore_mode_; } + bool location_service_mode() const { return location_service_mode_; } + // Emulates checking preference box. void set_metrics_mode(bool mode) { metrics_mode_ = mode; } void set_backup_and_restore_mode(bool mode) {
diff --git a/chrome/browser/chromeos/arc/intent_helper/arc_settings_service.cc b/chrome/browser/chromeos/arc/intent_helper/arc_settings_service.cc index b52c9cac..008a1c4 100644 --- a/chrome/browser/chromeos/arc/intent_helper/arc_settings_service.cc +++ b/chrome/browser/chromeos/arc/intent_helper/arc_settings_service.cc
@@ -65,12 +65,15 @@ return !host->empty() && *port; } +PrefService* GetPrefs() { + return ProfileManager::GetActiveUserProfile()->GetPrefs(); +} + // Returns whether kProxy pref proxy config is applied. bool IsPrefProxyConfigApplied() { net::ProxyConfig config; - Profile* profile = ProfileManager::GetActiveUserProfile(); return PrefProxyConfigTrackerImpl::PrefPrecedes( - PrefProxyConfigTrackerImpl::ReadPrefConfig(profile->GetPrefs(), &config)); + PrefProxyConfigTrackerImpl::ReadPrefConfig(GetPrefs(), &config)); } } // namespace @@ -112,18 +115,23 @@ // Stops listening for Chrome settings changes. void StopObservingSettingsChanges(); + // Retrieves Chrome's state for the settings that need to be synced on the + // initial Android boot and send it to Android. + void SyncInitialSettings() const; // Retrieves Chrome's state for the settings that need to be synced on each // Android boot and send it to Android. void SyncRuntimeSettings() const; - // Send settings that need to be synced only on Android first start to - // Android. + // Determine whether a particular setting needs to be synced to Android. + // Keep these lines ordered lexicographically. + bool ShouldSyncBackupEnabled() const; + bool ShouldSyncLocationServiceEnabled() const; + // Send particular settings to Android. // Keep these lines ordered lexicographically. void SyncAccessibilityLargeMouseCursorEnabled() const; void SyncAccessibilityVirtualKeyboardEnabled() const; void SyncBackupEnabled() const; void SyncFocusHighlightEnabled() const; void SyncFontSize() const; - void SyncInitialSettings() const; void SyncLocale() const; void SyncLocationServiceEnabled() const; void SyncProxySettings() const; @@ -204,10 +212,11 @@ SyncSpokenFeedbackEnabled(); } else if (pref_name == prefs::kAccessibilityVirtualKeyboardEnabled) { SyncAccessibilityVirtualKeyboardEnabled(); + } else if (pref_name == prefs::kArcBackupRestoreEnabled) { + if (ShouldSyncBackupEnabled()) + SyncBackupEnabled(); } else if (pref_name == prefs::kArcLocationServiceEnabled) { - const PrefService* const prefs = - ProfileManager::GetActiveUserProfile()->GetPrefs(); - if (prefs->IsManagedPreference(prefs::kArcLocationServiceEnabled)) + if (ShouldSyncLocationServiceEnabled()) SyncLocationServiceEnabled(); } else if (pref_name == prefs::kUse24HourClock) { SyncUse24HourClock(); @@ -249,8 +258,7 @@ } void ArcSettingsServiceImpl::StartObservingSettingsChanges() { - Profile* profile = ProfileManager::GetActiveUserProfile(); - registrar_.Init(profile->GetPrefs()); + registrar_.Init(GetPrefs()); // Keep these lines ordered lexicographically. AddPrefToObserve(prefs::kAccessibilityFocusHighlightEnabled); @@ -293,6 +301,12 @@ this, FROM_HERE); } +void ArcSettingsServiceImpl::SyncInitialSettings() const { + // Keep these lines ordered lexicographically. + SyncBackupEnabled(); + SyncLocationServiceEnabled(); +} + void ArcSettingsServiceImpl::SyncRuntimeSettings() const { // Keep these lines ordered lexicographically. SyncAccessibilityLargeMouseCursorEnabled(); @@ -306,14 +320,28 @@ SyncTimeZone(); SyncUse24HourClock(); - const PrefService* const prefs = - ProfileManager::GetActiveUserProfile()->GetPrefs(); - if (prefs->IsManagedPreference(prefs::kArcBackupRestoreEnabled)) + if (ShouldSyncBackupEnabled()) SyncBackupEnabled(); - if (prefs->IsManagedPreference(prefs::kArcLocationServiceEnabled)) + if (ShouldSyncLocationServiceEnabled()) SyncLocationServiceEnabled(); } +bool ArcSettingsServiceImpl::ShouldSyncBackupEnabled() const { + // Always sync the managed setting. Also sync when the pref is unset, which + // normally happens once after the pref changes from the managed state to + // unmanaged. + return GetPrefs()->IsManagedPreference(prefs::kArcBackupRestoreEnabled) || + !GetPrefs()->HasPrefPath(prefs::kArcBackupRestoreEnabled); +} + +bool ArcSettingsServiceImpl::ShouldSyncLocationServiceEnabled() const { + // Always sync the managed setting. Also sync when the pref is unset, which + // normally happens once after the pref changes from the managed state to + // unmanaged. + return GetPrefs()->IsManagedPreference(prefs::kArcLocationServiceEnabled) || + !GetPrefs()->HasPrefPath(prefs::kArcLocationServiceEnabled); +} + void ArcSettingsServiceImpl::SyncAccessibilityLargeMouseCursorEnabled() const { SendBoolPrefSettingsBroadcast( prefs::kAccessibilityLargeCursorEnabled, @@ -330,6 +358,15 @@ SendBoolPrefSettingsBroadcast( prefs::kArcBackupRestoreEnabled, "org.chromium.arc.intent_helper.SET_BACKUP_ENABLED"); + if (GetPrefs()->IsManagedPreference(prefs::kArcBackupRestoreEnabled)) { + // Unset the user pref so that if the pref becomes unmanaged at some point, + // this change will be synced. + GetPrefs()->ClearPref(prefs::kArcBackupRestoreEnabled); + } else if (!GetPrefs()->HasPrefPath(prefs::kArcBackupRestoreEnabled)) { + // Set the pref value in order to prevent the subsequent syncing. The + // "false" value is a safe default from the legal/privacy perspective. + GetPrefs()->SetBoolean(prefs::kArcBackupRestoreEnabled, false); + } } void ArcSettingsServiceImpl::SyncFocusHighlightEnabled() const { @@ -352,11 +389,6 @@ extras); } -void ArcSettingsServiceImpl::SyncInitialSettings() const { - SyncBackupEnabled(); - SyncLocationServiceEnabled(); -} - void ArcSettingsServiceImpl::SyncLocale() const { const PrefService::Preference* pref = registrar_.prefs()->FindPreference(prefs::kApplicationLocale); @@ -373,13 +405,21 @@ SendBoolPrefSettingsBroadcast( prefs::kArcLocationServiceEnabled, "org.chromium.arc.intent_helper.SET_LOCATION_SERVICE_ENABLED"); + if (GetPrefs()->IsManagedPreference(prefs::kArcLocationServiceEnabled)) { + // Unset the user pref so that if the pref becomes unmanaged at some point, + // this change will be synced. + GetPrefs()->ClearPref(prefs::kArcLocationServiceEnabled); + } else if (!GetPrefs()->HasPrefPath(prefs::kArcLocationServiceEnabled)) { + // Set the pref value in order to prevent the subsequent syncing. The + // "false" value is a safe default from the legal/privacy perspective. + GetPrefs()->SetBoolean(prefs::kArcLocationServiceEnabled, false); + } } void ArcSettingsServiceImpl::SyncProxySettings() const { std::unique_ptr<ProxyConfigDictionary> proxy_config_dict = chromeos::ProxyConfigServiceImpl::GetActiveProxyConfigDictionary( - ProfileManager::GetActiveUserProfile()->GetPrefs(), - g_browser_process->local_state()); + GetPrefs(), g_browser_process->local_state()); if (!proxy_config_dict) return;
diff --git a/chrome/browser/chromeos/arc/intent_helper/arc_settings_service_browsertest.cc b/chrome/browser/chromeos/arc/intent_helper/arc_settings_service_browsertest.cc index bdc2589..b6af8900 100644 --- a/chrome/browser/chromeos/arc/intent_helper/arc_settings_service_browsertest.cc +++ b/chrome/browser/chromeos/arc/intent_helper/arc_settings_service_browsertest.cc
@@ -15,6 +15,7 @@ #include "chrome/browser/chromeos/arc/intent_helper/arc_settings_service.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" +#include "chrome/common/pref_names.h" #include "chrome/test/base/in_process_browser_test.h" #include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/dbus/shill_profile_client.h" @@ -174,6 +175,8 @@ constexpr char kONCPacUrl[] = "http://domain.com/x"; +constexpr char kBackupBroadcastAction[] = + "org.chromium.arc.intent_helper.SET_BACKUP_ENABLED"; constexpr char kLocationServiceBroadcastAction[] = "org.chromium.arc.intent_helper.SET_LOCATION_SERVICE_ENABLED"; constexpr char kSetProxyBroadcastAction[] = @@ -317,7 +320,76 @@ DISALLOW_COPY_AND_ASSIGN(ArcSettingsServiceTest); }; +IN_PROC_BROWSER_TEST_F(ArcSettingsServiceTest, BackupRestorePolicyTest) { + PrefService* const prefs = browser()->profile()->GetPrefs(); + + // Set the user pref as initially enabled. + prefs->SetBoolean(prefs::kArcBackupRestoreEnabled, true); + EXPECT_TRUE(prefs->GetBoolean(prefs::kArcBackupRestoreEnabled)); + + fake_intent_helper_instance_->clear_broadcasts(); + + // The policy is set to false. + policy::PolicyMap policy; + policy.Set(policy::key::kArcBackupRestoreEnabled, + policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER, + policy::POLICY_SOURCE_CLOUD, base::MakeUnique<base::Value>(false), + nullptr); + UpdatePolicy(policy); + + // The pref is disabled and managed, and the corresponding broadcast is sent + // at least once. + EXPECT_FALSE(prefs->GetBoolean(prefs::kArcBackupRestoreEnabled)); + EXPECT_TRUE(prefs->IsManagedPreference(prefs::kArcBackupRestoreEnabled)); + base::DictionaryValue expected_broadcast_extras; + expected_broadcast_extras.SetBoolean("enabled", false); + expected_broadcast_extras.SetBoolean("managed", true); + EXPECT_GE(CountBroadcasts(fake_intent_helper_instance_->broadcasts(), + kBackupBroadcastAction, &expected_broadcast_extras), + 1); + + fake_intent_helper_instance_->clear_broadcasts(); + + // The policy is set to true. + policy.Set(policy::key::kArcBackupRestoreEnabled, + policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER, + policy::POLICY_SOURCE_CLOUD, base::MakeUnique<base::Value>(true), + nullptr); + UpdatePolicy(policy); + + // The pref is enabled and managed, and the corresponding broadcast is sent at + // least once. + EXPECT_TRUE(prefs->GetBoolean(prefs::kArcBackupRestoreEnabled)); + EXPECT_TRUE(prefs->IsManagedPreference(prefs::kArcBackupRestoreEnabled)); + expected_broadcast_extras.SetBoolean("enabled", true); + EXPECT_GE(CountBroadcasts(fake_intent_helper_instance_->broadcasts(), + kBackupBroadcastAction, &expected_broadcast_extras), + 1); + + fake_intent_helper_instance_->clear_broadcasts(); + + // The policy is unset. + policy.Erase(policy::key::kArcBackupRestoreEnabled); + UpdatePolicy(policy); + + // The pref is disabled and unmanaged, and the corresponding broadcast is + // sent. + EXPECT_FALSE(prefs->GetBoolean(prefs::kArcBackupRestoreEnabled)); + EXPECT_FALSE(prefs->IsManagedPreference(prefs::kArcBackupRestoreEnabled)); + expected_broadcast_extras.SetBoolean("enabled", false); + expected_broadcast_extras.SetBoolean("managed", false); + EXPECT_EQ(CountBroadcasts(fake_intent_helper_instance_->broadcasts(), + kBackupBroadcastAction, &expected_broadcast_extras), + 1); +} + IN_PROC_BROWSER_TEST_F(ArcSettingsServiceTest, LocationServicePolicyTest) { + PrefService* const prefs = browser()->profile()->GetPrefs(); + + // Set the user pref as initially enabled. + prefs->SetBoolean(prefs::kArcLocationServiceEnabled, true); + EXPECT_TRUE(prefs->GetBoolean(prefs::kArcLocationServiceEnabled)); + fake_intent_helper_instance_->clear_broadcasts(); // The policy is set to false. @@ -328,11 +400,14 @@ nullptr); UpdatePolicy(policy); - // The broadcast is sent which says that the pref is disabled and managed. + // The pref is disabled and managed, and the corresponding broadcast is sent + // at least once. + EXPECT_FALSE(prefs->GetBoolean(prefs::kArcLocationServiceEnabled)); + EXPECT_TRUE(prefs->IsManagedPreference(prefs::kArcLocationServiceEnabled)); base::DictionaryValue expected_broadcast_extras; expected_broadcast_extras.SetBoolean("enabled", false); expected_broadcast_extras.SetBoolean("managed", true); - EXPECT_EQ(CountBroadcasts(fake_intent_helper_instance_->broadcasts(), + EXPECT_GE(CountBroadcasts(fake_intent_helper_instance_->broadcasts(), kLocationServiceBroadcastAction, &expected_broadcast_extras), 1); @@ -346,8 +421,28 @@ nullptr); UpdatePolicy(policy); - // The broadcast is sent which says that the pref is enabled and managed. + // The pref is enabled and managed, and the corresponding broadcast is sent at + // least once. + EXPECT_TRUE(prefs->GetBoolean(prefs::kArcLocationServiceEnabled)); + EXPECT_TRUE(prefs->IsManagedPreference(prefs::kArcLocationServiceEnabled)); expected_broadcast_extras.SetBoolean("enabled", true); + EXPECT_GE(CountBroadcasts(fake_intent_helper_instance_->broadcasts(), + kLocationServiceBroadcastAction, + &expected_broadcast_extras), + 1); + + fake_intent_helper_instance_->clear_broadcasts(); + + // The policy is unset. + policy.Erase(policy::key::kArcLocationServiceEnabled); + UpdatePolicy(policy); + + // The pref is disabled and unmanaged, and the corresponding broadcast is + // sent. + EXPECT_FALSE(prefs->GetBoolean(prefs::kArcLocationServiceEnabled)); + EXPECT_FALSE(prefs->IsManagedPreference(prefs::kArcLocationServiceEnabled)); + expected_broadcast_extras.SetBoolean("enabled", false); + expected_broadcast_extras.SetBoolean("managed", false); EXPECT_EQ(CountBroadcasts(fake_intent_helper_instance_->broadcasts(), kLocationServiceBroadcastAction, &expected_broadcast_extras),
diff --git a/chrome/browser/chromeos/arc/optin/arc_optin_preference_handler.cc b/chrome/browser/chromeos/arc/optin/arc_optin_preference_handler.cc index 11972d6..8ae3b0f 100644 --- a/chrome/browser/chromeos/arc/optin/arc_optin_preference_handler.cc +++ b/chrome/browser/chromeos/arc/optin/arc_optin_preference_handler.cc
@@ -72,14 +72,26 @@ } void ArcOptInPreferenceHandler::SendBackupAndRestoreMode() { + // Override the pref default to the true value, in order to encourage users to + // consent with it during OptIn flow. + const bool enabled = + pref_service_->HasPrefPath(prefs::kArcBackupRestoreEnabled) + ? pref_service_->GetBoolean(prefs::kArcBackupRestoreEnabled) + : true; observer_->OnBackupAndRestoreModeChanged( - pref_service_->GetBoolean(prefs::kArcBackupRestoreEnabled), + enabled, pref_service_->IsManagedPreference(prefs::kArcBackupRestoreEnabled)); } void ArcOptInPreferenceHandler::SendLocationServicesMode() { + // Override the pref default to the true value, in order to encourage users to + // consent with it during OptIn flow. + const bool enabled = + pref_service_->HasPrefPath(prefs::kArcLocationServiceEnabled) + ? pref_service_->GetBoolean(prefs::kArcLocationServiceEnabled) + : true; observer_->OnLocationServicesModeChanged( - pref_service_->GetBoolean(prefs::kArcLocationServiceEnabled), + enabled, pref_service_->IsManagedPreference(prefs::kArcLocationServiceEnabled)); }
diff --git a/chrome/browser/chromeos/arc/optin/arc_optin_preference_handler.h b/chrome/browser/chromeos/arc/optin/arc_optin_preference_handler.h index 0d4ec31..2cc6d3b9 100644 --- a/chrome/browser/chromeos/arc/optin/arc_optin_preference_handler.h +++ b/chrome/browser/chromeos/arc/optin/arc_optin_preference_handler.h
@@ -20,6 +20,10 @@ // observes changes there. Changes in preferences and metrics mode are passed to // external consumer via ArcOptInPreferenceHandlerObserver. Once started it // immediately sends current state of metrics mode and preferences. +// +// Note that the preferences and metrics mode passed by this class should only +// be used for the OptIn flow, as this class overrides some of the defaults in +// order to encourage users to consent with the settings. class ArcOptInPreferenceHandler { public: ArcOptInPreferenceHandler(ArcOptInPreferenceHandlerObserver* observer,
diff --git a/chrome/browser/chromeos/arc/optin/arc_optin_preference_handler_observer.h b/chrome/browser/chromeos/arc/optin/arc_optin_preference_handler_observer.h index 56d9699..3d121f3 100644 --- a/chrome/browser/chromeos/arc/optin/arc_optin_preference_handler_observer.h +++ b/chrome/browser/chromeos/arc/optin/arc_optin_preference_handler_observer.h
@@ -10,11 +10,11 @@ // Notifies about changes in ARC related preferences and metrics mode. class ArcOptInPreferenceHandlerObserver { public: - // Notifies metrics mode has been changed. + // Notifies that the metrics mode has been changed. virtual void OnMetricsModeChanged(bool enabled, bool managed) = 0; - // Notifies use backup and restore preference has been changed. + // Notifies that the backup and restore mode has been changed. virtual void OnBackupAndRestoreModeChanged(bool enabled, bool managed) = 0; - // Notifies location service consent preference has been changed. + // Notifies that the location service mode has been changed. virtual void OnLocationServicesModeChanged(bool enabled, bool managed) = 0; virtual ~ArcOptInPreferenceHandlerObserver() = default;
diff --git a/chrome/browser/chromeos/arc/optin/arc_terms_of_service_default_negotiator_unittest.cc b/chrome/browser/chromeos/arc/optin/arc_terms_of_service_default_negotiator_unittest.cc index ce080c8d..78eb27f 100644 --- a/chrome/browser/chromeos/arc/optin/arc_terms_of_service_default_negotiator_unittest.cc +++ b/chrome/browser/chromeos/arc/optin/arc_terms_of_service_default_negotiator_unittest.cc
@@ -9,6 +9,7 @@ #include "base/macros.h" #include "base/memory/ptr_util.h" #include "base/run_loop.h" +#include "base/values.h" #include "chrome/browser/chromeos/arc/arc_support_host.h" #include "chrome/browser/chromeos/arc/extensions/fake_arc_support.h" #include "chrome/browser/chromeos/arc/optin/arc_terms_of_service_default_negotiator.h" @@ -18,6 +19,7 @@ #include "chrome/test/base/testing_browser_process.h" #include "chrome/test/base/testing_profile.h" #include "components/prefs/pref_service.h" +#include "components/sync_preferences/testing_pref_service_syncable.h" #include "content/public/test/test_browser_thread_bundle.h" #include "testing/gtest/include/gtest/gtest.h" @@ -34,8 +36,6 @@ new chromeos::FakeChromeUserManager()); profile_ = base::MakeUnique<TestingProfile>(); - profile_->GetPrefs()->SetBoolean(prefs::kArcBackupRestoreEnabled, false); - profile_->GetPrefs()->SetBoolean(prefs::kArcLocationServiceEnabled, false); support_host_ = base::MakeUnique<ArcSupportHost>(profile_.get()); fake_arc_support_ = base::MakeUnique<FakeArcSupport>(support_host_.get()); @@ -51,7 +51,7 @@ user_manager_enabler_.reset(); } - Profile* profile() { return profile_.get(); } + TestingProfile* profile() { return profile_.get(); } ArcSupportHost* support_host() { return support_host_.get(); } FakeArcSupport* fake_arc_support() { return fake_arc_support_.get(); } ArcTermsOfServiceNegotiator* negotiator() { return negotiator_.get(); } @@ -112,10 +112,32 @@ EXPECT_EQ(status, Status::PENDING); EXPECT_EQ(fake_arc_support()->ui_page(), ArcSupportHost::UIPage::TERMS); - // Check the preference related checkbox. - fake_arc_support()->set_metrics_mode(true); - fake_arc_support()->set_backup_and_restore_mode(true); - fake_arc_support()->set_location_service_mode(true); + // By default, the preference related checkboxes are checked, despite that + // the preferences default to false. + EXPECT_FALSE( + profile()->GetPrefs()->GetBoolean(prefs::kArcBackupRestoreEnabled)); + EXPECT_FALSE( + profile()->GetPrefs()->GetBoolean(prefs::kArcLocationServiceEnabled)); + EXPECT_TRUE(fake_arc_support()->backup_and_restore_mode()); + EXPECT_TRUE(fake_arc_support()->location_service_mode()); + + // The preferences are assigned to the managed false value, and the + // corresponding checkboxes are unchecked. + profile()->GetTestingPrefService()->SetManagedPref( + prefs::kArcBackupRestoreEnabled, new base::Value(false)); + EXPECT_FALSE(fake_arc_support()->backup_and_restore_mode()); + profile()->GetTestingPrefService()->SetManagedPref( + prefs::kArcLocationServiceEnabled, new base::Value(false)); + EXPECT_FALSE(fake_arc_support()->location_service_mode()); + + // The managed preference values are removed, and the corresponding checkboxes + // are checked again. + profile()->GetTestingPrefService()->RemoveManagedPref( + prefs::kArcBackupRestoreEnabled); + EXPECT_TRUE(fake_arc_support()->backup_and_restore_mode()); + profile()->GetTestingPrefService()->RemoveManagedPref( + prefs::kArcLocationServiceEnabled); + EXPECT_TRUE(fake_arc_support()->location_service_mode()); // Make sure preference values are not yet updated. EXPECT_FALSE( @@ -135,6 +157,41 @@ profile()->GetPrefs()->GetBoolean(prefs::kArcLocationServiceEnabled)); } +TEST_F(ArcTermsOfServiceDefaultNegotiatorTest, AcceptWithUnchecked) { + // Show Terms of service page. + Status status = Status::PENDING; + negotiator()->StartNegotiation(UpdateStatusCallback(&status)); + + // TERMS page should be shown. + EXPECT_EQ(status, Status::PENDING); + EXPECT_EQ(fake_arc_support()->ui_page(), ArcSupportHost::UIPage::TERMS); + + // Override the preferences from the default values to true. + profile()->GetPrefs()->SetBoolean(prefs::kArcBackupRestoreEnabled, true); + profile()->GetPrefs()->SetBoolean(prefs::kArcLocationServiceEnabled, true); + + // Uncheck the preference related checkboxes. + fake_arc_support()->set_backup_and_restore_mode(false); + fake_arc_support()->set_location_service_mode(false); + + // Make sure preference values are not yet updated. + EXPECT_TRUE( + profile()->GetPrefs()->GetBoolean(prefs::kArcBackupRestoreEnabled)); + EXPECT_TRUE( + profile()->GetPrefs()->GetBoolean(prefs::kArcLocationServiceEnabled)); + + // Click the "AGREE" button so that the callback should be invoked + // with |agreed| = true. + fake_arc_support()->ClickAgreeButton(); + EXPECT_EQ(status, Status::ACCEPTED); + + // Make sure preference values are now updated. + EXPECT_FALSE( + profile()->GetPrefs()->GetBoolean(prefs::kArcBackupRestoreEnabled)); + EXPECT_FALSE( + profile()->GetPrefs()->GetBoolean(prefs::kArcLocationServiceEnabled)); +} + TEST_F(ArcTermsOfServiceDefaultNegotiatorTest, Cancel) { // Show Terms of service page. Status status = Status::PENDING;
diff --git a/chrome/browser/download/download_shelf.cc b/chrome/browser/download/download_shelf.cc index e3172a4..cf47b9d 100644 --- a/chrome/browser/download/download_shelf.cc +++ b/chrome/browser/download/download_shelf.cc
@@ -149,12 +149,12 @@ } } -void DownloadShelf::Show() { +void DownloadShelf::Open() { if (is_hidden_) { should_show_on_unhide_ = true; return; } - DoShow(); + DoOpen(); } void DownloadShelf::Close(CloseReason reason) { @@ -171,7 +171,7 @@ is_hidden_ = true; if (IsShowing()) { should_show_on_unhide_ = true; - DoClose(AUTOMATIC); + DoHide(); } } @@ -181,7 +181,7 @@ is_hidden_ = false; if (should_show_on_unhide_) { should_show_on_unhide_ = false; - DoShow(); + DoUnhide(); } } @@ -203,7 +203,7 @@ if (is_hidden_) Unhide(); - Show(); + Open(); DoAddDownload(download); // browser() can be NULL for tests.
diff --git a/chrome/browser/download/download_shelf.h b/chrome/browser/download/download_shelf.h index aefee262..aa4467f 100644 --- a/chrome/browser/download/download_shelf.h +++ b/chrome/browser/download/download_shelf.h
@@ -95,7 +95,7 @@ virtual bool IsClosing() const = 0; // Opens the shelf. - void Show(); + void Open(); // Closes the shelf. void Close(CloseReason reason); @@ -114,8 +114,10 @@ protected: virtual void DoAddDownload(content::DownloadItem* download) = 0; - virtual void DoShow() = 0; + virtual void DoOpen() = 0; virtual void DoClose(CloseReason reason) = 0; + virtual void DoHide() = 0; + virtual void DoUnhide() = 0; // Time delay to wait before adding a transient download to the shelf. // Protected virtual for testing.
diff --git a/chrome/browser/download/download_shelf_unittest.cc b/chrome/browser/download/download_shelf_unittest.cc index c59e6a0..097cc82 100644 --- a/chrome/browser/download/download_shelf_unittest.cc +++ b/chrome/browser/download/download_shelf_unittest.cc
@@ -94,7 +94,7 @@ } // namespace TEST_F(DownloadShelfTest, ClosesShelfWhenHidden) { - shelf()->Show(); + shelf()->Open(); EXPECT_TRUE(shelf()->IsShowing()); shelf()->Hide(); EXPECT_FALSE(shelf()->IsShowing()); @@ -103,7 +103,7 @@ } TEST_F(DownloadShelfTest, CloseWhileHiddenPreventsShowOnUnhide) { - shelf()->Show(); + shelf()->Open(); shelf()->Hide(); shelf()->Close(DownloadShelf::AUTOMATIC); shelf()->Unhide(); @@ -117,7 +117,7 @@ } TEST_F(DownloadShelfTest, AddDownloadWhileHiddenUnhides) { - shelf()->Show(); + shelf()->Open(); shelf()->Hide(); shelf()->AddDownload(download_item()); EXPECT_TRUE(shelf()->IsShowing());
diff --git a/chrome/browser/download/test_download_shelf.cc b/chrome/browser/download/test_download_shelf.cc index 9538b7cd..80711138 100644 --- a/chrome/browser/download/test_download_shelf.cc +++ b/chrome/browser/download/test_download_shelf.cc
@@ -47,7 +47,7 @@ did_add_download_ = true; } -void TestDownloadShelf::DoShow() { +void TestDownloadShelf::DoOpen() { is_showing_ = true; } @@ -55,6 +55,14 @@ is_showing_ = false; } +void TestDownloadShelf::DoHide() { + is_showing_ = false; +} + +void TestDownloadShelf::DoUnhide() { + is_showing_ = true; +} + base::TimeDelta TestDownloadShelf::GetTransientDownloadShowDelay() { return base::TimeDelta(); }
diff --git a/chrome/browser/download/test_download_shelf.h b/chrome/browser/download/test_download_shelf.h index 7617c05..e00dbb6 100644 --- a/chrome/browser/download/test_download_shelf.h +++ b/chrome/browser/download/test_download_shelf.h
@@ -34,8 +34,10 @@ protected: void DoAddDownload(content::DownloadItem* download) override; - void DoShow() override; + void DoOpen() override; void DoClose(CloseReason reason) override; + void DoHide() override; + void DoUnhide() override; base::TimeDelta GetTransientDownloadShowDelay() override; content::DownloadManager* GetDownloadManager() override;
diff --git a/chrome/browser/extensions/api/cast_streaming/OWNERS b/chrome/browser/extensions/api/cast_streaming/OWNERS index 586a2f54..41c70ee 100644 --- a/chrome/browser/extensions/api/cast_streaming/OWNERS +++ b/chrome/browser/extensions/api/cast_streaming/OWNERS
@@ -1,2 +1,4 @@ hubbe@chromium.org miu@chromium.org + +# COMPONENT: Internals>Cast>Streaming
diff --git a/chrome/browser/extensions/api/developer_private/developer_private_api.cc b/chrome/browser/extensions/api/developer_private/developer_private_api.cc index b4126908..210f429 100644 --- a/chrome/browser/extensions/api/developer_private/developer_private_api.cc +++ b/chrome/browser/extensions/api/developer_private/developer_private_api.cc
@@ -15,7 +15,7 @@ #include "base/strings/string_number_conversions.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" -#include "base/threading/sequenced_worker_pool.h" +#include "base/task_scheduler/post_task.h" #include "chrome/browser/devtools/devtools_window.h" #include "chrome/browser/extensions/api/developer_private/developer_private_mangle.h" #include "chrome/browser/extensions/api/developer_private/entry_picker.h" @@ -1204,9 +1204,9 @@ if (properties.path_suffix == kManifestFile && !properties.manifest_key) return RespondNow(Error(kManifestKeyIsRequiredError)); - base::PostTaskAndReplyWithResult( - content::BrowserThread::GetBlockingPool(), - FROM_HERE, + base::PostTaskWithTraitsAndReplyWithResult( + FROM_HERE, base::TaskTraits().MayBlock().WithPriority( + base::TaskPriority::USER_VISIBLE), base::Bind(&ReadFileToString, extension->path().Append(path_suffix)), base::Bind(&DeveloperPrivateRequestFileSourceFunction::Finish, this));
diff --git a/chrome/browser/extensions/api/tab_capture/OWNERS b/chrome/browser/extensions/api/tab_capture/OWNERS index a24599a..100b4d087 100644 --- a/chrome/browser/extensions/api/tab_capture/OWNERS +++ b/chrome/browser/extensions/api/tab_capture/OWNERS
@@ -1,3 +1,5 @@ hubbe@chromium.org justinlin@chromium.org miu@chromium.org + +# COMPONENT: UI>Browser>TabCapture
diff --git a/chrome/browser/notifications/platform_notification_service_interactive_uitest.cc b/chrome/browser/notifications/platform_notification_service_interactive_uitest.cc index e00df839..88f3984 100644 --- a/chrome/browser/notifications/platform_notification_service_interactive_uitest.cc +++ b/chrome/browser/notifications/platform_notification_service_interactive_uitest.cc
@@ -7,6 +7,7 @@ #include <vector> #include "base/command_line.h" +#include "base/feature_list.h" #include "base/files/file_path.h" #include "base/path_service.h" #include "base/strings/string_piece.h" @@ -364,8 +365,12 @@ content::WebContents* web_contents = browser()->tab_strip_model()->GetActiveWebContents(); ASSERT_TRUE(content::WaitForLoadStop(web_contents)); - ASSERT_EQ("chrome://settings/contentExceptions#notifications", - web_contents->GetLastCommittedURL().spec()); + + std::string url = web_contents->GetLastCommittedURL().spec(); + if (base::FeatureList::IsEnabled(features::kMaterialDesignSettings)) + ASSERT_EQ("chrome://settings/content/notifications", url); + else + ASSERT_EQ("chrome://settings/contentExceptions#notifications", url); } IN_PROC_BROWSER_TEST_F(PlatformNotificationServiceBrowserTest,
diff --git a/chrome/browser/policy/policy_browsertest.cc b/chrome/browser/policy/policy_browsertest.cc index 292b004..fda3b28 100644 --- a/chrome/browser/policy/policy_browsertest.cc +++ b/chrome/browser/policy/policy_browsertest.cc
@@ -31,6 +31,7 @@ #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" +#include "base/test/scoped_feature_list.h" #include "base/test/test_file_util.h" #include "base/threading/sequenced_worker_pool.h" #include "base/time/time.h" @@ -83,6 +84,7 @@ #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/location_bar/location_bar.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" +#include "chrome/common/chrome_features.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/extensions/extension_constants.h" @@ -4168,13 +4170,17 @@ // Test ArcBackupRestoreEnabled policy. IN_PROC_BROWSER_TEST_F(ArcPolicyTest, ArcBackupRestoreEnabled) { - const PrefService* const pref = browser()->profile()->GetPrefs(); + PrefService* const pref = browser()->profile()->GetPrefs(); - // ARC Backup & Restore is switched on by default. - EXPECT_TRUE(pref->GetBoolean(prefs::kArcBackupRestoreEnabled)); + // ARC Backup & Restore is switched off by default. + EXPECT_FALSE(pref->GetBoolean(prefs::kArcBackupRestoreEnabled)); EXPECT_FALSE(pref->IsManagedPreference(prefs::kArcBackupRestoreEnabled)); - // Disable ARC Backup & Restore. + // Switch on ARC Backup & Restore in the user prefs. + pref->SetBoolean(prefs::kArcBackupRestoreEnabled, true); + EXPECT_TRUE(pref->GetBoolean(prefs::kArcBackupRestoreEnabled)); + + // Disable ARC Backup & Restore through the policy. PolicyMap policies; policies.Set(key::kArcBackupRestoreEnabled, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD, @@ -4183,7 +4189,7 @@ EXPECT_FALSE(pref->GetBoolean(prefs::kArcBackupRestoreEnabled)); EXPECT_TRUE(pref->IsManagedPreference(prefs::kArcBackupRestoreEnabled)); - // Enable ARC Backup & Restore. + // Enable ARC Backup & Restore through the policy. policies.Set(key::kArcBackupRestoreEnabled, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD, base::MakeUnique<base::FundamentalValue>(true), nullptr); @@ -4195,7 +4201,7 @@ // Test ArcLocationServiceEnabled policy and its interplay with the // DefaultGeolocationSetting policy. IN_PROC_BROWSER_TEST_F(ArcPolicyTest, ArcLocationServiceEnabled) { - const PrefService* const pref = browser()->profile()->GetPrefs(); + PrefService* const pref = browser()->profile()->GetPrefs(); // Values of the ArcLocationServiceEnabled policy to be tested. const std::vector<base::Value> test_policy_values = { @@ -4211,6 +4217,14 @@ base::FundamentalValue(3), // 'AskGeolocation' }; + // The pref is switched off by default. + EXPECT_FALSE(pref->GetBoolean(prefs::kArcLocationServiceEnabled)); + EXPECT_FALSE(pref->IsManagedPreference(prefs::kArcLocationServiceEnabled)); + + // Switch on the pref in the user prefs. + pref->SetBoolean(prefs::kArcLocationServiceEnabled, true); + EXPECT_TRUE(pref->GetBoolean(prefs::kArcLocationServiceEnabled)); + for (const auto& test_policy_value : test_policy_values) { for (const auto& test_default_geo_policy_value : test_default_geo_policy_values) { @@ -4352,6 +4366,9 @@ }; IN_PROC_BROWSER_TEST_F(ChromeOSPolicyTest, SystemTimezoneAutomaticDetection) { + base::test::ScopedFeatureList disable_md_settings; + disable_md_settings.InitAndDisableFeature(features::kMaterialDesignSettings); + ui_test_utils::NavigateToURL(browser(), GURL("chrome://settings")); chromeos::system::TimeZoneResolverManager* manager = g_browser_process->platform_part()->GetTimezoneResolverManager();
diff --git a/chrome/browser/renderer_host/chrome_extension_message_filter.cc b/chrome/browser/renderer_host/chrome_extension_message_filter.cc index 1870743..2306f56 100644 --- a/chrome/browser/renderer_host/chrome_extension_message_filter.cc +++ b/chrome/browser/renderer_host/chrome_extension_message_filter.cc
@@ -29,8 +29,10 @@ #include "extensions/browser/extension_system.h" #include "extensions/common/api/messaging/message.h" #include "extensions/common/extension_messages.h" +#include "extensions/common/extension_set.h" #include "extensions/common/file_util.h" #include "extensions/common/manifest_handlers/default_locale_handler.h" +#include "extensions/common/manifest_handlers/shared_module_info.h" #include "extensions/common/message_bundle.h" using content::BrowserThread; @@ -200,24 +202,66 @@ void ChromeExtensionMessageFilter::OnGetExtMessageBundle( const std::string& extension_id, IPC::Message* reply_msg) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + + const extensions::ExtensionSet& extension_set = + extension_info_map_->extensions(); + const extensions::Extension* extension = extension_set.GetByID(extension_id); + + if (!extension) { // The extension has gone. + ExtensionHostMsg_GetMessageBundle::WriteReplyParams( + reply_msg, extensions::MessageBundle::SubstitutionMap()); + Send(reply_msg); + return; + } + + const std::string& default_locale = + extensions::LocaleInfo::GetDefaultLocale(extension); + if (default_locale.empty()) { + // A little optimization: send the answer here to avoid an extra thread hop. + std::unique_ptr<extensions::MessageBundle::SubstitutionMap> dictionary_map( + extensions::file_util::LoadNonLocalizedMessageBundleSubstitutionMap( + extension_id)); + ExtensionHostMsg_GetMessageBundle::WriteReplyParams(reply_msg, + *dictionary_map); + Send(reply_msg); + return; + } + + std::vector<base::FilePath> paths_to_load; + paths_to_load.push_back(extension->path()); + + auto imports = extensions::SharedModuleInfo::GetImports(extension); + // Iterate through the imports in reverse. This will allow later imported + // modules to override earlier imported modules, as the list order is + // maintained from the definition in manifest.json of the imports. + for (auto it = imports.rbegin(); it != imports.rend(); ++it) { + const extensions::Extension* imported_extension = + extension_set.GetByID(it->extension_id); + if (!imported_extension) { + NOTREACHED() << "Missing shared module " << it->extension_id; + continue; + } + paths_to_load.push_back(imported_extension->path()); + } + BrowserThread::PostBlockingPoolTask( FROM_HERE, base::Bind( &ChromeExtensionMessageFilter::OnGetExtMessageBundleOnBlockingPool, - this, extension_id, reply_msg)); + this, paths_to_load, extension_id, default_locale, reply_msg)); } void ChromeExtensionMessageFilter::OnGetExtMessageBundleOnBlockingPool( - const std::string& extension_id, + const std::vector<base::FilePath>& extension_paths, + const std::string& main_extension_id, + const std::string& default_locale, IPC::Message* reply_msg) { DCHECK(BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread()); - const extensions::ExtensionSet& extension_set = - extension_info_map_->extensions(); - std::unique_ptr<extensions::MessageBundle::SubstitutionMap> dictionary_map( - extensions::file_util::LoadMessageBundleSubstitutionMapWithImports( - extension_id, extension_set)); + extensions::file_util::LoadMessageBundleSubstitutionMapFromPaths( + extension_paths, main_extension_id, default_locale)); ExtensionHostMsg_GetMessageBundle::WriteReplyParams(reply_msg, *dictionary_map);
diff --git a/chrome/browser/renderer_host/chrome_extension_message_filter.h b/chrome/browser/renderer_host/chrome_extension_message_filter.h index ddce9ca..b746f50 100644 --- a/chrome/browser/renderer_host/chrome_extension_message_filter.h +++ b/chrome/browser/renderer_host/chrome_extension_message_filter.h
@@ -6,6 +6,7 @@ #define CHROME_BROWSER_RENDERER_HOST_CHROME_EXTENSION_MESSAGE_FILTER_H_ #include <string> +#include <vector> #include "base/macros.h" #include "base/sequenced_task_runner_helpers.h" @@ -71,7 +72,9 @@ void OnGetExtMessageBundle(const std::string& extension_id, IPC::Message* reply_msg); void OnGetExtMessageBundleOnBlockingPool( - const std::string& extension_id, + const std::vector<base::FilePath>& extension_paths, + const std::string& main_extension_id, + const std::string& default_locale, IPC::Message* reply_msg); void OnAddAPIActionToExtensionActivityLog( const std::string& extension_id,
diff --git a/chrome/browser/resources/BUILD.gn b/chrome/browser/resources/BUILD.gn index e6a122a..c8edb250 100644 --- a/chrome/browser/resources/BUILD.gn +++ b/chrome/browser/resources/BUILD.gn
@@ -94,18 +94,7 @@ } grit("settings_resources") { - if (use_vulcanize) { - source = "settings/settings_resources_vulcanized.grd" - deps = [ - "//chrome/browser/resources/settings:vulcanize", - ] - grit_flags = [ - "-E", - "root_gen_dir=" + rebase_path(root_gen_dir, root_build_dir), - ] - } else { - source = "settings/settings_resources.grd" - } + source = "settings/settings_resources.grd" # TODO(thestig): use_qualified_include = true defines = chrome_grit_defines
diff --git a/chrome/browser/resources/settings/BUILD.gn b/chrome/browser/resources/settings/BUILD.gn deleted file mode 100644 index 45cc80d1..0000000 --- a/chrome/browser/resources/settings/BUILD.gn +++ /dev/null
@@ -1,31 +0,0 @@ -import("../vulcanize.gni") -import("//tools/grit/grit_rule.gni") -import("//chrome/common/features.gni") - -vulcanize("vulcanize") { - host = "md-settings" - html_in_file = "settings.html" - html_out_file = "vulcanized.html" - insert_in_head = "<base href=\"chrome://\$i18n{hostname}\">" - input = rebase_path(root_gen_dir, root_build_dir) + - "/chrome/browser/resources/settings/settings_resources.pak" - js_out_file = "crisper.js" - - deps = [ - ":flattened_resources", - ] -} - -grit("flattened_resources") { - source = "settings_resources.grd" - - # TODO(thestig): use_qualified_include = true - defines = chrome_grit_defines - outputs = [ - "grit/settings_resources.h", - "grit/settings_resources_map.cc", - "grit/settings_resources_map.h", - "settings_resources.pak", - ] - output_dir = "$root_gen_dir/chrome/browser/resources/settings" -}
diff --git a/chrome/browser/resources/settings/about_page/about_page.html b/chrome/browser/resources/settings/about_page/about_page.html index 15aaba4..3e4f029 100644 --- a/chrome/browser/resources/settings/about_page/about_page.html +++ b/chrome/browser/resources/settings/about_page/about_page.html
@@ -91,13 +91,12 @@ <span class="product-title">$i18n{aboutProductTitle}</span> </div> <div class="settings-box two-line"> - <!-- TODO(dpapad): Investigate why vulcanize does not handle well - a new line after "getIconSrc_(", causes incorrect src URL --> <iron-icon hidden="[[!showUpdateStatus_]]" icon$="[[getIcon_( obsoleteSystemInfo_, currentUpdateStatusEvent_)]]" - src="[[getIconSrc_(obsoleteSystemInfo_, currentUpdateStatusEvent_)]]"> + src="[[getIconSrc_( + obsoleteSystemInfo_, currentUpdateStatusEvent_)]]"> </iron-icon> <div class="start"> <div id="updateStatusMessage" hidden="[[!showUpdateStatus_]]"
diff --git a/chrome/browser/resources/settings/languages_page/languages_page.html b/chrome/browser/resources/settings/languages_page/languages_page.html index 33580fbb..34545a7 100644 --- a/chrome/browser/resources/settings/languages_page/languages_page.html +++ b/chrome/browser/resources/settings/languages_page/languages_page.html
@@ -171,7 +171,7 @@ $i18n{inputMethodEnabled} </div> </div> - <paper-icon-button icon="cr:settings_icon" + <paper-icon-button icon="cr:settings" on-tap="onInputMethodOptionsTap_" hidden="[[!item.hasOptionsPage]]"> </paper-icon-button>
diff --git a/chrome/browser/resources/settings/settings.html b/chrome/browser/resources/settings/settings.html index 2d4d4597..53975ff 100644 --- a/chrome/browser/resources/settings/settings.html +++ b/chrome/browser/resources/settings/settings.html
@@ -3,9 +3,7 @@ <head> <meta charset="utf-8"> <title>$i18n{settings}</title> -<if expr="not use_vulcanize"> <base href="chrome://$i18n{hostname}"> -</if> <link rel="import" href="chrome://resources/html/polymer.html"> <link rel="import" href="settings_ui/settings_ui.html"> <link rel="stylesheet" href="chrome://resources/css/text_defaults_md.css">
diff --git a/chrome/browser/resources/settings/settings_resources.grd b/chrome/browser/resources/settings/settings_resources.grd index f9dbb5b..6ce1ff7 100644 --- a/chrome/browser/resources/settings/settings_resources.grd +++ b/chrome/browser/resources/settings/settings_resources.grd
@@ -961,7 +961,6 @@ file="system_page/system_page.js" type="chrome_html" /> <structure name="IDR_SETTINGS_SETTINGS_HTML" - preprocess="true" file="settings.html" type="chrome_html" /> <structure name="IDR_SETTINGS_USB_DEVICES_HTML"
diff --git a/chrome/browser/resources/settings/settings_resources_vulcanized.grd b/chrome/browser/resources/settings/settings_resources_vulcanized.grd deleted file mode 100644 index 4187200..0000000 --- a/chrome/browser/resources/settings/settings_resources_vulcanized.grd +++ /dev/null
@@ -1,19 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<grit latest_public_release="0" current_release="1" output_all_resource_defines="false"> - <outputs> - <output filename="grit/settings_resources.h" type="rc_header"> - <emit emit_type='prepend'></emit> - </output> - <output filename="grit/settings_resources_map.cc" - type="resource_file_map_source" /> - <output filename="grit/settings_resources_map.h" - type="resource_map_header" /> - <output filename="settings_resources.pak" type="data_package" /> - </outputs> - <release seq="1"> - <includes> - <include name="IDR_MD_SETTINGS_VULCANIZED_HTML" file="${root_gen_dir}\chrome\browser\resources\settings\vulcanized.html" use_base_dir="false" flattenhtml="true" allowexternalscript="true" type="BINDATA" compress="gzip" /> - <include name="IDR_MD_SETTINGS_CRISPER_JS" file="${root_gen_dir}\chrome\browser\resources\settings\crisper.js" use_base_dir="false" flattenhtml="true" type="BINDATA" compress="gzip" /> - </includes> - </release> -</grit>
diff --git a/chrome/browser/resources/welcome/win10/inline.css b/chrome/browser/resources/welcome/win10/inline.css index 6eb9d5d..ac9ce13 100644 --- a/chrome/browser/resources/welcome/win10/inline.css +++ b/chrome/browser/resources/welcome/win10/inline.css
@@ -39,9 +39,8 @@ .heading { font-size: 2.125em; - line-height: 1.6em; - margin-bottom: 0.5em; - margin-top: 1.2em; + padding-bottom: 2rem; + padding-top: 1rem; } .sections { @@ -82,7 +81,6 @@ .section-heading-expand { height: 1.25em; - opacity: 0.54; transition: transform 150ms cubic-bezier(.4, .2, 0, 1) 50ms; width: 1.25em; } @@ -110,6 +108,7 @@ max-height: 0; opacity: 0; transition: max-height 300ms cubic-bezier(.4, .2, 0, 1) 50ms, opacity 150ms; + visibility: hidden; } .section.expandable.expanded .section-steps { @@ -117,6 +116,7 @@ opacity: 1; transition: max-height 300ms cubic-bezier(.4, .2, 0, 1) 50ms, opacity 150ms 250ms; + visibility: visible; } .button {
diff --git a/chrome/browser/resources/welcome/win10/inline.html b/chrome/browser/resources/welcome/win10/inline.html index 52014ae..96674098 100644 --- a/chrome/browser/resources/welcome/win10/inline.html +++ b/chrome/browser/resources/welcome/win10/inline.html
@@ -5,6 +5,8 @@ <link rel="import" href="chrome://resources/cr_elements/icons.html"> <link rel="import" href="chrome://resources/html/cr.html"> + <link rel="import" href="chrome://resources/html/action_link.html"> + <link rel="import" href="chrome://resources/html/action_link_css.html"> <link rel="import" href="chrome://resources/html/polymer.html"> <link rel="import" href="chrome://resources/html/util.html"> <link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html"> @@ -23,27 +25,36 @@ <div class="heading">$i18n{headerText}</div> <div class="sections"> <div class$="[[computeClasses(isCombined)]]"> - <div class="section-heading" on-tap="onToggle"> - <div class="section-heading-text"> - $i18n{defaultBrowserSubheaderText} - </div> - <template is="dom-if" if="[[isCombined]]"> + <template is="dom-if" if="[[isCombined]]"> + <a is="action-link" class="section-heading" on-tap="onToggle"> + <div class="section-heading-text"> + $i18n{defaultBrowserSubheaderText} + </div> <iron-icon class="section-heading-expand" icon="cr:expand-more"> </iron-icon> - </template> - </div> + </a> + </template> + <template is="dom-if" if="[[!isCombined]]"> + <div class="section-heading"> + <div class="section-heading-text"> + $i18n{defaultBrowserSubheaderText} + </div> + </div> + </template> <ol class="section-steps"> <li> - <a href="#" on-tap="onOpenSettings">$i18n{openSettingsText}</a> + <a is="action-link" on-tap="onOpenSettings"> + $i18n{openSettingsText} + </a> </li> <li> <div>$i18nRaw{clickEdgeText}</div> <div class="screenshot-image" id="default-image"> <div class="screenshot-overlay" id="browser-overlay"> - <div>$i18n{webBrowserLabel}</div> + <div aria-hidden="true">$i18n{webBrowserLabel}</div> </div> <div class="screenshot-overlay" id="edge-overlay"> - <div>$i18n{microsoftEdgeLabel}</div> + <div aria-hidden="true">$i18n{microsoftEdgeLabel}</div> </div> </div> </li> @@ -52,18 +63,18 @@ </div> <template is="dom-if" if="[[isCombined]]"> <div class="section expandable"> - <div class="section-heading" on-tap="onToggle"> + <a is="action-link" class="section-heading" on-tap="onToggle"> <div class="section-heading-text">$i18n{pinSubheaderText}</div> <iron-icon class="section-heading-expand" icon="cr:expand-more"> </iron-icon> - </div> + </a> <ol class="section-steps"> <li>$i18nRaw{rightClickText}</li> <li> <div>$i18nRaw{pinInstructionText}</div> <div class="screenshot-image" id="taskbar-image"> <div class="screenshot-overlay" id="taskbar-overlay"> - <div>$i18n{pinToTaskbarLabel}</div> + <div aria-hidden="true">$i18n{pinToTaskbarLabel}</div> </div> <div class="screenshot-overlay" id="icon-overlay"> </div>
diff --git a/chrome/browser/safe_browsing/ui_manager.cc b/chrome/browser/safe_browsing/ui_manager.cc index b8fdbf7..f20caf34 100644 --- a/chrome/browser/safe_browsing/ui_manager.cc +++ b/chrome/browser/safe_browsing/ui_manager.cc
@@ -55,97 +55,51 @@ sb_service_ = NULL; } -void SafeBrowsingUIManager::DisplayBlockingPage( +void SafeBrowsingUIManager::CreateAndSendHitReport( const UnsafeResource& resource) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - if (resource.is_subresource && !resource.is_subframe) { - // Sites tagged as serving Unwanted Software should only show a warning for - // main-frame or sub-frame resource. Similar warning restrictions should be - // applied to malware sites tagged as "landing sites" (see "Types of - // Malware sites" under - // https://developers.google.com/safe-browsing/developers_guide_v3#UserWarnings). - if (resource.threat_type == SB_THREAT_TYPE_URL_UNWANTED || - (resource.threat_type == SB_THREAT_TYPE_URL_MALWARE && - resource.threat_metadata.threat_pattern_type == - ThreatPatternType::MALWARE_LANDING)) { - if (!resource.callback.is_null()) { - DCHECK(resource.callback_thread); - resource.callback_thread->PostTask(FROM_HERE, - base::Bind(resource.callback, true)); - } - - return; - } - } - - // The tab might have been closed. If it was closed, just act as if "Don't - // Proceed" had been chosen. WebContents* web_contents = resource.web_contents_getter.Run(); - if (!web_contents) { - std::vector<UnsafeResource> resources; - resources.push_back(resource); - OnBlockingPageDone(resources, false, web_contents, - GetMainFrameWhitelistUrlForResource(resource)); - return; + DCHECK(web_contents); + HitReport hit_report; + hit_report.malicious_url = resource.url; + hit_report.is_subresource = resource.is_subresource; + hit_report.threat_type = resource.threat_type; + hit_report.threat_source = resource.threat_source; + hit_report.population_id = resource.threat_metadata.population_id; + + NavigationEntry* entry = resource.GetNavigationEntryForResource(); + if (entry) { + hit_report.page_url = entry->GetURL(); + hit_report.referrer_url = entry->GetReferrer().url; } - // Check if the user has already ignored a SB warning for the same WebContents - // and top-level domain. - if (IsWhitelisted(resource)) { - if (!resource.callback.is_null()) { - DCHECK(resource.callback_thread); - resource.callback_thread->PostTask(FROM_HERE, - base::Bind(resource.callback, true)); - } - return; + // When the malicious url is on the main frame, and resource.original_url + // is not the same as the resource.url, that means we have a redirect from + // resource.original_url to resource.url. + // Also, at this point, page_url points to the _previous_ page that we + // were on. We replace page_url with resource.original_url and referrer + // with page_url. + if (!resource.is_subresource && !resource.original_url.is_empty() && + resource.original_url != resource.url) { + hit_report.referrer_url = hit_report.page_url; + hit_report.page_url = resource.original_url; } - if (resource.threat_type != SB_THREAT_TYPE_SAFE) { - HitReport hit_report; - hit_report.malicious_url = resource.url; - hit_report.is_subresource = resource.is_subresource; - hit_report.threat_type = resource.threat_type; - hit_report.threat_source = resource.threat_source; - hit_report.population_id = resource.threat_metadata.population_id; + Profile* profile = + Profile::FromBrowserContext(web_contents->GetBrowserContext()); + hit_report.extended_reporting_level = + profile ? GetExtendedReportingLevel(*profile->GetPrefs()) + : SBER_LEVEL_OFF; + hit_report.is_metrics_reporting_active = + ChromeMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled(); - NavigationEntry* entry = resource.GetNavigationEntryForResource(); - if (entry) { - hit_report.page_url = entry->GetURL(); - hit_report.referrer_url = entry->GetReferrer().url; - } + MaybeReportSafeBrowsingHit(hit_report); - // When the malicious url is on the main frame, and resource.original_url - // is not the same as the resource.url, that means we have a redirect from - // resource.original_url to resource.url. - // Also, at this point, page_url points to the _previous_ page that we - // were on. We replace page_url with resource.original_url and referrer - // with page_url. - if (!resource.is_subresource && - !resource.original_url.is_empty() && - resource.original_url != resource.url) { - hit_report.referrer_url = hit_report.page_url; - hit_report.page_url = resource.original_url; - } + for (Observer& observer : observer_list_) + observer.OnSafeBrowsingHit(resource); +} - Profile* profile = - Profile::FromBrowserContext(web_contents->GetBrowserContext()); - hit_report.extended_reporting_level = - profile ? GetExtendedReportingLevel(*profile->GetPrefs()) - : SBER_LEVEL_OFF; - hit_report.is_metrics_reporting_active = - ChromeMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled(); - - MaybeReportSafeBrowsingHit(hit_report); - } - - if (resource.threat_type != SB_THREAT_TYPE_SAFE) { - for (Observer& observer : observer_list_) - observer.OnSafeBrowsingHit(resource); - } - AddToWhitelistUrlSet(GetMainFrameWhitelistUrlForResource(resource), - resource.web_contents_getter.Run(), - true /* A decision is now pending */, - resource.threat_type); +void SafeBrowsingUIManager::ShowBlockingPageForResource( + const UnsafeResource& resource) { SafeBrowsingBlockingPage::ShowBlockingPage(this, resource); }
diff --git a/chrome/browser/safe_browsing/ui_manager.h b/chrome/browser/safe_browsing/ui_manager.h index cbc2c0d00..7ac91d4 100644 --- a/chrome/browser/safe_browsing/ui_manager.h +++ b/chrome/browser/safe_browsing/ui_manager.h
@@ -63,13 +63,6 @@ // on IO thread. If shutdown is true, the manager is disabled permanently. void StopOnIOThread(bool shutdown) override; - // Called on the UI thread to display an interstitial page. - // |url| is the url of the resource that matches a safe browsing list. - // If the request contained a chain of redirects, |url| is the last url - // in the chain, and |original_url| is the first one (the root of the - // chain). Otherwise, |original_url| = |url|. - void DisplayBlockingPage(const UnsafeResource& resource) override; - // Called on the IO thread by the ThreatDetails with the serialized // protocol buffer, so the service can send it over. void SendSerializedThreatDetails(const std::string& serialized) override; @@ -107,6 +100,14 @@ void ReportSafeBrowsingHitOnIOThread( const safe_browsing::HitReport& hit_report) override; + // Creates a hit report for the given resource and calls + // MaybeReportSafeBrowsingHit. This also notifies all observers in + // |observer_list_|. + void CreateAndSendHitReport(const UnsafeResource& resource) override; + + // Calls SafeBrowsingBlockingPage::ShowBlockingPage(). + void ShowBlockingPageForResource(const UnsafeResource& resource) override; + private: friend class SafeBrowsingUIManagerTest; friend class TestSafeBrowsingUIManager;
diff --git a/chrome/browser/sync/test/integration/sync_test.cc b/chrome/browser/sync/test/integration/sync_test.cc index d1272415..74d6549 100644 --- a/chrome/browser/sync/test/integration/sync_test.cc +++ b/chrome/browser/sync/test/integration/sync_test.cc
@@ -82,6 +82,7 @@ #include "net/base/load_flags.h" #include "net/base/network_change_notifier.h" #include "net/base/port_util.h" +#include "net/traffic_annotation/network_traffic_annotation_test_helper.h" #include "net/url_request/test_url_fetcher_factory.h" #include "net/url_request/url_fetcher.h" #include "net/url_request/url_fetcher_delegate.h" @@ -978,7 +979,8 @@ GURL sync_url_status(sync_url.append("/healthz")); SyncServerStatusChecker delegate; std::unique_ptr<net::URLFetcher> fetcher = - net::URLFetcher::Create(sync_url_status, net::URLFetcher::GET, &delegate); + net::URLFetcher::Create(sync_url_status, net::URLFetcher::GET, &delegate, + TRAFFIC_ANNOTATION_FOR_TESTS); fetcher->SetLoadFlags(net::LOAD_DISABLE_CACHE | net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES);
diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_impl_browsertest.cc b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_impl_browsertest.cc index 538c7b0a..ca9f3bd 100644 --- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_impl_browsertest.cc +++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_impl_browsertest.cc
@@ -1065,7 +1065,8 @@ // Confirm that a tab can be moved between browsers while maintaining the // correct running state. -IN_PROC_BROWSER_TEST_F(ShelfAppBrowserTest, TabDragAndDrop) { +// Disabled due to flake: crbug.com/693341. +IN_PROC_BROWSER_TEST_F(ShelfAppBrowserTest, DISABLED_TabDragAndDrop) { TabStripModel* tab_strip_model1 = browser()->tab_strip_model(); EXPECT_EQ(1, tab_strip_model1->count()); int browser_index = GetIndexOfShelfItemType(ash::TYPE_BROWSER_SHORTCUT);
diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc index df9d34c..6d268b3 100644 --- a/chrome/browser/ui/browser.cc +++ b/chrome/browser/ui/browser.cc
@@ -826,6 +826,11 @@ //////////////////////////////////////////////////////////////////////////////// // Browser, Tab adding/showing functions: +void Browser::WindowFullscreenStateWillChange() { + exclusive_access_manager_->fullscreen_controller() + ->WindowFullscreenStateWillChange(); +} + void Browser::WindowFullscreenStateChanged() { exclusive_access_manager_->fullscreen_controller() ->WindowFullscreenStateChanged();
diff --git a/chrome/browser/ui/browser.h b/chrome/browser/ui/browser.h index c741ab7..59da0950 100644 --- a/chrome/browser/ui/browser.h +++ b/chrome/browser/ui/browser.h
@@ -368,9 +368,10 @@ // External state change handling //////////////////////////////////////////// - // Invoked when the fullscreen state of the window changes. - // BrowserWindow::EnterFullscreen invokes this after the window has become - // fullscreen. + // BrowserWindow::EnterFullscreen invokes WindowFullscreenStateWillChange at + // the beginning of a fullscreen transition, and WindowFullscreenStateChanged + // at the end. + void WindowFullscreenStateWillChange(); void WindowFullscreenStateChanged(); // Assorted browser commands ////////////////////////////////////////////////
diff --git a/chrome/browser/ui/cocoa/browser_window_controller_private.mm b/chrome/browser/ui/cocoa/browser_window_controller_private.mm index f084fb03..03216863 100644 --- a/chrome/browser/ui/cocoa/browser_window_controller_private.mm +++ b/chrome/browser/ui/cocoa/browser_window_controller_private.mm
@@ -610,6 +610,7 @@ [self setSheetHiddenForFullscreenTransition:YES]; [self adjustUIForEnteringFullscreen]; + browser_->WindowFullscreenStateWillChange(); } - (void)windowDidEnterFullScreen:(NSNotification*)notification { @@ -700,6 +701,7 @@ } else { [self adjustUIForExitingFullscreen]; } + browser_->WindowFullscreenStateWillChange(); } - (void)windowDidExitFullScreen:(NSNotification*)notification {
diff --git a/chrome/browser/ui/cocoa/download/download_shelf_controller.h b/chrome/browser/ui/cocoa/download/download_shelf_controller.h index f124bb8..071f806 100644 --- a/chrome/browser/ui/cocoa/download/download_shelf_controller.h +++ b/chrome/browser/ui/cocoa/download/download_shelf_controller.h
@@ -102,7 +102,8 @@ // directly, the shelf visibility state maintained by DownloadShelf and the // owning Browser will not be updated. - (void)showDownloadShelf:(BOOL)show - isUserAction:(BOOL)isUserAction; + isUserAction:(BOOL)isUserAction + animate:(BOOL)animate; // Returns our view cast as an AnimatableView. - (AnimatableView*)animatableView;
diff --git a/chrome/browser/ui/cocoa/download/download_shelf_controller.mm b/chrome/browser/ui/cocoa/download/download_shelf_controller.mm index cc0cc76..364bf2a 100644 --- a/chrome/browser/ui/cocoa/download/download_shelf_controller.mm +++ b/chrome/browser/ui/cocoa/download/download_shelf_controller.mm
@@ -227,7 +227,8 @@ } - (void)showDownloadShelf:(BOOL)show - isUserAction:(BOOL)isUserAction { + isUserAction:(BOOL)isUserAction + animate:(BOOL)animate { [self cancelAutoClose]; shouldCloseOnMouseExit_ = NO; @@ -251,11 +252,11 @@ // do no animation over janky animation. Find a way to make animating in // smoother. AnimatableView* view = [self animatableView]; - if (show) { - [view setHeight:maxShelfHeight_]; - [view setHidden:NO]; - } else { + if (animate && !show) { [view animateToNewHeight:0 duration:kDownloadShelfCloseDuration]; + } else { + [view setHeight:show ? maxShelfHeight_ : 0]; + [view setHidden:!show]; } barIsVisible_ = show;
diff --git a/chrome/browser/ui/cocoa/download/download_shelf_controller_unittest.mm b/chrome/browser/ui/cocoa/download/download_shelf_controller_unittest.mm index c4b4e21..b444f061 100644 --- a/chrome/browser/ui/cocoa/download/download_shelf_controller_unittest.mm +++ b/chrome/browser/ui/cocoa/download/download_shelf_controller_unittest.mm
@@ -11,7 +11,6 @@ #import "base/mac/scoped_block.h" #import "base/mac/scoped_nsobject.h" -#include "base/run_loop.h" #include "chrome/browser/download/download_shelf.h" #import "chrome/browser/ui/cocoa/download/download_item_controller.h" #include "chrome/browser/ui/cocoa/test/cocoa_profile_test.h" @@ -171,8 +170,7 @@ // immediately. TEST_F(DownloadShelfControllerTest, AddAndRemoveDownload) { base::scoped_nsobject<DownloadItemController> item(CreateItemController()); - [shelf_ showDownloadShelf:YES - isUserAction:NO]; + [shelf_ showDownloadShelf:YES isUserAction:NO animate:YES]; EXPECT_TRUE([shelf_ isVisible]); EXPECT_TRUE([shelf_ bridge]->IsShowing()); [shelf_ add:item]; @@ -188,8 +186,7 @@ TEST_F(DownloadShelfControllerTest, AddAndRemoveWithActiveItem) { base::scoped_nsobject<DownloadItemController> item1(CreateItemController()); base::scoped_nsobject<DownloadItemController> item2(CreateItemController()); - [shelf_ showDownloadShelf:YES - isUserAction:NO]; + [shelf_ showDownloadShelf:YES isUserAction:NO animate:YES]; EXPECT_TRUE([shelf_ isVisible]); [shelf_ add:item1.get()]; [shelf_ add:item2.get()]; @@ -204,8 +201,7 @@ // active downloads on it. TEST_F(DownloadShelfControllerTest, HideAndUnhide) { base::scoped_nsobject<DownloadItemController> item(CreateItemController()); - [shelf_ showDownloadShelf:YES - isUserAction:NO]; + [shelf_ showDownloadShelf:YES isUserAction:NO animate:YES]; EXPECT_TRUE([shelf_ isVisible]); [shelf_ add:item.get()]; [shelf_ bridge]->Hide(); @@ -220,8 +216,7 @@ // active downloads are removed from the shelf while the shelf was hidden. TEST_F(DownloadShelfControllerTest, HideAutocloseUnhide) { base::scoped_nsobject<DownloadItemController> item(CreateItemController()); - [shelf_ showDownloadShelf:YES - isUserAction:NO]; + [shelf_ showDownloadShelf:YES isUserAction:NO animate:YES]; EXPECT_TRUE([shelf_ isVisible]); [shelf_ add:item.get()]; [shelf_ bridge]->Hide(); @@ -236,8 +231,7 @@ // the download shelf at the time the autoclose is scheduled. TEST_F(DownloadShelfControllerTest, AutoCloseAfterOpenWithMouseInShelf) { base::scoped_nsobject<DownloadItemController> item(CreateItemController()); - [shelf_ showDownloadShelf:YES - isUserAction:NO]; + [shelf_ showDownloadShelf:YES isUserAction:NO animate:YES]; EXPECT_TRUE([shelf_ isVisible]); [shelf_ add:item.get()]; // Expect 2 cancelAutoClose calls: From the showDownloadShelf: call and the @@ -273,8 +267,7 @@ // Test of autoclosing behavior after opening a download item. TEST_F(DownloadShelfControllerTest, AutoCloseAfterOpenWithMouseOffShelf) { base::scoped_nsobject<DownloadItemController> item(CreateItemController()); - [shelf_ showDownloadShelf:YES - isUserAction:NO]; + [shelf_ showDownloadShelf:YES isUserAction:NO animate:YES]; EXPECT_TRUE([shelf_ isVisible]); [shelf_ add:item.get()]; @@ -292,8 +285,7 @@ // autoClose is cancelled. TEST_F(DownloadShelfControllerTest, CloseWithPendingAutoClose) { base::scoped_nsobject<DownloadItemController> item(CreateItemController()); - [shelf_ showDownloadShelf:YES - isUserAction:NO]; + [shelf_ showDownloadShelf:YES isUserAction:NO animate:YES]; EXPECT_TRUE([shelf_ isVisible]); [shelf_ add:item.get()]; // Expect 2 cancelAutoClose calls: From the showDownloadShelf: call and the @@ -333,8 +325,7 @@ // added to it. TEST_F(DownloadShelfControllerTest, AddItemWithPendingAutoClose) { base::scoped_nsobject<DownloadItemController> item(CreateItemController()); - [shelf_ showDownloadShelf:YES - isUserAction:NO]; + [shelf_ showDownloadShelf:YES isUserAction:NO animate:YES]; EXPECT_TRUE([shelf_ isVisible]); [shelf_ add:item.get()]; // Expect 2 cancelAutoClose calls: From the showDownloadShelf: call and the @@ -373,8 +364,7 @@ // Test that pending autoClose calls are cancelled when exiting. TEST_F(DownloadShelfControllerTest, CancelAutoCloseOnExit) { base::scoped_nsobject<DownloadItemController> item(CreateItemController()); - [shelf_ showDownloadShelf:YES - isUserAction:NO]; + [shelf_ showDownloadShelf:YES isUserAction:NO animate:YES]; EXPECT_TRUE([shelf_ isVisible]); [shelf_ add:item.get()]; EXPECT_EQ(0, shelf_.get()->scheduleAutoCloseCount_); @@ -386,24 +376,16 @@ shelf_.reset(); } -// The view should not be hidden when the shelf is shown. -// The view should be hidden after the closing animation. -// Failing flakily on Mac 10.9, see: crbug.com/687447. -TEST_F(DownloadShelfControllerTest, DISABLED_ViewVisibility) { - [shelf_ showDownloadShelf:YES isUserAction:NO]; +// The view should not be hidden when the shelf is open. +// The view should be hidden when the shelf is closed. +TEST_F(DownloadShelfControllerTest, ViewVisibility) { + [shelf_ showDownloadShelf:YES isUserAction:NO animate:NO]; EXPECT_FALSE([[shelf_ view] isHidden]); - base::RunLoop run_loop; - base::RunLoop* const run_loop_ptr = &run_loop; - - [shelf_ setCloseAnimationHandler:^{ - run_loop_ptr->Quit(); - }]; - [shelf_ showDownloadShelf:NO isUserAction:NO]; - run_loop.Run(); + [shelf_ showDownloadShelf:NO isUserAction:NO animate:NO]; EXPECT_TRUE([[shelf_ view] isHidden]); - [shelf_ showDownloadShelf:YES isUserAction:NO]; + [shelf_ showDownloadShelf:YES isUserAction:NO animate:NO]; EXPECT_FALSE([[shelf_ view] isHidden]); }
diff --git a/chrome/browser/ui/cocoa/download/download_shelf_mac.h b/chrome/browser/ui/cocoa/download/download_shelf_mac.h index 11a631db..2d78a595 100644 --- a/chrome/browser/ui/cocoa/download/download_shelf_mac.h +++ b/chrome/browser/ui/cocoa/download/download_shelf_mac.h
@@ -26,8 +26,10 @@ protected: void DoAddDownload(content::DownloadItem* download) override; - void DoShow() override; + void DoOpen() override; void DoClose(CloseReason reason) override; + void DoHide() override; + void DoUnhide() override; private: // The browser that owns this shelf.
diff --git a/chrome/browser/ui/cocoa/download/download_shelf_mac.mm b/chrome/browser/ui/cocoa/download/download_shelf_mac.mm index cf14be7..35ca1d3 100644 --- a/chrome/browser/ui/cocoa/download/download_shelf_mac.mm +++ b/chrome/browser/ui/cocoa/download/download_shelf_mac.mm
@@ -28,18 +28,28 @@ return false; } -void DownloadShelfMac::DoShow() { - [shelf_controller_ showDownloadShelf:YES - isUserAction:NO]; +void DownloadShelfMac::DoOpen() { + [shelf_controller_ showDownloadShelf:YES isUserAction:NO animate:YES]; browser_->UpdateDownloadShelfVisibility(true); } void DownloadShelfMac::DoClose(CloseReason reason) { [shelf_controller_ showDownloadShelf:NO - isUserAction:reason == USER_ACTION]; + isUserAction:reason == USER_ACTION + animate:YES]; browser_->UpdateDownloadShelfVisibility(false); } +void DownloadShelfMac::DoHide() { + [shelf_controller_ showDownloadShelf:NO isUserAction:NO animate:NO]; + browser_->UpdateDownloadShelfVisibility(false); +} + +void DownloadShelfMac::DoUnhide() { + [shelf_controller_ showDownloadShelf:YES isUserAction:NO animate:NO]; + browser_->UpdateDownloadShelfVisibility(true); +} + Browser* DownloadShelfMac::browser() const { return browser_; }
diff --git a/chrome/browser/ui/cocoa/download/download_shelf_mac_unittest.mm b/chrome/browser/ui/cocoa/download/download_shelf_mac_unittest.mm index b68ba95..d7a99e9 100644 --- a/chrome/browser/ui/cocoa/download/download_shelf_mac_unittest.mm +++ b/chrome/browser/ui/cocoa/download/download_shelf_mac_unittest.mm
@@ -23,7 +23,8 @@ - (BOOL)isVisible; - (void)showDownloadShelf:(BOOL)enable - isUserAction:(BOOL)isUserAction; + isUserAction:(BOOL)isUserAction + animate:(BOOL)animate; @end @implementation FakeDownloadShelfController @@ -34,7 +35,8 @@ } - (void)showDownloadShelf:(BOOL)enable - isUserAction:(BOOL)isUserAction { + isUserAction:(BOOL)isUserAction + animate:(BOOL)animate { if (enable) ++callCountShow; else @@ -69,7 +71,7 @@ DownloadShelfMac shelf(browser(), (DownloadShelfController*)shelf_controller_.get()); EXPECT_EQ(0, shelf_controller_.get()->callCountShow); - shelf.Show(); + shelf.Open(); EXPECT_EQ(1, shelf_controller_.get()->callCountShow); }
diff --git a/chrome/browser/ui/cocoa/tab_contents/OWNERS b/chrome/browser/ui/cocoa/tab_contents/OWNERS index c16f00c..d67ec98 100644 --- a/chrome/browser/ui/cocoa/tab_contents/OWNERS +++ b/chrome/browser/ui/cocoa/tab_contents/OWNERS
@@ -1,3 +1,5 @@ avi@chromium.org miu@chromium.org thakis@chromium.org + +# COMPONENT: UI>Browser>TabContents
diff --git a/chrome/browser/ui/cocoa/tabs/OWNERS b/chrome/browser/ui/cocoa/tabs/OWNERS index 0021790..5edf558 100644 --- a/chrome/browser/ui/cocoa/tabs/OWNERS +++ b/chrome/browser/ui/cocoa/tabs/OWNERS
@@ -3,3 +3,5 @@ # For changes related to the tab alert indicator/button. miu@chromium.org + +# COMPONENT: UI>Browser>TabStrip
diff --git a/chrome/browser/ui/cocoa/view_id_util_browsertest.mm b/chrome/browser/ui/cocoa/view_id_util_browsertest.mm index b935b4c..dd26af6 100644 --- a/chrome/browser/ui/cocoa/view_id_util_browsertest.mm +++ b/chrome/browser/ui/cocoa/view_id_util_browsertest.mm
@@ -52,7 +52,7 @@ DevToolsWindowTesting::OpenDevToolsWindowSync(browser(), true); // Make sure download shelf is created to test VIEW_ID_DOWNLOAD_SHELF - browser()->window()->GetDownloadShelf()->Show(); + browser()->window()->GetDownloadShelf()->Open(); // Create a bookmark to test VIEW_ID_BOOKMARK_BAR_ELEMENT BookmarkModel* bookmark_model =
diff --git a/chrome/browser/ui/exclusive_access/OWNERS b/chrome/browser/ui/exclusive_access/OWNERS index 35e2632..192ee8f 100644 --- a/chrome/browser/ui/exclusive_access/OWNERS +++ b/chrome/browser/ui/exclusive_access/OWNERS
@@ -1,3 +1,5 @@ mgiuca@chromium.org miu@chromium.org scheib@chromium.org + +# COMPONENT: UI>Browser>FullScreen
diff --git a/chrome/browser/ui/exclusive_access/fullscreen_controller.cc b/chrome/browser/ui/exclusive_access/fullscreen_controller.cc index 04d2a6de..ca73d98 100644 --- a/chrome/browser/ui/exclusive_access/fullscreen_controller.cc +++ b/chrome/browser/ui/exclusive_access/fullscreen_controller.cc
@@ -238,6 +238,16 @@ ExclusiveAccessControllerBase::OnTabClosing(web_contents); } +void FullscreenController::WindowFullscreenStateWillChange() { + ExclusiveAccessContext* exclusive_access_context = + exclusive_access_manager()->context(); + if (exclusive_access_context->IsFullscreen()) { + exclusive_access_context->HideDownloadShelf(); + } else { + exclusive_access_context->UnhideDownloadShelf(); + } +} + void FullscreenController::WindowFullscreenStateChanged() { reentrant_window_state_change_call_check_ = true; ExclusiveAccessContext* const exclusive_access_context = @@ -249,9 +259,6 @@ toggled_into_fullscreen_ = false; extension_caused_fullscreen_ = GURL(); NotifyTabExclusiveAccessLost(); - exclusive_access_context->UnhideDownloadShelf(); - } else { - exclusive_access_context->HideDownloadShelf(); } }
diff --git a/chrome/browser/ui/exclusive_access/fullscreen_controller.h b/chrome/browser/ui/exclusive_access/fullscreen_controller.h index 0a234b28..58ce24b 100644 --- a/chrome/browser/ui/exclusive_access/fullscreen_controller.h +++ b/chrome/browser/ui/exclusive_access/fullscreen_controller.h
@@ -123,6 +123,9 @@ void ExitExclusiveAccessIfNecessary() override; // Callbacks ///////////////////////////////////////////////////////////////// + // Called by Browser::WindowFullscreenStateWillChange. + void WindowFullscreenStateWillChange(); + // Called by Browser::WindowFullscreenStateChanged. void WindowFullscreenStateChanged();
diff --git a/chrome/browser/ui/tabs/OWNERS b/chrome/browser/ui/tabs/OWNERS index a4ef29a..f933a2a 100644 --- a/chrome/browser/ui/tabs/OWNERS +++ b/chrome/browser/ui/tabs/OWNERS
@@ -2,3 +2,5 @@ # For changes related to the tab alert indicators. per-file tab_utils*=miu@chromium.org + +# COMPONENT: UI>Browser>TabStrip
diff --git a/chrome/browser/ui/views/download/download_shelf_view.cc b/chrome/browser/ui/views/download/download_shelf_view.cc index 1e119e9..23b3297 100644 --- a/chrome/browser/ui/views/download/download_shelf_view.cc +++ b/chrome/browser/ui/views/download/download_shelf_view.cc
@@ -367,7 +367,7 @@ return shelf_animation_.IsClosing(); } -void DownloadShelfView::DoShow() { +void DownloadShelfView::DoOpen() { SetVisible(true); shelf_animation_.Show(); } @@ -384,6 +384,18 @@ shelf_animation_.Hide(); } +void DownloadShelfView::DoHide() { + SetVisible(false); + parent_->ToolbarSizeChanged(false); + parent_->SetDownloadShelfVisible(false); +} + +void DownloadShelfView::DoUnhide() { + SetVisible(true); + parent_->ToolbarSizeChanged(true); + parent_->SetDownloadShelfVisible(true); +} + Browser* DownloadShelfView::browser() const { return browser_; }
diff --git a/chrome/browser/ui/views/download/download_shelf_view.h b/chrome/browser/ui/views/download/download_shelf_view.h index 6da340f..5bbec13d 100644 --- a/chrome/browser/ui/views/download/download_shelf_view.h +++ b/chrome/browser/ui/views/download/download_shelf_view.h
@@ -96,8 +96,10 @@ protected: // Implementation of DownloadShelf. void DoAddDownload(content::DownloadItem* download) override; - void DoShow() override; + void DoOpen() override; void DoClose(CloseReason reason) override; + void DoHide() override; + void DoUnhide() override; // From AccessiblePaneView views::View* GetDefaultFocusableChild() override;
diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc index d0efcd36..a58f71b0 100644 --- a/chrome/browser/ui/views/frame/browser_view.cc +++ b/chrome/browser/ui/views/frame/browser_view.cc
@@ -2319,6 +2319,7 @@ if (ShouldUseImmersiveFullscreenForUrl(url)) immersive_mode_controller_->SetEnabled(fullscreen); + browser_->WindowFullscreenStateWillChange(); browser_->WindowFullscreenStateChanged(); if (fullscreen && !chrome::IsRunningInAppMode()) {
diff --git a/chrome/browser/ui/views/payments/credit_card_editor_view_controller.cc b/chrome/browser/ui/views/payments/credit_card_editor_view_controller.cc index d165ab2..6504936 100644 --- a/chrome/browser/ui/views/payments/credit_card_editor_view_controller.cc +++ b/chrome/browser/ui/views/payments/credit_card_editor_view_controller.cc
@@ -12,10 +12,12 @@ #include "base/strings/utf_string_conversions.h" #include "base/time/time.h" #include "chrome/browser/ui/views/payments/payment_request_dialog_view.h" +#include "chrome/browser/ui/views/payments/payment_request_views_util.h" #include "chrome/browser/ui/views/payments/preselected_combobox_model.h" #include "chrome/browser/ui/views/payments/validating_combobox.h" #include "chrome/browser/ui/views/payments/validating_textfield.h" #include "chrome/grit/generated_resources.h" +#include "components/autofill/core/browser/autofill_data_util.h" #include "components/autofill/core/browser/autofill_type.h" #include "components/autofill/core/browser/credit_card.h" #include "components/autofill/core/browser/field_types.h" @@ -23,8 +25,14 @@ #include "components/autofill/core/common/autofill_clock.h" #include "components/autofill/core/common/autofill_constants.h" #include "components/payments/payment_request.h" +#include "components/strings/grit/components_strings.h" #include "ui/base/l10n/l10n_util.h" +#include "ui/native_theme/native_theme.h" +#include "ui/views/controls/image_view.h" +#include "ui/views/controls/label.h" #include "ui/views/controls/textfield/textfield.h" +#include "ui/views/layout/box_layout.h" +#include "ui/views/view.h" namespace payments { @@ -73,6 +81,59 @@ CreditCardEditorViewController::~CreditCardEditorViewController() {} +// Creates the "Cards accepted" view with a row of icons at the top of the +// credit card editor. +// +----------------------------------------------+ +// | Cards Accepted | +// | | +// | | VISA | | MC | | AMEX | | +// +----------------------------------------------+ +std::unique_ptr<views::View> +CreditCardEditorViewController::CreateHeaderView() { + std::unique_ptr<views::View> view = base::MakeUnique<views::View>(); + + // 9dp is required between the first and second row. + constexpr int kRowVerticalInset = 9; + views::BoxLayout* layout = new views::BoxLayout( + views::BoxLayout::kVertical, payments::kPaymentRequestRowHorizontalInsets, + payments::kPaymentRequestRowVerticalInsets, kRowVerticalInset); + layout->set_main_axis_alignment(views::BoxLayout::MAIN_AXIS_ALIGNMENT_START); + layout->set_cross_axis_alignment( + views::BoxLayout::CROSS_AXIS_ALIGNMENT_START); + view->SetLayoutManager(layout); + + // "Cards accepted" label is "disabled" grey. + std::unique_ptr<views::Label> label = base::MakeUnique<views::Label>( + l10n_util::GetStringUTF16(IDS_PAYMENTS_ACCEPTED_CARDS_LABEL)); + label->SetDisabledColor(label->GetNativeTheme()->GetSystemColor( + ui::NativeTheme::kColorId_LabelDisabledColor)); + label->SetEnabled(false); + view->AddChildView(label.release()); + + // 8dp padding is required between icons. + constexpr int kPaddingBetweenCardIcons = 8; + std::unique_ptr<views::View> icons_row = base::MakeUnique<views::View>(); + views::BoxLayout* icons_layout = new views::BoxLayout( + views::BoxLayout::kHorizontal, 0, 0, kPaddingBetweenCardIcons); + icons_row->SetLayoutManager(icons_layout); + + constexpr gfx::Size kCardIconSize = gfx::Size(30, 18); + for (const std::string& supported_network : + request()->supported_card_networks()) { + const std::string autofill_card_type = + autofill::data_util::GetCardTypeForBasicCardPaymentType( + supported_network); + std::unique_ptr<views::ImageView> card_icon_view = + CreateCardIconView(autofill_card_type); + card_icon_view->SetImageSize(kCardIconSize); + + icons_row->AddChildView(card_icon_view.release()); + } + view->AddChildView(icons_row.release()); + + return view; +} + std::vector<EditorField> CreditCardEditorViewController::GetFieldDefinitions() { return std::vector<EditorField>{ {autofill::CREDIT_CARD_NAME_FULL,
diff --git a/chrome/browser/ui/views/payments/credit_card_editor_view_controller.h b/chrome/browser/ui/views/payments/credit_card_editor_view_controller.h index 40420f2..4ea2ef7 100644 --- a/chrome/browser/ui/views/payments/credit_card_editor_view_controller.h +++ b/chrome/browser/ui/views/payments/credit_card_editor_view_controller.h
@@ -24,6 +24,7 @@ ~CreditCardEditorViewController() override; // EditorViewController: + std::unique_ptr<views::View> CreateHeaderView() override; std::vector<EditorField> GetFieldDefinitions() override; bool ValidateModelAndSave() override; std::unique_ptr<ValidationDelegate> CreateValidationDelegate(
diff --git a/chrome/browser/ui/views/payments/editor_view_controller.cc b/chrome/browser/ui/views/payments/editor_view_controller.cc index 239a04f..38eeee77 100644 --- a/chrome/browser/ui/views/payments/editor_view_controller.cc +++ b/chrome/browser/ui/views/payments/editor_view_controller.cc
@@ -61,6 +61,8 @@ views::BoxLayout::CROSS_AXIS_ALIGNMENT_STRETCH); content_view->SetLayoutManager(layout); + content_view->AddChildView(CreateHeaderView().release()); + // Create an input label/textfield for each field definition. std::vector<EditorField> fields = GetFieldDefinitions(); for (const auto& field : fields) {
diff --git a/chrome/browser/ui/views/payments/editor_view_controller.h b/chrome/browser/ui/views/payments/editor_view_controller.h index c5851c8..09ab46d9 100644 --- a/chrome/browser/ui/views/payments/editor_view_controller.h +++ b/chrome/browser/ui/views/payments/editor_view_controller.h
@@ -18,6 +18,7 @@ #include "ui/views/controls/button/vector_icon_button_delegate.h" #include "ui/views/controls/combobox/combobox_listener.h" #include "ui/views/controls/textfield/textfield_controller.h" +#include "ui/views/view.h" namespace ui { class ComboboxModel; @@ -82,6 +83,7 @@ // PaymentRequestSheetController: std::unique_ptr<views::View> CreateView() override; + virtual std::unique_ptr<views::View> CreateHeaderView() = 0; // Returns the field definitions used to build the UI. virtual std::vector<EditorField> GetFieldDefinitions() = 0; // Validates the data entered and attempts to save; returns true on success.
diff --git a/chrome/browser/ui/views/payments/payment_request_credit_card_editor_interactive_uitest.cc b/chrome/browser/ui/views/payments/payment_request_credit_card_editor_interactive_uitest.cc index ac01aa1..3e7b5f3 100644 --- a/chrome/browser/ui/views/payments/payment_request_credit_card_editor_interactive_uitest.cc +++ b/chrome/browser/ui/views/payments/payment_request_credit_card_editor_interactive_uitest.cc
@@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include <vector> + #include "base/macros.h" #include "base/strings/utf_string_conversions.h" #include "base/time/time.h" @@ -13,6 +15,7 @@ #include "components/autofill/core/browser/personal_data_manager_observer.h" #include "components/autofill/core/browser/test_autofill_clock.h" #include "components/payments/payment_request.h" +#include "content/public/test/browser_test_utils.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -176,4 +179,144 @@ EXPECT_TRUE(textfield->invalid()); } +class PaymentRequestCreditCardBasicCardTest + : public PaymentRequestInteractiveTestBase { + protected: + PaymentRequestCreditCardBasicCardTest() + : PaymentRequestInteractiveTestBase( + "/payment_request_basic_card_test.html") {} + + void InvokePaymentRequestWithJs(const std::string& js) { + ResetEventObserver(DialogEvent::DIALOG_OPENED); + + ASSERT_TRUE(content::ExecuteScript(GetActiveWebContents(), js)); + + WaitForObservedEvent(); + } + + private: + DISALLOW_COPY_AND_ASSIGN(PaymentRequestCreditCardBasicCardTest); +}; + +// One network is specified in 'basic-card' data, one in supportedMethods. +IN_PROC_BROWSER_TEST_F(PaymentRequestCreditCardBasicCardTest, + BasicCard_NetworksSpecified) { + InvokePaymentRequestWithJs("buy();"); + + std::vector<PaymentRequest*> requests = + GetPaymentRequests(GetActiveWebContents()); + EXPECT_EQ(1u, requests.size()); + std::vector<std::string> supported_card_networks = + requests[0]->supported_card_networks(); + EXPECT_EQ(2u, supported_card_networks.size()); + // The networks appear in the order in which they were specified by the + // merchant. + EXPECT_EQ("mastercard", supported_card_networks[0]); + EXPECT_EQ("visa", supported_card_networks[1]); +} + +// Only specifying 'basic-card' with no supportedNetworks means all networks are +// supported. +IN_PROC_BROWSER_TEST_F(PaymentRequestCreditCardBasicCardTest, + BasicCard_NoNetworksSpecified) { + InvokePaymentRequestWithJs("buyBasicCard();"); + + std::vector<PaymentRequest*> requests = + GetPaymentRequests(GetActiveWebContents()); + EXPECT_EQ(1u, requests.size()); + std::vector<std::string> supported_card_networks = + requests[0]->supported_card_networks(); + // The default ordering is alphabetical. + EXPECT_EQ(8u, supported_card_networks.size()); + EXPECT_EQ("amex", supported_card_networks[0]); + EXPECT_EQ("diners", supported_card_networks[1]); + EXPECT_EQ("discover", supported_card_networks[2]); + EXPECT_EQ("jcb", supported_card_networks[3]); + EXPECT_EQ("mastercard", supported_card_networks[4]); + EXPECT_EQ("mir", supported_card_networks[5]); + EXPECT_EQ("unionpay", supported_card_networks[6]); + EXPECT_EQ("visa", supported_card_networks[7]); +} + +// Specifying 'basic-card' after having explicitely included a network yields +// the expected order when in different supportedMethods lists. +IN_PROC_BROWSER_TEST_F(PaymentRequestCreditCardBasicCardTest, + BasicCard_NetworkThenBasicCard_DifferentList) { + InvokePaymentRequestWithJs( + "buyHelper([{" + " supportedMethods: ['mastercard']," + "}, {" + " supportedMethods: ['basic-card']" + "}]);"); + + std::vector<PaymentRequest*> requests = + GetPaymentRequests(GetActiveWebContents()); + EXPECT_EQ(1u, requests.size()); + std::vector<std::string> supported_card_networks = + requests[0]->supported_card_networks(); + // 'mastercard' is first because it was explicitely specified first. The rest + // is alphabetical. + EXPECT_EQ(8u, supported_card_networks.size()); + EXPECT_EQ("mastercard", supported_card_networks[0]); + EXPECT_EQ("amex", supported_card_networks[1]); + EXPECT_EQ("diners", supported_card_networks[2]); + EXPECT_EQ("discover", supported_card_networks[3]); + EXPECT_EQ("jcb", supported_card_networks[4]); + EXPECT_EQ("mir", supported_card_networks[5]); + EXPECT_EQ("unionpay", supported_card_networks[6]); + EXPECT_EQ("visa", supported_card_networks[7]); +} + +// Specifying 'basic-card' after having explicitely included a network yields +// the expected order when in the same supportedMethods list. +IN_PROC_BROWSER_TEST_F(PaymentRequestCreditCardBasicCardTest, + BasicCard_NetworkThenBasicCard_SameList) { + InvokePaymentRequestWithJs( + "buyHelper([{" + " supportedMethods: ['visa', 'basic-card']" + "}]);"); + + std::vector<PaymentRequest*> requests = + GetPaymentRequests(GetActiveWebContents()); + EXPECT_EQ(1u, requests.size()); + std::vector<std::string> supported_card_networks = + requests[0]->supported_card_networks(); + // 'visa' is first because it was explicitely specified first. The rest + // is alphabetical. + EXPECT_EQ(8u, supported_card_networks.size()); + EXPECT_EQ("visa", supported_card_networks[0]); + EXPECT_EQ("amex", supported_card_networks[1]); + EXPECT_EQ("diners", supported_card_networks[2]); + EXPECT_EQ("discover", supported_card_networks[3]); + EXPECT_EQ("jcb", supported_card_networks[4]); + EXPECT_EQ("mastercard", supported_card_networks[5]); + EXPECT_EQ("mir", supported_card_networks[6]); + EXPECT_EQ("unionpay", supported_card_networks[7]); +} + +// Specifying 'basic-card' with some networks after having explicitely included +// the same networks does not yield duplicates and has the expected order. +IN_PROC_BROWSER_TEST_F(PaymentRequestCreditCardBasicCardTest, + BasicCard_NetworkThenBasicCardWithSameNetwork) { + InvokePaymentRequestWithJs( + "buyHelper([{" + " supportedMethods: ['mastercard', 'visa']" + "}, {" + " supportedMethods: ['basic-card']," + " data: {" + " supportedNetworks: ['visa', 'mastercard', 'jcb']," + " }" + "}]);"); + + std::vector<PaymentRequest*> requests = + GetPaymentRequests(GetActiveWebContents()); + EXPECT_EQ(1u, requests.size()); + std::vector<std::string> supported_card_networks = + requests[0]->supported_card_networks(); + EXPECT_EQ(3u, supported_card_networks.size()); + EXPECT_EQ("mastercard", supported_card_networks[0]); + EXPECT_EQ("visa", supported_card_networks[1]); + EXPECT_EQ("jcb", supported_card_networks[2]); +} + } // namespace payments
diff --git a/chrome/browser/ui/views/payments/payment_request_views_util.cc b/chrome/browser/ui/views/payments/payment_request_views_util.cc index 21e5fa1..74e5b02 100644 --- a/chrome/browser/ui/views/payments/payment_request_views_util.cc +++ b/chrome/browser/ui/views/payments/payment_request_views_util.cc
@@ -10,10 +10,13 @@ #include "base/memory/ptr_util.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/ui/views/payments/payment_request_sheet_controller.h" +#include "components/autofill/core/browser/autofill_data_util.h" #include "components/autofill/core/browser/autofill_profile.h" #include "components/autofill/core/browser/autofill_type.h" +#include "components/autofill/core/browser/credit_card.h" #include "components/autofill/core/browser/field_types.h" #include "third_party/skia/include/core/SkColor.h" +#include "ui/base/resource/resource_bundle.h" #include "ui/gfx/canvas.h" #include "ui/gfx/geometry/insets.h" #include "ui/gfx/geometry/point_f.h" @@ -23,6 +26,7 @@ #include "ui/views/bubble/bubble_frame_view.h" #include "ui/views/controls/button/button.h" #include "ui/views/controls/button/vector_icon_button.h" +#include "ui/views/controls/image_view.h" #include "ui/views/controls/label.h" #include "ui/views/controls/styled_label.h" #include "ui/views/layout/grid_layout.h" @@ -114,6 +118,24 @@ return container; } +std::unique_ptr<views::ImageView> CreateCardIconView( + const std::string& card_type) { + std::unique_ptr<views::ImageView> card_icon_view = + base::MakeUnique<views::ImageView>(); + card_icon_view->set_interactive(false); + card_icon_view->SetImage( + ResourceBundle::GetSharedInstance() + .GetImageNamed(autofill::data_util::GetPaymentRequestData(card_type) + .icon_resource_id) + .AsImageSkia()); + card_icon_view->SetTooltipText( + autofill::CreditCard::TypeForDisplay(card_type)); + card_icon_view->SetBorder(views::CreateRoundedRectBorder( + 1, 3, card_icon_view->GetNativeTheme()->GetSystemColor( + ui::NativeTheme::kColorId_UnfocusedBorderColor))); + return card_icon_view; +} + std::unique_ptr<views::View> GetShippingAddressLabel( AddressStyleType type, const std::string& locale,
diff --git a/chrome/browser/ui/views/payments/payment_request_views_util.h b/chrome/browser/ui/views/payments/payment_request_views_util.h index de9c6a3bf..016e9c7 100644 --- a/chrome/browser/ui/views/payments/payment_request_views_util.h +++ b/chrome/browser/ui/views/payments/payment_request_views_util.h
@@ -16,6 +16,7 @@ namespace views { class Border; +class ImageView; class VectorIconButtonDelegate; class View; } @@ -49,6 +50,11 @@ const base::string16& title, views::VectorIconButtonDelegate* delegate); +// Returns a card image view for the given |card_type|. Includes a rounded rect +// border. Callers need to set the size of the resulting ImageView. +std::unique_ptr<views::ImageView> CreateCardIconView( + const std::string& card_type); + // Represents formatting options for each of the different contexts in which an // Address label may be displayed. enum class AddressStyleType { SUMMARY, DETAILED };
diff --git a/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc b/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc index 95fc1af..21129d6 100644 --- a/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc +++ b/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc
@@ -29,12 +29,10 @@ #include "components/strings/grit/components_strings.h" #include "content/public/browser/web_contents.h" #include "ui/base/l10n/l10n_util.h" -#include "ui/base/resource/resource_bundle.h" #include "ui/gfx/color_utils.h" #include "ui/gfx/font.h" #include "ui/gfx/paint_vector_icon.h" #include "ui/gfx/range/range.h" -#include "ui/views/border.h" #include "ui/views/controls/button/label_button.h" #include "ui/views/controls/button/md_text_button.h" #include "ui/views/controls/image_view.h" @@ -325,18 +323,8 @@ autofill::AutofillType(autofill::CREDIT_CARD_NAME_FULL), g_browser_process->GetApplicationLocale()))); - card_icon_view = base::MakeUnique<views::ImageView>(); - card_icon_view->set_interactive(false); - card_icon_view->SetImage( - ResourceBundle::GetSharedInstance() - .GetImageNamed(autofill::data_util::GetPaymentRequestData( - selected_card->type()).icon_resource_id) - .AsImageSkia()); - card_icon_view->SetBorder( - views::CreateRoundedRectBorder(1, 3, SK_ColorLTGRAY)); - - constexpr gfx::Size kCardIconSize = gfx::Size(32, 20); - card_icon_view->SetImageSize(kCardIconSize); + card_icon_view = CreateCardIconView(selected_card->type()); + card_icon_view->SetImageSize(gfx::Size(32, 20)); } std::unique_ptr<views::Button> section = CreatePaymentSheetRow(
diff --git a/chrome/browser/ui/webui/options/certificate_manager_browsertest.cc b/chrome/browser/ui/webui/options/certificate_manager_browsertest.cc index c9e1308..3d1545b 100644 --- a/chrome/browser/ui/webui/options/certificate_manager_browsertest.cc +++ b/chrome/browser/ui/webui/options/certificate_manager_browsertest.cc
@@ -35,6 +35,7 @@ protected: void SetUpInProcessBrowserTestFixture() override { + options::OptionsUIBrowserTest::SetUpInProcessBrowserTestFixture(); #if defined(OS_CHROMEOS) device_policy_test_helper_.MarkAsEnterpriseOwned(); #endif
diff --git a/chrome/browser/ui/webui/options/language_dictionary_interactive_uitest.cc b/chrome/browser/ui/webui/options/language_dictionary_interactive_uitest.cc index fb09683..dbdad4f2 100644 --- a/chrome/browser/ui/webui/options/language_dictionary_interactive_uitest.cc +++ b/chrome/browser/ui/webui/options/language_dictionary_interactive_uitest.cc
@@ -4,11 +4,13 @@ #include "base/macros.h" #include "base/strings/stringprintf.h" +#include "base/test/scoped_feature_list.h" #include "build/build_config.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/chrome_pages.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" +#include "chrome/common/chrome_features.h" #include "chrome/common/url_constants.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/interactive_test_utils.h" @@ -25,6 +27,8 @@ // Navigate to the editDictionary page. void SetUpOnMainThread() override { + disable_md_settings_.InitAndDisableFeature( + features::kMaterialDesignSettings); const GURL url = chrome::GetSettingsUrl("editDictionary"); ui_test_utils::NavigateToURL(browser(), url); } @@ -177,6 +181,7 @@ private: std::unique_ptr<content::DOMMessageQueue> dom_message_queue_; + base::test::ScopedFeatureList disable_md_settings_; DISALLOW_COPY_AND_ASSIGN(LanguageDictionaryWebUITest); };
diff --git a/chrome/browser/ui/webui/options/language_options_interactive_uitest.cc b/chrome/browser/ui/webui/options/language_options_interactive_uitest.cc index 394e071..e9fa0e27 100644 --- a/chrome/browser/ui/webui/options/language_options_interactive_uitest.cc +++ b/chrome/browser/ui/webui/options/language_options_interactive_uitest.cc
@@ -3,11 +3,13 @@ // found in the LICENSE file. #include "base/macros.h" +#include "base/test/scoped_feature_list.h" #include "build/build_config.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/chrome_pages.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" +#include "chrome/common/chrome_features.h" #include "chrome/common/pref_names.h" #include "chrome/common/url_constants.h" #include "chrome/test/base/in_process_browser_test.h" @@ -30,6 +32,11 @@ public: LanguageOptionsWebUITest() {} + void SetUpInProcessBrowserTestFixture() override { + disable_md_settings_.InitAndDisableFeature( + features::kMaterialDesignSettings); + } + // This method will navigate to the language settings page and show // a subset of languages from the list of available languages. void SetUpOnMainThread() override { @@ -84,6 +91,8 @@ } private: + base::test::ScopedFeatureList disable_md_settings_; + DISALLOW_COPY_AND_ASSIGN(LanguageOptionsWebUITest); };
diff --git a/chrome/browser/ui/webui/options/options_ui_browsertest.cc b/chrome/browser/ui/webui/options/options_ui_browsertest.cc index 255cc61f..b375226 100644 --- a/chrome/browser/ui/webui/options/options_ui_browsertest.cc +++ b/chrome/browser/ui/webui/options/options_ui_browsertest.cc
@@ -16,6 +16,7 @@ #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/ui/webui/options/options_ui.h" #include "chrome/browser/ui/webui/uber/uber_ui.h" +#include "chrome/common/chrome_features.h" #include "chrome/common/url_constants.h" #include "chrome/grit/generated_resources.h" #include "chrome/test/base/ui_test_utils.h" @@ -107,6 +108,11 @@ OptionsUIBrowserTest::OptionsUIBrowserTest() { } +void OptionsUIBrowserTest::SetUpInProcessBrowserTestFixture() { + InProcessBrowserTest::SetUpInProcessBrowserTestFixture(); + disable_md_settings_.InitAndDisableFeature(features::kMaterialDesignSettings); +} + void OptionsUIBrowserTest::NavigateToSettings() { NavigateToSettingsSubpage(""); }
diff --git a/chrome/browser/ui/webui/options/options_ui_browsertest.h b/chrome/browser/ui/webui/options/options_ui_browsertest.h index aa75e2b..35b49b2 100644 --- a/chrome/browser/ui/webui/options/options_ui_browsertest.h +++ b/chrome/browser/ui/webui/options/options_ui_browsertest.h
@@ -8,6 +8,7 @@ #include <string> #include "base/macros.h" +#include "base/test/scoped_feature_list.h" #include "chrome/test/base/in_process_browser_test.h" namespace content { @@ -20,6 +21,8 @@ public: OptionsUIBrowserTest(); + void SetUpInProcessBrowserTestFixture() override; + // Navigate to the Uber/Settings page and block until it has loaded. void NavigateToSettings(); @@ -44,6 +47,8 @@ content::RenderFrameHost* GetSettingsFrame(); private: + base::test::ScopedFeatureList disable_md_settings_; + DISALLOW_COPY_AND_ASSIGN(OptionsUIBrowserTest); };
diff --git a/chrome/browser/ui/webui/settings/md_settings_ui.cc b/chrome/browser/ui/webui/settings/md_settings_ui.cc index 2cd4c0b..e5a9ae4 100644 --- a/chrome/browser/ui/webui/settings/md_settings_ui.cc +++ b/chrome/browser/ui/webui/settings/md_settings_ui.cc
@@ -190,20 +190,14 @@ // Add the metrics handler to write uma stats. web_ui->AddMessageHandler(base::MakeUnique<MetricsHandler>()); -#if BUILDFLAG(USE_VULCANIZE) - html_source->AddResourcePath("crisper.js", IDR_MD_SETTINGS_CRISPER_JS); - html_source->SetDefaultResource(IDR_MD_SETTINGS_VULCANIZED_HTML); - html_source->UseGzip(std::unordered_set<std::string>()); -#else // Add all settings resources. for (size_t i = 0; i < kSettingsResourcesSize; ++i) { html_source->AddResourcePath(kSettingsResources[i].name, kSettingsResources[i].value); } - html_source->SetDefaultResource(IDR_SETTINGS_SETTINGS_HTML); -#endif AddLocalizedStrings(html_source, profile); + html_source->SetDefaultResource(IDR_SETTINGS_SETTINGS_HTML); content::WebUIDataSource::Add(web_ui->GetWebContents()->GetBrowserContext(), html_source);
diff --git a/chrome/common/chrome_features.cc b/chrome/common/chrome_features.cc index 4f62bd8..ab7b093 100644 --- a/chrome/common/chrome_features.cc +++ b/chrome/common/chrome_features.cc
@@ -157,7 +157,7 @@ // Enables or disables the Material Design version of chrome://settings. // Also affects chrome://help. const base::Feature kMaterialDesignSettings{"MaterialDesignSettings", - base::FEATURE_DISABLED_BY_DEFAULT}; + base::FEATURE_ENABLED_BY_DEFAULT}; #if !defined(OS_ANDROID) && !defined(OS_IOS) // Enables media content bitstream remoting, an optimization that can activate
diff --git a/chrome/test/base/run_all_unittests.cc b/chrome/test/base/run_all_unittests.cc index 8536390..89f2415 100644 --- a/chrome/test/base/run_all_unittests.cc +++ b/chrome/test/base/run_all_unittests.cc
@@ -6,10 +6,15 @@ #include "base/command_line.h" #include "base/test/launcher/unit_test_launcher.h" #include "base/test/test_io_thread.h" +#include "build/build_config.h" #include "chrome/test/base/chrome_unit_test_suite.h" #include "content/public/test/unittest_test_suite.h" #include "mojo/edk/embedder/scoped_ipc_support.h" +#if defined(OS_WIN) +#include "chrome/install_static/test/scoped_install_details.h" +#endif + int main(int argc, char **argv) { content::UnitTestTestSuite test_suite(new ChromeUnitTestSuite(argc, argv)); @@ -18,6 +23,10 @@ test_io_thread.task_runner(), mojo::edk::ScopedIPCSupport::ShutdownPolicy::FAST); +#if defined(OS_WIN) + install_static::ScopedInstallDetails scoped_install_details; +#endif + return base::LaunchUnitTests( argc, argv, base::Bind(&content::UnitTestTestSuite::Run, base::Unretained(&test_suite)));
diff --git a/components/guest_view/renderer/guest_view_container.h b/components/guest_view/renderer/guest_view_container.h index e8f53d82..7025d95 100644 --- a/components/guest_view/renderer/guest_view_container.h +++ b/components/guest_view/renderer/guest_view_container.h
@@ -66,6 +66,7 @@ // BrowserPluginGuestDelegate public implementation. void SetElementInstanceID(int element_instance_id) final; void DidResizeElement(const gfx::Size& new_size) override; + base::WeakPtr<BrowserPluginDelegate> GetWeakPtr() final; protected: ~GuestViewContainer() override; @@ -89,7 +90,6 @@ // BrowserPluginDelegate implementation. void Ready() final; void DidDestroyElement() final; - base::WeakPtr<BrowserPluginDelegate> GetWeakPtr() final; int element_instance_id_; content::RenderFrame* render_frame_;
diff --git a/components/ntp_snippets/pref_names.cc b/components/ntp_snippets/pref_names.cc index b6e96c51..cd03e32 100644 --- a/components/ntp_snippets/pref_names.cc +++ b/components/ntp_snippets/pref_names.cc
@@ -17,6 +17,9 @@ const char kSnippetSoftFetchingIntervalOnUsageEvent[] = "ntp_snippets.soft_fetching_interval_on_usage_event"; +const char kSnippetSoftFetchingIntervalOnNtpOpened[] = + "ntp_snippets.soft_fetching_interval_on_ntp_opened"; + const char kSnippetPersistentFetchingIntervalWifi[] = "ntp_snippets.fetching_interval_wifi";
diff --git a/components/ntp_snippets/pref_names.h b/components/ntp_snippets/pref_names.h index 7ff783d..ee60486 100644 --- a/components/ntp_snippets/pref_names.h +++ b/components/ntp_snippets/pref_names.h
@@ -20,8 +20,11 @@ extern const char kSnippetLastFetchAttempt[]; // The pref name for the currently applied minimal interval between two // successive soft background fetches that react to user activity (such as -// opening an NTP). +// opening Chrome). extern const char kSnippetSoftFetchingIntervalOnUsageEvent[]; +// The pref name for the currently applied minimal interval between two +// successive soft brackground fetches when the New Tab Page is opened. +extern const char kSnippetSoftFetchingIntervalOnNtpOpened[]; // The pref name for the currently-scheduled background fetching interval when // there is WiFi connectivity.
diff --git a/components/ntp_snippets/remote/scheduling_remote_suggestions_provider.cc b/components/ntp_snippets/remote/scheduling_remote_suggestions_provider.cc index 614907b5..deb218a 100644 --- a/components/ntp_snippets/remote/scheduling_remote_suggestions_provider.cc +++ b/components/ntp_snippets/remote/scheduling_remote_suggestions_provider.cc
@@ -38,6 +38,7 @@ PERSISTENT_FALLBACK, PERSISTENT_WIFI, SOFT_ON_USAGE_EVENT, + SOFT_ON_NTP_OPENED, COUNT }; @@ -47,25 +48,30 @@ // The values of each array specify a default time interval for the intervals // defined by the enum FetchingInterval. The default time intervals defined in // the arrays can be overridden using different variation parameters. -const double kDefaultFetchingIntervalHoursRareNtpUser[] = {48.0, 24.0, 12.0}; -const double kDefaultFetchingIntervalHoursActiveNtpUser[] = {24.0, 6.0, 2.0}; +const double kDefaultFetchingIntervalHoursRareNtpUser[] = {48.0, 24.0, 12.0, + 6.0}; +const double kDefaultFetchingIntervalHoursActiveNtpUser[] = {24.0, 6.0, 2.0, + 2.0}; const double kDefaultFetchingIntervalHoursActiveSuggestionsConsumer[] = { - 24.0, 6.0, 2.0}; + 24.0, 6.0, 2.0, 1.0}; // Variation parameters than can be used to override the default fetching // intervals. const char* kFetchingIntervalParamNameRareNtpUser[] = { "fetching_interval_hours-fallback-rare_ntp_user", "fetching_interval_hours-wifi-rare_ntp_user", - "soft_fetching_interval_hours-active-rare_ntp_user"}; + "soft_fetching_interval_hours-active-rare_ntp_user", + "soft_on_ntp_opened_interval_hours-rare_ntp_user"}; const char* kFetchingIntervalParamNameActiveNtpUser[] = { "fetching_interval_hours-fallback-active_ntp_user", "fetching_interval_hours-wifi-active_ntp_user", - "soft_fetching_interval_hours-active-active_ntp_user"}; + "soft_fetching_interval_hours-active-active_ntp_user", + "soft_on_ntp_opened_interval_hours-active_ntp_user"}; const char* kFetchingIntervalParamNameActiveSuggestionsConsumer[] = { "fetching_interval_hours-fallback-active_suggestions_consumer", "fetching_interval_hours-wifi-active_suggestions_consumer", - "soft_fetching_interval_hours-active-active_suggestions_consumer"}; + "soft_fetching_interval_hours-active-active_suggestions_consumer", + "soft_on_ntp_opened_interval_hours-active_suggestions_consumer"}; static_assert( static_cast<unsigned int>(FetchingInterval::COUNT) == @@ -129,14 +135,15 @@ SchedulingRemoteSuggestionsProvider::FetchingSchedule SchedulingRemoteSuggestionsProvider::FetchingSchedule::Empty() { return FetchingSchedule{base::TimeDelta(), base::TimeDelta(), - base::TimeDelta()}; + base::TimeDelta(), base::TimeDelta()}; } bool SchedulingRemoteSuggestionsProvider::FetchingSchedule::operator==( const FetchingSchedule& other) const { return interval_persistent_wifi == other.interval_persistent_wifi && interval_persistent_fallback == other.interval_persistent_fallback && - interval_soft_on_usage_event == other.interval_soft_on_usage_event; + interval_soft_on_usage_event == other.interval_soft_on_usage_event && + interval_soft_on_ntp_opened == other.interval_soft_on_ntp_opened; } bool SchedulingRemoteSuggestionsProvider::FetchingSchedule::operator!=( @@ -147,7 +154,8 @@ bool SchedulingRemoteSuggestionsProvider::FetchingSchedule::is_empty() const { return interval_persistent_wifi.is_zero() && interval_persistent_fallback.is_zero() && - interval_soft_on_usage_event.is_zero(); + interval_soft_on_usage_event.is_zero() && + interval_soft_on_ntp_opened.is_zero(); } // The TriggerType enum specifies values for the events that can trigger @@ -203,6 +211,8 @@ registry->RegisterInt64Pref(prefs::kSnippetSoftFetchingIntervalOnUsageEvent, 0); registry->RegisterInt64Pref(prefs::kSnippetLastFetchAttempt, 0); + registry->RegisterInt64Pref(prefs::kSnippetSoftFetchingIntervalOnNtpOpened, + 0); } void SchedulingRemoteSuggestionsProvider::RescheduleFetching() { @@ -218,7 +228,7 @@ void SchedulingRemoteSuggestionsProvider::OnBrowserForegrounded() { // TODO(jkrcal): Consider that this is called whenever we open or return to an // Activity. Therefore, keep work light for fast start up calls. - if (!ShouldRefetchInTheBackgroundNow()) { + if (!ShouldRefetchInTheBackgroundNow(TriggerType::BROWSER_FOREGROUNDED)) { return; } @@ -228,7 +238,7 @@ void SchedulingRemoteSuggestionsProvider::OnBrowserColdStart() { // TODO(fhorschig|jkrcal): Consider that work here must be kept light for fast // cold start ups. - if (!ShouldRefetchInTheBackgroundNow()) { + if (!ShouldRefetchInTheBackgroundNow(TriggerType::BROWSER_COLD_START)) { return; } @@ -236,7 +246,7 @@ } void SchedulingRemoteSuggestionsProvider::OnNTPOpened() { - if (!ShouldRefetchInTheBackgroundNow()) { + if (!ShouldRefetchInTheBackgroundNow(TriggerType::NTP_OPENED)) { return; } @@ -394,6 +404,8 @@ FetchingInterval::PERSISTENT_FALLBACK, user_class); schedule.interval_soft_on_usage_event = GetDesiredFetchingInterval( FetchingInterval::SOFT_ON_USAGE_EVENT, user_class); + schedule.interval_soft_on_ntp_opened = GetDesiredFetchingInterval( + FetchingInterval::SOFT_ON_NTP_OPENED, user_class); return schedule; } @@ -406,6 +418,8 @@ prefs::kSnippetPersistentFetchingIntervalFallback)); schedule_.interval_soft_on_usage_event = base::TimeDelta::FromInternalValue( pref_service_->GetInt64(prefs::kSnippetSoftFetchingIntervalOnUsageEvent)); + schedule_.interval_soft_on_ntp_opened = base::TimeDelta::FromInternalValue( + pref_service_->GetInt64(prefs::kSnippetSoftFetchingIntervalOnNtpOpened)); } void SchedulingRemoteSuggestionsProvider::StoreFetchingSchedule() { @@ -417,6 +431,9 @@ pref_service_->SetInt64( prefs::kSnippetSoftFetchingIntervalOnUsageEvent, schedule_.interval_soft_on_usage_event.ToInternalValue()); + pref_service_->SetInt64( + prefs::kSnippetSoftFetchingIntervalOnNtpOpened, + schedule_.interval_soft_on_ntp_opened.ToInternalValue()); } void SchedulingRemoteSuggestionsProvider::RefetchInTheBackgroundIfEnabled( @@ -432,11 +449,26 @@ RefetchInTheBackground(/*callback=*/nullptr); } -bool SchedulingRemoteSuggestionsProvider::ShouldRefetchInTheBackgroundNow() { - base::Time first_allowed_fetch_time = - base::Time::FromInternalValue( - pref_service_->GetInt64(prefs::kSnippetLastFetchAttempt)) + - schedule_.interval_soft_on_usage_event; +bool SchedulingRemoteSuggestionsProvider::ShouldRefetchInTheBackgroundNow( + SchedulingRemoteSuggestionsProvider::TriggerType trigger) { + const base::Time last_fetch_attempt_time = base::Time::FromInternalValue( + pref_service_->GetInt64(prefs::kSnippetLastFetchAttempt)); + base::Time first_allowed_fetch_time; + switch (trigger) { + case TriggerType::NTP_OPENED: + first_allowed_fetch_time = + last_fetch_attempt_time + schedule_.interval_soft_on_ntp_opened; + break; + case TriggerType::BROWSER_FOREGROUNDED: + case TriggerType::BROWSER_COLD_START: + first_allowed_fetch_time = + last_fetch_attempt_time + schedule_.interval_soft_on_usage_event; + break; + case TriggerType::PERSISTENT_SCHEDULER_WAKE_UP: + case TriggerType::COUNT: + NOTREACHED(); + break; + } return first_allowed_fetch_time <= clock_->Now(); }
diff --git a/components/ntp_snippets/remote/scheduling_remote_suggestions_provider.h b/components/ntp_snippets/remote/scheduling_remote_suggestions_provider.h index 7a42b47..d0639cb 100644 --- a/components/ntp_snippets/remote/scheduling_remote_suggestions_provider.h +++ b/components/ntp_snippets/remote/scheduling_remote_suggestions_provider.h
@@ -114,6 +114,7 @@ base::TimeDelta interval_persistent_wifi; base::TimeDelta interval_persistent_fallback; base::TimeDelta interval_soft_on_usage_event; + base::TimeDelta interval_soft_on_ntp_opened; }; enum class TriggerType; @@ -137,7 +138,7 @@ // Checks whether it is time to perform a soft background fetch, according to // |schedule|. - bool ShouldRefetchInTheBackgroundNow(); + bool ShouldRefetchInTheBackgroundNow(TriggerType trigger); // Returns whether background fetching (for the given |trigger|) is disabled. bool BackgroundFetchesDisabled(TriggerType trigger) const;
diff --git a/components/ntp_snippets/remote/scheduling_remote_suggestions_provider_unittest.cc b/components/ntp_snippets/remote/scheduling_remote_suggestions_provider_unittest.cc index 950923f..0acb45c 100644 --- a/components/ntp_snippets/remote/scheduling_remote_suggestions_provider_unittest.cc +++ b/components/ntp_snippets/remote/scheduling_remote_suggestions_provider_unittest.cc
@@ -419,7 +419,7 @@ } TEST_F(SchedulingRemoteSuggestionsProviderTest, - ShouldFetchAgainOnNTPOpenedLaterAgain) { + ShouldFetchAgainOnBrowserForgroundLaterAgain) { RemoteSuggestionsProvider::FetchStatusCallback signal_fetch_done; { InSequence s; @@ -438,11 +438,11 @@ ChangeStatusOfUnderlyingProvider( RemoteSuggestionsProvider::ProviderStatus::ACTIVE); // Make the first soft fetch successful. - scheduling_provider_->OnNTPOpened(); + scheduling_provider_->OnBrowserForegrounded(); signal_fetch_done.Run(Status::Success()); // Open NTP again after 2hrs. test_clock_->Advance(base::TimeDelta::FromHours(2)); - scheduling_provider_->OnNTPOpened(); + scheduling_provider_->OnBrowserForegrounded(); } TEST_F(SchedulingRemoteSuggestionsProviderTest, @@ -586,4 +586,92 @@ RemoteSuggestionsProvider::ProviderStatus::ACTIVE); } +TEST_F(SchedulingRemoteSuggestionsProviderTest, + ReschedulesWhenOnNtpOpenedParamChanges) { + EXPECT_CALL(persistent_scheduler_, Schedule(_, _)).Times(2); + ChangeStatusOfUnderlyingProvider( + RemoteSuggestionsProvider::ProviderStatus::ACTIVE); + + // UserClassifier defaults to UserClass::ACTIVE_NTP_USER if PrefService is + // null. Change the fallback interval for this class. + SetVariationParameter("soft_on_ntp_opened_interval_hours-active_ntp_user", + "1.5"); + + // Schedule() should get called for the second time after params have changed. + ChangeStatusOfUnderlyingProvider( + RemoteSuggestionsProvider::ProviderStatus::ACTIVE); +} + +TEST_F(SchedulingRemoteSuggestionsProviderTest, + FetchIntervalForNtpOpenedTrigger) { + RemoteSuggestionsProvider::FetchStatusCallback signal_fetch_done; + { + InSequence s; + // Initial scheduling after being enabled. + EXPECT_CALL(persistent_scheduler_, Schedule(_, _)); + // The first call to NTPOpened results in a fetch. + EXPECT_CALL(*underlying_provider_, RefetchInTheBackground(_)) + .WillOnce(SaveArg<0>(&signal_fetch_done)); + // Rescheduling after a succesful fetch. + EXPECT_CALL(persistent_scheduler_, Schedule(_, _)); + // The third call to NTPOpened 35min later again results in a fetch. + EXPECT_CALL(*underlying_provider_, RefetchInTheBackground(_)); + } + + ChangeStatusOfUnderlyingProvider( + RemoteSuggestionsProvider::ProviderStatus::ACTIVE); + + scheduling_provider_->OnNTPOpened(); + signal_fetch_done.Run(Status::Success()); + + // UserClassifier defaults to UserClass::ACTIVE_NTP_USER which uses a 2h time + // interval by default for soft backgroudn fetches on ntp open events. + + // Open NTP again after 20min. This time no fetch is executed. + test_clock_->Advance(base::TimeDelta::FromMinutes(20)); + scheduling_provider_->OnNTPOpened(); + + // Open NTP again after 101min (121min since first opened). Since the default + // time interval has passed refetch again. + test_clock_->Advance(base::TimeDelta::FromMinutes(101)); + scheduling_provider_->OnNTPOpened(); +} + +TEST_F(SchedulingRemoteSuggestionsProviderTest, + OverrideFetchIntervalForNtpOpenedTrigger) { + // UserClassifier defaults to UserClass::ACTIVE_NTP_USER if PrefService is + // null. Change the on usage interval for this class from 2h to 30min. + SetVariationParameter("soft_on_ntp_opened_interval_hours-active_ntp_user", + "0.5"); + + RemoteSuggestionsProvider::FetchStatusCallback signal_fetch_done; + { + InSequence s; + // Initial scheduling after being enabled. + EXPECT_CALL(persistent_scheduler_, Schedule(_, _)); + // The first call to NTPOpened results in a fetch. + EXPECT_CALL(*underlying_provider_, RefetchInTheBackground(_)) + .WillOnce(SaveArg<0>(&signal_fetch_done)); + // Rescheduling after a succesful fetch. + EXPECT_CALL(persistent_scheduler_, Schedule(_, _)); + // The third call to NTPOpened 35min later again results in a fetch. + EXPECT_CALL(*underlying_provider_, RefetchInTheBackground(_)); + } + + ChangeStatusOfUnderlyingProvider( + RemoteSuggestionsProvider::ProviderStatus::ACTIVE); + + scheduling_provider_->OnNTPOpened(); + signal_fetch_done.Run(Status::Success()); + + // Open NTP again after 20min. No fetch request is issues since the 30 min + // time interval has not passed yet. + test_clock_->Advance(base::TimeDelta::FromMinutes(20)); + scheduling_provider_->OnNTPOpened(); + + // Open NTP again after 15min (35min since first opened) + test_clock_->Advance(base::TimeDelta::FromMinutes(15)); + scheduling_provider_->OnNTPOpened(); +} + } // namespace ntp_snippets
diff --git a/components/payments/payment_request.cc b/components/payments/payment_request.cc index fd2fc4f5..9ea28a8 100644 --- a/components/payments/payment_request.cc +++ b/components/payments/payment_request.cc
@@ -10,8 +10,17 @@ #include "content/public/browser/browser_thread.h" #include "content/public/browser/web_contents.h" +using payments::mojom::BasicCardNetwork; + namespace payments { +namespace { + +// Identifier for the basic card payment method in the PaymentMethodData. +const char* const kBasicCardMethodName = "basic-card"; + +} // namespace + PaymentRequest::PaymentRequest( content::WebContents* web_contents, std::unique_ptr<PaymentRequestDelegate> delegate, @@ -37,7 +46,7 @@ void PaymentRequest::Init( payments::mojom::PaymentRequestClientPtr client, - std::vector<payments::mojom::PaymentMethodDataPtr> methodData, + std::vector<payments::mojom::PaymentMethodDataPtr> method_data, payments::mojom::PaymentDetailsPtr details, payments::mojom::PaymentOptionsPtr options) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); @@ -49,6 +58,7 @@ } client_ = std::move(client); details_ = std::move(details); + PopulateValidatedMethodData(method_data); PopulateProfileCache(); SetDefaultProfileSelections(); } @@ -160,4 +170,75 @@ set_selected_contact_profile(contact_profiles()[0]); } +void PaymentRequest::PopulateValidatedMethodData( + const std::vector<payments::mojom::PaymentMethodDataPtr>& method_data) { + if (method_data.empty()) { + LOG(ERROR) << "Invalid payment methods or data"; + OnConnectionTerminated(); + return; + } + + std::set<std::string> card_networks{"amex", "diners", "discover", + "jcb", "mastercard", "mir", + "unionpay", "visa"}; + for (const payments::mojom::PaymentMethodDataPtr& method_data_entry : + method_data) { + std::vector<std::string> supported_methods = + method_data_entry->supported_methods; + if (supported_methods.empty()) { + LOG(ERROR) << "Invalid payment methods or data"; + OnConnectionTerminated(); + return; + } + + for (const std::string& method : supported_methods) { + if (method.empty()) + continue; + + // If a card network is specified right in "supportedMethods", add it. + auto card_it = card_networks.find(method); + if (card_it != card_networks.end()) { + supported_card_networks_.push_back(method); + // |method| removed from |card_networks| so that it is not doubly added + // to |supported_card_networks_| if "basic-card" is specified with no + // supported networks. + card_networks.erase(card_it); + } else if (method == kBasicCardMethodName) { + // For the "basic-card" method, check "supportedNetworks". + if (method_data_entry->supported_networks.empty()) { + // Empty |supported_networks| means all networks are supported. + supported_card_networks_.insert(supported_card_networks_.end(), + card_networks.begin(), + card_networks.end()); + // Clear the set so that no further networks are added to + // |supported_card_networks_|. + card_networks.clear(); + } else { + // The merchant has specified a few basic card supported networks. Use + // the mapping to transform to known basic-card types. + std::unordered_map<BasicCardNetwork, std::string> networks = { + {BasicCardNetwork::AMEX, "amex"}, + {BasicCardNetwork::DINERS, "diners"}, + {BasicCardNetwork::DISCOVER, "discover"}, + {BasicCardNetwork::JCB, "jcb"}, + {BasicCardNetwork::MASTERCARD, "mastercard"}, + {BasicCardNetwork::MIR, "mir"}, + {BasicCardNetwork::UNIONPAY, "unionpay"}, + {BasicCardNetwork::VISA, "visa"}}; + for (const BasicCardNetwork& supported_network : + method_data_entry->supported_networks) { + // Make sure that the network was not already added to + // |supported_card_networks_|. + auto card_it = card_networks.find(networks[supported_network]); + if (card_it != card_networks.end()) { + supported_card_networks_.push_back(networks[supported_network]); + card_networks.erase(card_it); + } + } + } + } + } + } +} + } // namespace payments
diff --git a/components/payments/payment_request.h b/components/payments/payment_request.h index cd54b7c..bde05954 100644 --- a/components/payments/payment_request.h +++ b/components/payments/payment_request.h
@@ -39,7 +39,7 @@ // payments::mojom::PaymentRequest "stub" void Init(payments::mojom::PaymentRequestClientPtr client, - std::vector<payments::mojom::PaymentMethodDataPtr> methodData, + std::vector<payments::mojom::PaymentMethodDataPtr> method_data, payments::mojom::PaymentDetailsPtr details, payments::mojom::PaymentOptionsPtr options) override; void Show() override; @@ -101,6 +101,9 @@ } payments::mojom::PaymentDetails* details() { return details_.get(); } + const std::vector<std::string>& supported_card_networks() { + return supported_card_networks_; + } content::WebContents* web_contents() { return web_contents_; } private: @@ -111,6 +114,10 @@ // Sets the default values for the selected Shipping and Contact profiles. void SetDefaultProfileSelections(); + // Validates the |method_data| and fills |supported_card_networks_|. + void PopulateValidatedMethodData( + const std::vector<payments::mojom::PaymentMethodDataPtr>& method_data); + content::WebContents* web_contents_; std::unique_ptr<PaymentRequestDelegate> delegate_; // |manager_| owns this PaymentRequest. @@ -119,6 +126,8 @@ payments::mojom::PaymentRequestClientPtr client_; payments::mojom::PaymentDetailsPtr details_; std::unique_ptr<CurrencyFormatter> currency_formatter_; + // A set of supported basic card networks. + std::vector<std::string> supported_card_networks_; // Profiles may change due to (e.g.) sync events, so profiles are cached after // loading and owned here. They are populated once only, and ordered by
diff --git a/components/safe_browsing/base_ui_manager.cc b/components/safe_browsing/base_ui_manager.cc index 9ea77fe..f951896d 100644 --- a/components/safe_browsing/base_ui_manager.cc +++ b/components/safe_browsing/base_ui_manager.cc
@@ -215,13 +215,15 @@ return; } - // BaseUIManager does not send SafeBrowsingHitReport. Subclasses should - // implement the reporting logic themselves if needed. + if (resource.threat_type != SB_THREAT_TYPE_SAFE) { + CreateAndSendHitReport(resource); + } + AddToWhitelistUrlSet(GetMainFrameWhitelistUrlForResource(resource), resource.web_contents_getter.Run(), true /* A decision is now pending */, resource.threat_type); - BaseBlockingPage::ShowBlockingPage(this, resource); + ShowBlockingPageForResource(resource); } void BaseUIManager::EnsureWhitelistCreated( @@ -234,6 +236,13 @@ return; } +void BaseUIManager::CreateAndSendHitReport(const UnsafeResource& resource) {} + +void BaseUIManager::ShowBlockingPageForResource( + const UnsafeResource& resource) { + BaseBlockingPage::ShowBlockingPage(this, resource); +} + // A safebrowsing hit is sent after a blocking page for malware/phishing // or after the warning dialog for download urls, only for // UMA || extended_reporting users.
diff --git a/components/safe_browsing/base_ui_manager.h b/components/safe_browsing/base_ui_manager.h index 638e0cd4..1230417 100644 --- a/components/safe_browsing/base_ui_manager.h +++ b/components/safe_browsing/base_ui_manager.h
@@ -136,6 +136,14 @@ static GURL GetMainFrameWhitelistUrlForResource( const security_interstitials::UnsafeResource& resource); + // BaseUIManager does not send SafeBrowsingHitReport. Subclasses should + // implement the reporting logic themselves if needed. + virtual void CreateAndSendHitReport(const UnsafeResource& resource); + + // Calls BaseBlockingPage::ShowBlockingPage(). Override this if using a + // different blocking page. + virtual void ShowBlockingPageForResource(const UnsafeResource& resource); + private: friend class base::RefCountedThreadSafe<BaseUIManager>;
diff --git a/content/browser/android/synchronous_compositor_browser_filter.cc b/content/browser/android/synchronous_compositor_browser_filter.cc index 838c80e..f4e661965 100644 --- a/content/browser/android/synchronous_compositor_browser_filter.cc +++ b/content/browser/android/synchronous_compositor_browser_filter.cc
@@ -194,12 +194,14 @@ if (!render_process_host_->Send( new SyncCompositorMsg_SynchronizeRendererState(routing_ids, ¶ms))) { + compositor_host_pending_renderer_state_.clear(); return; } if (compositor_host_pending_renderer_state_.size() != params.size()) { bad_message::ReceivedBadMessage(render_process_host_, bad_message::SCO_INVALID_ARGUMENT); + compositor_host_pending_renderer_state_.clear(); return; }
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index 9e954d8..7b92187 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc
@@ -448,6 +448,7 @@ should_normally_be_visible_(true), did_first_set_visible_(false), is_being_destroyed_(false), + is_notifying_observers_(false), notify_disconnection_(false), dialog_manager_(NULL), is_showing_before_unload_dialog_(false), @@ -494,6 +495,11 @@ WebContentsImpl::~WebContentsImpl() { is_being_destroyed_ = true; + // A WebContents should never be deleted while it is notifying observers, + // since this will lead to a use-after-free as it continues to notfiy later + // observers. + CHECK(!is_notifying_observers_); + rwh_input_event_router_.reset(); for (auto& entry : binding_sets_) @@ -4558,8 +4564,10 @@ RenderFrameHost* render_frame_host) { ShowInsecureLocalhostWarningIfNeeded(); + is_notifying_observers_ = true; for (auto& observer : observers_) observer.DocumentOnLoadCompletedInMainFrame(); + is_notifying_observers_ = false; // TODO(avi): Remove. http://crbug.com/170921 NotificationService::current()->Notify(
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h index a88e34b8e..cf9f25f 100644 --- a/content/browser/web_contents/web_contents_impl.h +++ b/content/browser/web_contents/web_contents_impl.h
@@ -1307,6 +1307,10 @@ // See getter above. bool is_being_destroyed_; + // Keep track of whether this WebContents is currently iterating over its list + // of observers, during which time it should not be deleted. + bool is_notifying_observers_; + // Indicates whether we should notify about disconnection of this // WebContentsImpl. This is used to ensure disconnection notifications only // happen if a connection notification has happened and that they happen only
diff --git a/content/browser/zygote_host/OWNERS b/content/browser/zygote_host/OWNERS index 8a7f8eb..75b96d59 100644 --- a/content/browser/zygote_host/OWNERS +++ b/content/browser/zygote_host/OWNERS
@@ -1,3 +1,6 @@ jln@chromium.org mdempsky@chromium.org rickyz@chromium.org + +# TEAM: security-dev@chromium.org +# COMPONENT: Internals>Sandbox
diff --git a/content/common/sandbox_linux/OWNERS b/content/common/sandbox_linux/OWNERS index 4f1c402..444aa4e 100644 --- a/content/common/sandbox_linux/OWNERS +++ b/content/common/sandbox_linux/OWNERS
@@ -3,3 +3,6 @@ mdempsky@chromium.org rickyz@chromium.org rsesek@chromium.org + +# TEAM: security-dev@chromium.org +# COMPONENT: Internals>Sandbox
diff --git a/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py b/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py index ea65b56..bd5b2962 100644 --- a/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py +++ b/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py
@@ -505,6 +505,10 @@ ['mac', 'amd'], bug=645298) # Mac Pro with AMD GPU + self.Fail('deqp/functional/gles3/fborender/recreate_color_02.html', + ['mac', ('amd', 0x679e)], bug=679682) + self.Fail('deqp/functional/gles3/fborender/resize_01.html', + ['mac', ('amd', 0x679e)], bug=679682) self.Flaky('deqp/functional/gles3/shaderindexing/mat_01.html', ['mac', ('amd', 0x679e)], bug=636648) self.Flaky('deqp/functional/gles3/shaderindexing/tmp.html', @@ -515,10 +519,6 @@ ['mac', ('amd', 0x679e)], bug=483282) # Mac Multi-vendor failures. - self.Fail('deqp/functional/gles3/fborender/recreate_color_02.html', - ['mac', 'nvidia', 'amd'], bug=679682) - self.Fail('deqp/functional/gles3/fborender/resize_01.html', - ['mac', 'nvidia', 'amd'], bug=679682) self.Fail('deqp/functional/gles3/fragmentoutput/basic.float.html', ['mac', 'nvidia', 'amd'], bug=679684) self.Fail('deqp/functional/gles3/fragmentoutput/array.float.html',
diff --git a/content/zygote/OWNERS b/content/zygote/OWNERS index 8a7f8eb..75b96d59 100644 --- a/content/zygote/OWNERS +++ b/content/zygote/OWNERS
@@ -1,3 +1,6 @@ jln@chromium.org mdempsky@chromium.org rickyz@chromium.org + +# TEAM: security-dev@chromium.org +# COMPONENT: Internals>Sandbox
diff --git a/device/usb/BUILD.gn b/device/usb/BUILD.gn index 4e22715..9fb1235 100644 --- a/device/usb/BUILD.gn +++ b/device/usb/BUILD.gn
@@ -34,6 +34,8 @@ "usb_device_handle_android.h", "usb_device_linux.cc", "usb_device_linux.h", + "usb_device_win.cc", + "usb_device_win.h", "usb_endpoint_android.cc", "usb_endpoint_android.h", "usb_ids.cc", @@ -89,6 +91,10 @@ deps += [ "//third_party/libusb" ] } + if (is_win) { + libs = [ "setupapi.lib" ] + } + if (is_android || is_chromeos || is_linux) { sources += [ "usb_device_handle_usbfs.cc",
diff --git a/device/usb/usb_device.cc b/device/usb/usb_device.cc index c7ffa73c..b6198d0 100644 --- a/device/usb/usb_device.cc +++ b/device/usb/usb_device.cc
@@ -14,6 +14,8 @@ void UsbDevice::Observer::OnDeviceRemoved(scoped_refptr<UsbDevice> device) {} +UsbDevice::UsbDevice() : guid_(base::GenerateGUID()) {} + UsbDevice::UsbDevice(const UsbDeviceDescriptor& descriptor, const base::string16& manufacturer_string, const base::string16& product_string, @@ -47,8 +49,7 @@ descriptor_.device_version = device_version; } -UsbDevice::~UsbDevice() { -} +UsbDevice::~UsbDevice() {} void UsbDevice::CheckUsbAccess(const ResultCallback& callback) { // By default assume that access to the device is allowed. This is implemented
diff --git a/device/usb/usb_device.h b/device/usb/usb_device.h index 58c9792..4dc115c 100644 --- a/device/usb/usb_device.h +++ b/device/usb/usb_device.h
@@ -96,6 +96,7 @@ protected: friend class UsbService; + UsbDevice(); UsbDevice(const UsbDeviceDescriptor& descriptor, const base::string16& manufacturer_string, const base::string16& product_string, @@ -134,6 +135,7 @@ friend class UsbServiceAndroid; friend class UsbServiceImpl; friend class UsbServiceLinux; + friend class UsbServiceWin; void OnDisconnect(); void HandleClosed(UsbDeviceHandle* handle);
diff --git a/device/usb/usb_device_win.cc b/device/usb/usb_device_win.cc new file mode 100644 index 0000000..172858d --- /dev/null +++ b/device/usb/usb_device_win.cc
@@ -0,0 +1,35 @@ +// 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 "device/usb/usb_device_win.h" + +#include "base/bind.h" +#include "base/memory/ptr_util.h" +#include "base/sequenced_task_runner.h" +#include "base/single_thread_task_runner.h" +#include "base/threading/thread_task_runner_handle.h" +#include "components/device_event_log/device_event_log.h" +#include "device/usb/usb_device_handle.h" + +namespace device { + +UsbDeviceWin::UsbDeviceWin( + const std::string& device_path, + const std::string& hub_path, + int port_number, + scoped_refptr<base::SequencedTaskRunner> blocking_task_runner) + : device_path_(device_path), + hub_path_(hub_path), + port_number_(port_number), + task_runner_(base::ThreadTaskRunnerHandle::Get()), + blocking_task_runner_(std::move(blocking_task_runner)) {} + +UsbDeviceWin::~UsbDeviceWin() {} + +void UsbDeviceWin::Open(const OpenCallback& callback) { + DCHECK(thread_checker_.CalledOnValidThread()); + task_runner_->PostTask(FROM_HERE, base::Bind(callback, nullptr)); +} + +} // namespace device
diff --git a/device/usb/usb_device_win.h b/device/usb/usb_device_win.h new file mode 100644 index 0000000..0a74c06 --- /dev/null +++ b/device/usb/usb_device_win.h
@@ -0,0 +1,55 @@ +// 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 DEVICE_USB_USB_DEVICE_WIN_H_ +#define DEVICE_USB_USB_DEVICE_WIN_H_ + +#include <string> + +#include "base/macros.h" +#include "base/threading/thread_checker.h" +#include "device/usb/usb_device.h" + +namespace base { +class SequencedTaskRunner; +} + +namespace device { + +class UsbDeviceWin : public UsbDevice { + public: + // UsbDevice implementation: + void Open(const OpenCallback& callback) override; + + protected: + friend class UsbServiceWin; + friend class UsbDeviceHandleWin; + + // Called by UsbServiceWin only; + UsbDeviceWin(const std::string& device_path, + const std::string& hub_path, + int port_number, + scoped_refptr<base::SequencedTaskRunner> task_runner); + + ~UsbDeviceWin() override; + + const std::string& device_path() const { return device_path_; } + int port_number() const { return port_number_; } + + private: + base::ThreadChecker thread_checker_; + + const std::string device_path_; + const std::string hub_path_; + const int port_number_; + + scoped_refptr<base::SequencedTaskRunner> task_runner_; + scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_; + + DISALLOW_COPY_AND_ASSIGN(UsbDeviceWin); +}; + +} // namespace device + +#endif // DEVICE_USB_USB_DEVICE_WIN_H_
diff --git a/device/usb/usb_service_impl.h b/device/usb/usb_service_impl.h index e5467fb..c644842 100644 --- a/device/usb/usb_service_impl.h +++ b/device/usb/usb_service_impl.h
@@ -34,6 +34,8 @@ typedef struct libusb_device* PlatformUsbDevice; typedef struct libusb_context* PlatformUsbContext; +class UsbDeviceImpl; + class UsbServiceImpl : #if defined(OS_WIN) public DeviceMonitorWin::Observer,
diff --git a/device/usb/usb_service_win.cc b/device/usb/usb_service_win.cc index 6feea89..131fdb33 100644 --- a/device/usb/usb_service_win.cc +++ b/device/usb/usb_service_win.cc
@@ -4,12 +4,386 @@ #include "device/usb/usb_service_win.h" +#include <setupapi.h> +#include <stdint.h> +#include <usbiodef.h> + +#define INITGUID +#include <devpkey.h> + +#include "base/bind.h" +#include "base/location.h" +#include "base/memory/free_deleter.h" +#include "base/memory/ptr_util.h" +#include "base/scoped_generic.h" +#include "base/single_thread_task_runner.h" +#include "base/stl_util.h" +#include "base/strings/string_util.h" +#include "base/strings/sys_string_conversions.h" +#include "base/threading/thread_task_runner_handle.h" +#include "base/win/scoped_handle.h" +#include "components/device_event_log/device_event_log.h" +#include "device/usb/usb_descriptors.h" +#include "device/usb/usb_device_handle.h" +#include "device/usb/webusb_descriptors.h" + namespace device { +namespace { + +struct DevInfoScopedTraits { + static HDEVINFO InvalidValue() { return INVALID_HANDLE_VALUE; } + static void Free(HDEVINFO h) { SetupDiDestroyDeviceInfoList(h); } +}; + +using ScopedDevInfo = base::ScopedGeneric<HDEVINFO, DevInfoScopedTraits>; + +bool GetDeviceUint32Property(HDEVINFO dev_info, + SP_DEVINFO_DATA* dev_info_data, + const DEVPROPKEY& property, + uint32_t* property_buffer) { + DEVPROPTYPE property_type; + if (!SetupDiGetDeviceProperty(dev_info, dev_info_data, &property, + &property_type, + reinterpret_cast<PBYTE>(property_buffer), + sizeof(*property_buffer), nullptr, 0) || + property_type != DEVPROP_TYPE_UINT32) { + return false; + } + + return true; +} + +bool GetDeviceStringProperty(HDEVINFO dev_info, + SP_DEVINFO_DATA* dev_info_data, + const DEVPROPKEY& property, + std::string* property_buffer) { + DEVPROPTYPE property_type; + DWORD required_size; + if (SetupDiGetDeviceProperty(dev_info, dev_info_data, &property, + &property_type, nullptr, 0, &required_size, 0) || + GetLastError() != ERROR_INSUFFICIENT_BUFFER || + property_type != DEVPROP_TYPE_STRING) { + return false; + } + + std::wstring wide_buffer; + if (!SetupDiGetDeviceProperty( + dev_info, dev_info_data, &property, &property_type, + reinterpret_cast<PBYTE>(base::WriteInto(&wide_buffer, required_size)), + required_size, nullptr, 0)) { + return false; + } + + *property_buffer = base::SysWideToUTF8(wide_buffer); + return true; +} + +bool GetDeviceInterfaceDetails(HDEVINFO dev_info, + SP_DEVICE_INTERFACE_DATA* device_interface_data, + std::string* device_path, + uint32_t* port_number, + std::string* parent_instance_id) { + DWORD required_size; + if (SetupDiGetDeviceInterfaceDetail(dev_info, device_interface_data, nullptr, + 0, &required_size, nullptr) || + GetLastError() != ERROR_INSUFFICIENT_BUFFER) { + return false; + } + + std::unique_ptr<SP_DEVICE_INTERFACE_DETAIL_DATA, base::FreeDeleter> + device_interface_detail_data( + static_cast<SP_DEVICE_INTERFACE_DETAIL_DATA*>(malloc(required_size))); + device_interface_detail_data->cbSize = sizeof(*device_interface_detail_data); + + SP_DEVINFO_DATA dev_info_data; + dev_info_data.cbSize = sizeof(dev_info_data); + + if (!SetupDiGetDeviceInterfaceDetail( + dev_info, device_interface_data, device_interface_detail_data.get(), + required_size, nullptr, &dev_info_data)) { + USB_PLOG(ERROR) << "SetupDiGetDeviceInterfaceDetail"; + return false; + } + + if (device_path) { + *device_path = + base::SysWideToUTF8(device_interface_detail_data->DevicePath); + } + + if (port_number) { + if (!GetDeviceUint32Property(dev_info, &dev_info_data, + DEVPKEY_Device_Address, port_number)) { + USB_PLOG(ERROR) << "Failed to get device address"; + return false; + } + } + + if (parent_instance_id) { + if (!GetDeviceStringProperty(dev_info, &dev_info_data, + DEVPKEY_Device_Parent, parent_instance_id)) { + USB_PLOG(ERROR) << "Failed to get the device parent"; + return false; + } + } + + return true; +} + +bool GetHubDevicePath(const std::string& instance_id, + std::string* device_path) { + ScopedDevInfo dev_info( + SetupDiGetClassDevsA(&GUID_DEVINTERFACE_USB_HUB, instance_id.c_str(), 0, + DIGCF_DEVICEINTERFACE | DIGCF_PRESENT)); + if (!dev_info.is_valid()) { + USB_PLOG(ERROR) << "SetupDiGetClassDevs"; + return false; + } + + SP_DEVICE_INTERFACE_DATA device_interface_data; + device_interface_data.cbSize = sizeof(device_interface_data); + if (!SetupDiEnumDeviceInterfaces(dev_info.get(), nullptr, + &GUID_DEVINTERFACE_USB_HUB, 0, + &device_interface_data)) { + USB_PLOG(ERROR) << "SetupDiEnumDeviceInterfaces"; + return false; + } + + return GetDeviceInterfaceDetails(dev_info.get(), &device_interface_data, + device_path, nullptr, nullptr); +} + +} // namespace + +class UsbServiceWin::BlockingThreadHelper { + public: + explicit BlockingThreadHelper(base::WeakPtr<UsbServiceWin> service) + : service_task_runner_(base::ThreadTaskRunnerHandle::Get()), + service_(service) {} + ~BlockingThreadHelper() {} + + void EnumerateDevices() { + ScopedDevInfo dev_info( + SetupDiGetClassDevs(&GUID_DEVINTERFACE_USB_DEVICE, nullptr, 0, + DIGCF_DEVICEINTERFACE | DIGCF_PRESENT)); + if (!dev_info.is_valid()) { + USB_PLOG(ERROR) << "Failed to set up device enumeration"; + service_task_runner_->PostTask( + FROM_HERE, base::Bind(&UsbServiceWin::HelperStarted, service_)); + return; + } + + SP_DEVICE_INTERFACE_DATA device_interface_data; + device_interface_data.cbSize = sizeof(device_interface_data); + for (DWORD i = 0; SetupDiEnumDeviceInterfaces(dev_info.get(), nullptr, + &GUID_DEVINTERFACE_USB_DEVICE, + i, &device_interface_data); + ++i) { + std::string device_path; + uint32_t port_number; + std::string parent_instance_id; + if (!GetDeviceInterfaceDetails(dev_info.get(), &device_interface_data, + &device_path, &port_number, + &parent_instance_id)) { + continue; + } + + std::string& hub_path = hub_paths_[parent_instance_id]; + if (hub_path.empty()) { + std::string parent_path; + if (!GetHubDevicePath(parent_instance_id, &parent_path)) + continue; + + hub_path = parent_path; + } + + service_task_runner_->PostTask( + FROM_HERE, base::Bind(&UsbServiceWin::CreateDeviceObject, service_, + device_path, hub_path, port_number)); + } + + if (GetLastError() != ERROR_NO_MORE_ITEMS) + USB_PLOG(ERROR) << "Failed to enumerate devices"; + + service_task_runner_->PostTask( + FROM_HERE, base::Bind(&UsbServiceWin::HelperStarted, service_)); + } + + void EnumerateDevicePath(const std::string& device_path) { + ScopedDevInfo dev_info( + SetupDiGetClassDevs(&GUID_DEVINTERFACE_USB_DEVICE, nullptr, 0, + DIGCF_DEVICEINTERFACE | DIGCF_PRESENT)); + if (!dev_info.is_valid()) { + USB_PLOG(ERROR) << "Failed to set up device enumeration"; + return; + } + + SP_DEVICE_INTERFACE_DATA device_interface_data; + device_interface_data.cbSize = sizeof(device_interface_data); + if (!SetupDiOpenDeviceInterfaceA(dev_info.get(), device_path.c_str(), 0, + &device_interface_data)) { + USB_PLOG(ERROR) << "Failed to add device interface: " << device_path; + return; + } + + uint32_t port_number; + std::string parent_instance_id; + if (!GetDeviceInterfaceDetails(dev_info.get(), &device_interface_data, + nullptr, &port_number, + &parent_instance_id)) { + return; + } + + std::string& hub_path = hub_paths_[parent_instance_id]; + if (hub_path.empty()) { + std::string parent_path; + if (!GetHubDevicePath(parent_instance_id, &parent_path)) + return; + + hub_path = parent_path; + } + + service_task_runner_->PostTask( + FROM_HERE, base::Bind(&UsbServiceWin::CreateDeviceObject, service_, + device_path, hub_path, port_number)); + } + + private: + std::unordered_map<std::string, std::string> hub_paths_; + + // Calls back to |service_| must be posted to |service_task_runner_|, which + // runs tasks on the thread where that object lives. + scoped_refptr<base::SingleThreadTaskRunner> service_task_runner_; + base::WeakPtr<UsbServiceWin> service_; +}; + UsbServiceWin::UsbServiceWin( scoped_refptr<base::SequencedTaskRunner> blocking_task_runner) - : UsbService(blocking_task_runner) {} + : UsbService(blocking_task_runner), + device_observer_(this), + weak_factory_(this) { + DeviceMonitorWin* device_monitor = + DeviceMonitorWin::GetForDeviceInterface(GUID_DEVINTERFACE_USB_DEVICE); + if (device_monitor) + device_observer_.Add(device_monitor); + + helper_ = new BlockingThreadHelper(weak_factory_.GetWeakPtr()); + blocking_task_runner->PostTask( + FROM_HERE, base::Bind(&BlockingThreadHelper::EnumerateDevices, + base::Unretained(helper_))); +} UsbServiceWin::~UsbServiceWin() {} +void UsbServiceWin::GetDevices(const GetDevicesCallback& callback) { + DCHECK(CalledOnValidThread()); + if (enumeration_ready()) + UsbService::GetDevices(callback); + else + enumeration_callbacks_.push_back(callback); +} + +void UsbServiceWin::OnDeviceAdded(const GUID& class_guid, + const std::string& device_path) { + blocking_task_runner()->PostTask( + FROM_HERE, base::Bind(&BlockingThreadHelper::EnumerateDevicePath, + base::Unretained(helper_), device_path)); +} + +void UsbServiceWin::OnDeviceRemoved(const GUID& class_guid, + const std::string& device_path) { + DCHECK(CalledOnValidThread()); + auto by_path_it = devices_by_path_.find(device_path); + if (by_path_it == devices_by_path_.end()) + return; + + scoped_refptr<UsbDeviceWin> device = by_path_it->second; + devices_by_path_.erase(by_path_it); + device->OnDisconnect(); + + auto by_guid_it = devices().find(device->guid()); + if (by_guid_it != devices().end() && enumeration_ready()) { + USB_LOG(USER) << "USB device removed: path=" << device->device_path() + << " guid=" << device->guid(); + + devices().erase(by_guid_it); + NotifyDeviceRemoved(device); + } +} + +void UsbServiceWin::HelperStarted() { + DCHECK(CalledOnValidThread()); + helper_started_ = true; + if (enumeration_ready()) { + std::vector<scoped_refptr<UsbDevice>> result; + result.reserve(devices().size()); + for (const auto& map_entry : devices()) + result.push_back(map_entry.second); + for (const auto& callback : enumeration_callbacks_) + callback.Run(result); + enumeration_callbacks_.clear(); + } +} + +void UsbServiceWin::CreateDeviceObject(const std::string& device_path, + const std::string& hub_path, + int port_number) { + // Devices that appear during initial enumeration are gathered into the first + // result returned by GetDevices() and prevent device add/remove notifications + // from being sent. + if (!enumeration_ready()) + ++first_enumeration_countdown_; + + scoped_refptr<UsbDeviceWin> device(new UsbDeviceWin( + device_path, hub_path, port_number, blocking_task_runner())); + devices_by_path_[device->device_path()] = device; + + // TODO(reillyg): Read device descriptors. + DeviceReady(device, true); +} + +void UsbServiceWin::DeviceReady(scoped_refptr<UsbDeviceWin> device, + bool success) { + DCHECK(CalledOnValidThread()); + + bool enumeration_became_ready = false; + if (!enumeration_ready()) { + DCHECK_GT(first_enumeration_countdown_, 0u); + first_enumeration_countdown_--; + if (enumeration_ready()) + enumeration_became_ready = true; + } + + // If |device| was disconnected while descriptors were being read then it + // will have been removed from |devices_by_path_|. + auto it = devices_by_path_.find(device->device_path()); + if (it == devices_by_path_.end()) { + success = false; + } else if (success) { + DCHECK(!base::ContainsKey(devices(), device->guid())); + devices()[device->guid()] = device; + + USB_LOG(USER) << "USB device added: path=" << device->device_path() + << " vendor=" << device->vendor_id() << " \"" + << device->manufacturer_string() + << "\", product=" << device->product_id() << " \"" + << device->product_string() << "\", serial=\"" + << device->serial_number() << "\", guid=" << device->guid(); + } else { + devices_by_path_.erase(it); + } + + if (enumeration_became_ready) { + std::vector<scoped_refptr<UsbDevice>> result; + result.reserve(devices().size()); + for (const auto& map_entry : devices()) + result.push_back(map_entry.second); + for (const auto& callback : enumeration_callbacks_) + callback.Run(result); + enumeration_callbacks_.clear(); + } else if (success && enumeration_ready()) { + NotifyDeviceAdded(device); + } +} + } // namespace device
diff --git a/device/usb/usb_service_win.h b/device/usb/usb_service_win.h index a6feb81..a915577 100644 --- a/device/usb/usb_service_win.h +++ b/device/usb/usb_service_win.h
@@ -4,17 +4,63 @@ #include "device/usb/usb_service.h" +#include <list> +#include <unordered_map> + #include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "base/scoped_observer.h" +#include "device/base/device_monitor_win.h" +#include "device/usb/usb_device_win.h" + +namespace base { +class SequencedTaskRunner; +} namespace device { -class UsbServiceWin : public UsbService { +class UsbServiceWin : public DeviceMonitorWin::Observer, public UsbService { public: explicit UsbServiceWin( scoped_refptr<base::SequencedTaskRunner> blocking_task_runner); ~UsbServiceWin() override; private: + class BlockingThreadHelper; + + // device::UsbService implementation + void GetDevices(const GetDevicesCallback& callback) override; + + // device::DeviceMonitorWin::Observer implementation + void OnDeviceAdded(const GUID& class_guid, + const std::string& device_path) override; + void OnDeviceRemoved(const GUID& class_guid, + const std::string& device_path) override; + + // Methods called by BlockingThreadHelper + void HelperStarted(); + void CreateDeviceObject(const std::string& device_path, + const std::string& hub_path, + int port_number); + + void DeviceReady(scoped_refptr<UsbDeviceWin> device, bool success); + + bool enumeration_ready() { + return helper_started_ && first_enumeration_countdown_ == 0; + } + + // Enumeration callbacks are queued until an enumeration completes. + bool helper_started_ = false; + uint32_t first_enumeration_countdown_ = 0; + std::list<GetDevicesCallback> enumeration_callbacks_; + + BlockingThreadHelper* helper_; + std::unordered_map<std::string, scoped_refptr<UsbDeviceWin>> devices_by_path_; + + ScopedObserver<DeviceMonitorWin, DeviceMonitorWin::Observer> device_observer_; + + base::WeakPtrFactory<UsbServiceWin> weak_factory_; + DISALLOW_COPY_AND_ASSIGN(UsbServiceWin); };
diff --git a/extensions/browser/info_map.cc b/extensions/browser/info_map.cc index c97832c..7efb7365 100644 --- a/extensions/browser/info_map.cc +++ b/extensions/browser/info_map.cc
@@ -49,6 +49,16 @@ InfoMap::InfoMap() { } +const ExtensionSet& InfoMap::extensions() const { + CheckOnValidThread(); + return extensions_; +} + +const ExtensionSet& InfoMap::disabled_extensions() const { + CheckOnValidThread(); + return disabled_extensions_; +} + void InfoMap::AddExtension(const Extension* extension, base::Time install_time, bool incognito_enabled,
diff --git a/extensions/browser/info_map.h b/extensions/browser/info_map.h index 2deafec..c895007 100644 --- a/extensions/browser/info_map.h +++ b/extensions/browser/info_map.h
@@ -30,10 +30,8 @@ public: InfoMap(); - const ExtensionSet& extensions() const { return extensions_; } - const ExtensionSet& disabled_extensions() const { - return disabled_extensions_; - } + const ExtensionSet& extensions() const; + const ExtensionSet& disabled_extensions() const; // Information about which extensions are assigned to which render processes. const ProcessMap& process_map() const { return process_map_; }
diff --git a/extensions/common/file_util.cc b/extensions/common/file_util.cc index 96982d06..2e986c430 100644 --- a/extensions/common/file_util.cc +++ b/extensions/common/file_util.cc
@@ -38,7 +38,6 @@ #include "extensions/common/manifest_handler.h" #include "extensions/common/manifest_handlers/default_locale_handler.h" #include "extensions/common/manifest_handlers/icons_handler.h" -#include "extensions/common/manifest_handlers/shared_module_info.h" #include "grit/extensions_strings.h" #include "net/base/escape.h" #include "net/base/filename_util.h" @@ -514,77 +513,40 @@ const base::FilePath& extension_path, const std::string& extension_id, const std::string& default_locale) { + return LoadMessageBundleSubstitutionMapFromPaths( + {extension_path}, extension_id, default_locale); +} + +MessageBundle::SubstitutionMap* LoadNonLocalizedMessageBundleSubstitutionMap( + const std::string& extension_id) { MessageBundle::SubstitutionMap* return_value = new MessageBundle::SubstitutionMap(); - if (!default_locale.empty()) { - // Touch disk only if extension is localized. - std::string error; - std::unique_ptr<MessageBundle> bundle( - LoadMessageBundle(extension_path, default_locale, &error)); - if (bundle.get()) - *return_value = *bundle->dictionary(); - } - - // Add @@extension_id reserved message here, so it's available to - // non-localized extensions too. + // Add @@extension_id reserved message here. return_value->insert( std::make_pair(MessageBundle::kExtensionIdKey, extension_id)); return return_value; } -MessageBundle::SubstitutionMap* LoadMessageBundleSubstitutionMapWithImports( +MessageBundle::SubstitutionMap* LoadMessageBundleSubstitutionMapFromPaths( + const std::vector<base::FilePath>& paths, const std::string& extension_id, - const ExtensionSet& extension_set) { - const Extension* extension = extension_set.GetByID(extension_id); + const std::string& default_locale) { MessageBundle::SubstitutionMap* return_value = - new MessageBundle::SubstitutionMap(); - - // Add @@extension_id reserved message here, so it's available to - // non-localized extensions too. - return_value->insert( - std::make_pair(MessageBundle::kExtensionIdKey, extension_id)); - - base::FilePath extension_path; - std::string default_locale; - if (!extension) { - NOTREACHED() << "Missing extension " << extension_id; - return return_value; - } + LoadNonLocalizedMessageBundleSubstitutionMap(extension_id); // Touch disk only if extension is localized. - default_locale = LocaleInfo::GetDefaultLocale(extension); - if (default_locale.empty()) { + if (default_locale.empty()) return return_value; - } std::string error; - std::unique_ptr<MessageBundle> bundle( - LoadMessageBundle(extension->path(), default_locale, &error)); + for (const base::FilePath& path : paths) { + std::unique_ptr<MessageBundle> bundle( + LoadMessageBundle(path, default_locale, &error)); - if (bundle.get()) { - for (auto iter : *bundle->dictionary()) { - return_value->insert(std::make_pair(iter.first, iter.second)); - } - } - - auto imports = extensions::SharedModuleInfo::GetImports(extension); - // Iterate through the imports in reverse. This will allow later imported - // modules to override earlier imported modules, as the list order is - // maintained from the definition in manifest.json of the imports. - for (auto it = imports.rbegin(); it != imports.rend(); ++it) { - const extensions::Extension* imported_extension = - extension_set.GetByID(it->extension_id); - if (!imported_extension) { - NOTREACHED() << "Missing shared module " << it->extension_id; - continue; - } - std::unique_ptr<MessageBundle> imported_bundle( - LoadMessageBundle(imported_extension->path(), default_locale, &error)); - - if (imported_bundle.get()) { - for (auto iter : *imported_bundle->dictionary()) { + if (bundle) { + for (const auto& iter : *bundle->dictionary()) { // |insert| only adds new entries, and does not replace entries in // the main extension or previously processed imports. return_value->insert(std::make_pair(iter.first, iter.second));
diff --git a/extensions/common/file_util.h b/extensions/common/file_util.h index bc080edb..6678163 100644 --- a/extensions/common/file_util.h +++ b/extensions/common/file_util.h
@@ -23,7 +23,6 @@ namespace extensions { class Extension; -class ExtensionSet; struct InstallWarning; // Utilities for manipulating the on-disk storage of extensions. @@ -135,12 +134,18 @@ const std::string& extension_id, const std::string& default_locale); -// Loads the extension message bundle substitution map, including messages from -// Shared Modules that the given extension imports. Contains at least the -// extension_id item. -MessageBundle::SubstitutionMap* LoadMessageBundleSubstitutionMapWithImports( +// Loads the extension message bundle substitution map for a non-localized +// extension. Contains only the extension_id item. +// This doesn't require hitting disk, so it's safe to call on any thread. +MessageBundle::SubstitutionMap* LoadNonLocalizedMessageBundleSubstitutionMap( + const std::string& extension_id); + +// Loads the extension message bundle substitution map from the specified paths. +// Contains at least the extension_id item. +MessageBundle::SubstitutionMap* LoadMessageBundleSubstitutionMapFromPaths( + const std::vector<base::FilePath>& paths, const std::string& extension_id, - const ExtensionSet& extension_set); + const std::string& default_locale); // Helper functions for getting paths for files used in content verification. base::FilePath GetVerifiedContentsPath(const base::FilePath& extension_path);
diff --git a/extensions/renderer/guest_view/guest_view_internal_custom_bindings.cc b/extensions/renderer/guest_view/guest_view_internal_custom_bindings.cc index bec7d1c..77bc51f 100644 --- a/extensions/renderer/guest_view/guest_view_internal_custom_bindings.cc +++ b/extensions/renderer/guest_view/guest_view_internal_custom_bindings.cc
@@ -15,6 +15,7 @@ #include "components/guest_view/renderer/iframe_guest_view_request.h" #include "content/public/child/v8_value_converter.h" #include "content/public/renderer/render_frame.h" +#include "content/public/renderer/render_frame_observer.h" #include "content/public/renderer/render_thread.h" #include "content/public/renderer/render_view.h" #include "extensions/common/extension.h" @@ -57,6 +58,18 @@ return content::RenderFrame::FromWebFrame(frame); } +class RenderFrameStatus : public content::RenderFrameObserver { + public: + explicit RenderFrameStatus(content::RenderFrame* render_frame) + : content::RenderFrameObserver(render_frame) {} + ~RenderFrameStatus() final {} + + bool is_ok() { return render_frame() != nullptr; } + + // RenderFrameObserver implementation. + void OnDestruct() final {} +}; + } // namespace GuestViewInternalCustomBindings::GuestViewInternalCustomBindings( @@ -144,6 +157,8 @@ // is invalid? if (!guest_view_container) return; + // Retain a weak pointer so we can easily test if the container goes away. + auto weak_ptr = guest_view_container->GetWeakPtr(); int guest_instance_id = args[1]->Int32Value(); @@ -155,6 +170,12 @@ params = base::DictionaryValue::From(std::move(params_as_value)); CHECK(params); } + // We should be careful that some malicious JS in the GuestView's embedder + // hasn't destroyed |guest_view_container| during the enumeration of the + // properties of the guest's object during extraction of |params| above + // (see https://crbug.com/683523). + if (!weak_ptr) + return; // Add flag to |params| to indicate that the element size is specified in // logical units. @@ -221,6 +242,12 @@ int element_instance_id = args[0]->Int32Value(); int guest_instance_id = args[1]->Int32Value(); + // Get the WebLocalFrame before (possibly) executing any user-space JS while + // getting the |params|. We track the status of the RenderFrame via an + // observer in case it is deleted during user code execution. + content::RenderFrame* render_frame = GetRenderFrame(args[3]); + RenderFrameStatus render_frame_status(render_frame); + std::unique_ptr<base::DictionaryValue> params; { std::unique_ptr<V8ValueConverter> converter(V8ValueConverter::create()); @@ -229,19 +256,19 @@ params = base::DictionaryValue::From(std::move(params_as_value)); CHECK(params); } + if (!render_frame_status.is_ok()) + return; - // Add flag to |params| to indicate that the element size is specified in - // logical units. - params->SetBoolean(guest_view::kElementSizeIsLogical, true); - - content::RenderFrame* render_frame = GetRenderFrame(args[3]); blink::WebLocalFrame* frame = render_frame->GetWebFrame(); - // Parent must exist. blink::WebFrame* parent_frame = frame->parent(); DCHECK(parent_frame); DCHECK(parent_frame->isWebLocalFrame()); + // Add flag to |params| to indicate that the element size is specified in + // logical units. + params->SetBoolean(guest_view::kElementSizeIsLogical, true); + content::RenderFrame* embedder_parent_frame = content::RenderFrame::FromWebFrame(parent_frame);
diff --git a/ios/chrome/browser/tabs/BUILD.gn b/ios/chrome/browser/tabs/BUILD.gn index 6a71d9c..61bfe2a1 100644 --- a/ios/chrome/browser/tabs/BUILD.gn +++ b/ios/chrome/browser/tabs/BUILD.gn
@@ -102,6 +102,7 @@ "//ios/net", "//ios/public/provider/chrome/browser", "//ios/public/provider/chrome/browser/native_app_launcher", + "//ios/shared/chrome/browser/tabs", "//ios/web", "//net", "//ui/base", @@ -127,6 +128,7 @@ "//base", "//ios/chrome/browser", "//ios/chrome/browser/browser_state", + "//ios/shared/chrome/browser/tabs", "//ios/web", ] libs = [ "Foundation.framework" ]
diff --git a/ios/chrome/browser/tabs/tab_model.mm b/ios/chrome/browser/tabs/tab_model.mm index 81d4528f2..c9799c0 100644 --- a/ios/chrome/browser/tabs/tab_model.mm +++ b/ios/chrome/browser/tabs/tab_model.mm
@@ -4,6 +4,7 @@ #import "ios/chrome/browser/tabs/tab_model.h" +#include <cstdint> #include <utility> #include <vector> @@ -28,12 +29,16 @@ #import "ios/chrome/browser/sessions/session_window.h" #import "ios/chrome/browser/snapshots/snapshot_cache.h" #include "ios/chrome/browser/tab_parenting_global_observer.h" +#import "ios/chrome/browser/tabs/legacy_tab_helper.h" #import "ios/chrome/browser/tabs/tab.h" #import "ios/chrome/browser/tabs/tab_model_list.h" #import "ios/chrome/browser/tabs/tab_model_observers.h" #import "ios/chrome/browser/tabs/tab_model_order_controller.h" #import "ios/chrome/browser/tabs/tab_model_synced_window_delegate.h" #import "ios/chrome/browser/xcallback_parameters.h" +#import "ios/shared/chrome/browser/tabs/web_state_list.h" +#import "ios/shared/chrome/browser/tabs/web_state_list_fast_enumeration_helper.h" +#import "ios/shared/chrome/browser/tabs/web_state_list_observer.h" #import "ios/web/navigation/crw_session_certificate_policy_manager.h" #import "ios/web/navigation/crw_session_controller.h" #include "ios/web/public/browser_state.h" @@ -79,38 +84,62 @@ updateCertificatePolicyCache:policy_cache]; } -// Populates the certificate policy cache based on the WebStates of |tab_model|. +// Populates the certificate policy cache based on the WebStates of +// |web_state_list|. void RestoreCertificatePolicyCacheFromModel( const scoped_refptr<web::CertificatePolicyCache>& policy_cache, - TabModel* tab_model) { + WebStateList* web_state_list) { DCHECK_CURRENTLY_ON(web::WebThread::UI); - for (Tab* tab in tab_model) - UpdateCertificatePolicyCacheFromWebState(policy_cache, tab.webState); + for (int index = 0; index < web_state_list->count(); ++index) { + UpdateCertificatePolicyCacheFromWebState( + policy_cache, web_state_list->GetWebStateAt(index)); + } } // Scrubs the certificate policy cache of all certificates policies except -// those for the current entries in |tab_model|. +// those for the current entries in |web_state_list|. void CleanCertificatePolicyCache( base::CancelableTaskTracker* task_tracker, const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, const scoped_refptr<web::CertificatePolicyCache>& policy_cache, - TabModel* tab_model) { - DCHECK(tab_model); + WebStateList* web_state_list) { DCHECK(policy_cache); + DCHECK(web_state_list); DCHECK_CURRENTLY_ON(web::WebThread::UI); task_tracker->PostTaskAndReply( task_runner.get(), FROM_HERE, base::Bind(&web::CertificatePolicyCache::ClearCertificatePolicies, policy_cache), base::Bind(&RestoreCertificatePolicyCacheFromModel, policy_cache, - base::Unretained(tab_model))); + base::Unretained(web_state_list))); } } // anonymous namespace +@interface TabModelWebStateProxyFactory : NSObject<WebStateProxyFactory> +@end + +@implementation TabModelWebStateProxyFactory + +- (id)proxyForWebState:(web::WebState*)webState { + return LegacyTabHelper::GetTabForWebState(webState); +} + +@end + @interface TabModel ()<TabUsageRecorderDelegate> { - // Array of |Tab| objects. - base::scoped_nsobject<NSMutableArray> _tabs; + // Underlying shared model implementation. + WebStateList _webStateList; + + // Helper providing NSFastEnumeration implementation over the WebStateList. + base::scoped_nsobject<WebStateListFastEnumerationHelper> + _fastEnumerationHelper; + + // Used to keep the Tabs alive while the corresponding WebStates are stored + // in the WebStateList (as Tabs currently own their WebState). Remove once + // WebState owns the associated Tab. + base::scoped_nsobject<NSMutableSet<Tab*>> _tabRetainer; + // Maintains policy for where new tabs go and the selection when a tab // is removed. base::scoped_nsobject<TabModelOrderController> _orderController; @@ -214,7 +243,7 @@ } - (void)setCurrentTab:(Tab*)newTab { - DCHECK([_tabs containsObject:newTab]); + DCHECK_NE([self indexOfTab:newTab], static_cast<NSUInteger>(NSNotFound)); if (_currentTab != newTab) { base::RecordAction(base::UserMetricsAction("MobileTabSwitched")); [self updateSnapshotCache:newTab]; @@ -238,19 +267,25 @@ } - (BOOL)isEmpty { - return self.count == 0; + return _webStateList.empty(); } - (NSUInteger)count { - return [_tabs count]; + DCHECK_GE(_webStateList.count(), 0); + return static_cast<NSUInteger>(_webStateList.count()); } - (instancetype)initWithSessionWindow:(SessionWindowIOS*)window sessionService:(SessionServiceIOS*)service browserState:(ios::ChromeBrowserState*)browserState { if ((self = [super init])) { + _tabRetainer.reset([[NSMutableSet alloc] init]); _observers.reset([[TabModelObservers observers] retain]); + _fastEnumerationHelper.reset([[WebStateListFastEnumerationHelper alloc] + initWithWebStateList:&_webStateList + proxyFactory:[[TabModelWebStateProxyFactory alloc] init]]); + _browserState = browserState; DCHECK(_browserState); @@ -267,7 +302,6 @@ } _syncedWindowDelegate.reset(new TabModelSyncedWindowDelegate(self)); - _tabs.reset([[NSMutableArray alloc] init]); if (window) { DCHECK([_observers empty]); // Restore the session and reset the session metrics (as the event have @@ -316,7 +350,7 @@ - (void)saveSessionImmediately:(BOOL)immediately { // Do nothing if there are tabs in the model but no selected tab. This is // a transitional state. - if ((!_currentTab && [_tabs count]) || !_browserState) + if ((!_currentTab && _webStateList.count()) || !_browserState) return; [_sessionService saveWindow:self.windowForSavingSession forBrowserState:_browserState @@ -324,17 +358,24 @@ } - (Tab*)tabAtIndex:(NSUInteger)index { - return [_tabs objectAtIndex:index]; + DCHECK_LE(index, static_cast<NSUInteger>(INT_MAX)); + return LegacyTabHelper::GetTabForWebState( + _webStateList.GetWebStateAt(static_cast<int>(index))); } - (NSUInteger)indexOfTab:(Tab*)tab { - return [_tabs indexOfObject:tab]; + int index = _webStateList.GetIndexOfWebState(tab.webState); + if (index == WebStateList::kInvalidIndex) + return NSNotFound; + + DCHECK_GE(index, 0); + return static_cast<NSUInteger>(index); } - (Tab*)tabWithWindowName:(NSString*)windowName { if (!windowName) return nil; - for (Tab* tab in _tabs.get()) { + for (Tab* tab in self) { if ([windowName isEqualToString:tab.windowName]) { return tab; } @@ -353,8 +394,8 @@ if (startIndex == NSNotFound) return nil; NSString* parentID = tab.tabId; - for (NSUInteger i = startIndex + 1; i < [_tabs count]; ++i) { - Tab* current = [_tabs objectAtIndex:i]; + for (NSUInteger i = startIndex + 1; i < self.count; ++i) { + Tab* current = [self tabAtIndex:i]; DCHECK([current navigationManager]); CRWSessionController* sessionController = [current navigationManager]->GetSessionController(); @@ -379,8 +420,8 @@ // tabs whose opener's id and opener's navigation index match. The navigation // index is used in addition to the session id to detect navigations changes // within the same session. - for (NSUInteger i = startIndex + 1; i < [_tabs count]; ++i) { - Tab* tabToCheck = [_tabs objectAtIndex:i]; + for (NSUInteger i = startIndex + 1; i < self.count; ++i) { + Tab* tabToCheck = [self tabAtIndex:i]; DCHECK([tabToCheck navigationManager]); CRWSessionController* sessionController = [tabToCheck navigationManager]->GetSessionController(); @@ -400,7 +441,7 @@ NSString* openerId = [tab navigationManager]->GetSessionController().openerId; if (!openerId.length) // Short-circuit if opener is empty. return nil; - for (Tab* iteratedTab in _tabs.get()) { + for (Tab* iteratedTab in self) { if ([iteratedTab.tabId isEqualToString:openerId]) return iteratedTab; } @@ -493,10 +534,12 @@ - (void)insertTab:(Tab*)tab atIndex:(NSUInteger)index { DCHECK(tab); - DCHECK(index <= [_tabs count]); + DCHECK(![_tabRetainer containsObject:tab]); + DCHECK_LE(index, static_cast<NSUInteger>(INT_MAX)); [tab fetchFavicon]; - [_tabs insertObject:tab atIndex:index]; + [_tabRetainer addObject:tab]; + _webStateList.InsertWebState(static_cast<int>(index), tab.webState); TabParentingGlobalObserver::GetInstance()->OnTabParented(tab.webState); [_observers tabModel:self didInsertTab:tab atIndex:index inForeground:NO]; [_observers tabModelDidChangeTabCount:self]; @@ -507,36 +550,41 @@ // state properly. If it does eventually become active, another save will // be triggered to properly capture the end result. [self saveSessionImmediately:NO]; + ++_newTabCount; } - (void)moveTab:(Tab*)tab toIndex:(NSUInteger)toIndex { - NSUInteger fromIndex = [self indexOfTab:tab]; - DCHECK_NE(NSNotFound, static_cast<NSInteger>(fromIndex)); - DCHECK_LT(toIndex, self.count); - if (fromIndex == NSNotFound || toIndex >= self.count || - fromIndex == toIndex) { + if ([self tabAtIndex:toIndex] == tab) return; - } - base::scoped_nsobject<Tab> tabSaver([tab retain]); - [_tabs removeObject:tab]; - [_tabs insertObject:tab atIndex:toIndex]; - + DCHECK([_tabRetainer containsObject:tab]); + DCHECK_LE(toIndex, static_cast<NSUInteger>(INT_MAX)); + int fromIndex = _webStateList.GetIndexOfWebState(tab.webState); + _webStateList.MoveWebStateAt(fromIndex, static_cast<int>(toIndex)); [_observers tabModel:self didMoveTab:tab fromIndex:fromIndex toIndex:toIndex]; } - (void)replaceTab:(Tab*)oldTab withTab:(Tab*)newTab { - NSUInteger index = [self indexOfTab:oldTab]; - DCHECK_NE(NSNotFound, static_cast<NSInteger>(index)); + DCHECK([_tabRetainer containsObject:oldTab]); + DCHECK(![_tabRetainer containsObject:newTab]); + + int index = _webStateList.GetIndexOfWebState(oldTab.webState); + DCHECK_NE(index, WebStateList::kInvalidIndex); + DCHECK_GE(index, 0); base::scoped_nsobject<Tab> tabSaver([oldTab retain]); [newTab fetchFavicon]; - [_tabs replaceObjectAtIndex:index withObject:newTab]; + [_tabRetainer removeObject:oldTab]; + [_tabRetainer addObject:newTab]; [newTab setParentTabModel:self]; + _webStateList.ReplaceWebStateAt(index, newTab.webState); TabParentingGlobalObserver::GetInstance()->OnTabParented(newTab.webState); - [_observers tabModel:self didReplaceTab:oldTab withTab:newTab atIndex:index]; + [_observers tabModel:self + didReplaceTab:oldTab + withTab:newTab + atIndex:static_cast<NSUInteger>(index)]; if (self.currentTab == oldTab) [self changeSelectedTabFrom:nil to:newTab persistState:NO]; @@ -550,8 +598,8 @@ } - (void)closeTabAtIndex:(NSUInteger)index { - DCHECK(index < [_tabs count]); - [self closeTab:[_tabs objectAtIndex:index]]; + DCHECK(index < self.count); + [self closeTab:[self tabAtIndex:index]]; } - (void)closeTab:(Tab*)tab { @@ -571,7 +619,7 @@ } - (void)haltAllTabs { - for (Tab* tab in _tabs.get()) { + for (Tab* tab in self) { [tab terminateNetworkActivity]; } } @@ -608,7 +656,7 @@ } - (void)resetAllWebViews { - for (Tab* tab in _tabs.get()) { + for (Tab* tab in self) { [tab.webController reinitializeWebViewAndReload:(tab == _currentTab)]; } } @@ -617,7 +665,7 @@ if (webUsageEnabled_ == webUsageEnabled) return; webUsageEnabled_ = webUsageEnabled; - for (Tab* tab in _tabs.get()) { + for (Tab* tab in self) { tab.webUsageEnabled = webUsageEnabled; } } @@ -632,7 +680,7 @@ if (!_browserState) return referencedFiles; // Check the currently open tabs for external files. - for (Tab* tab in _tabs.get()) { + for (Tab* tab in self) { if (UrlIsExternalFileReference(tab.url)) { NSString* fileName = base::SysUTF8ToNSString(tab.url.ExtractFileName()); [referencedFiles addObject:fileName]; @@ -669,9 +717,12 @@ // Called when a tab is closing, but before its CRWWebController is destroyed. // Equivalent to DetachTabContentsAt() in Chrome's TabStripModel. - (void)didCloseTab:(Tab*)closedTab { - NSUInteger closedTabIndex = [_tabs indexOfObject:closedTab]; DCHECK(closedTab); - DCHECK(closedTabIndex != NSNotFound); + DCHECK([_tabRetainer containsObject:closedTab]); + int closedTabIndex = _webStateList.GetIndexOfWebState(closedTab.webState); + DCHECK_NE(closedTabIndex, WebStateList::kInvalidIndex); + DCHECK_GE(closedTabIndex, 0); + // Let the sessions::TabRestoreService know about that new tab. sessions::TabRestoreService* restoreService = _browserState @@ -683,13 +734,13 @@ if (restoreService && (![self isNTPTab:closedTab] || itemCount > 1)) { restoreService->CreateHistoricalTab( sessions::IOSLiveTab::GetForWebState(closedTab.webState), - static_cast<int>(closedTabIndex)); + closedTabIndex); } // This needs to be called before the tab is removed from the list. Tab* newSelection = [_orderController determineNewSelectedTabFromRemovedTab:closedTab]; + base::scoped_nsobject<Tab> kungFuDeathGrip([closedTab retain]); - [_tabs removeObject:closedTab]; // If closing the current tab, clear |_currentTab| before sending any // notification. This avoids various parts of the code getting confused @@ -698,7 +749,13 @@ if (closedTab == _currentTab) _currentTab.reset(nil); - [_observers tabModel:self didRemoveTab:closedTab atIndex:closedTabIndex]; + DCHECK([_tabRetainer containsObject:closedTab]); + [_tabRetainer removeObject:closedTab]; + + _webStateList.DetachWebStateAt(closedTabIndex); + [_observers tabModel:self + didRemoveTab:closedTab + atIndex:static_cast<NSUInteger>(closedTabIndex)]; [_observers tabModelDidChangeTabCount:self]; // Current tab has closed, update the selected tab and swap in its @@ -745,15 +802,16 @@ - (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState*)state objects:(id*)objects count:(NSUInteger)count { - return [_tabs countByEnumeratingWithState:state objects:objects count:count]; + return [_fastEnumerationHelper countByEnumeratingWithState:state + objects:objects + count:count]; } #pragma mark - TabUsageRecorderDelegate - (NSUInteger)liveTabsCount { NSUInteger count = 0; - NSArray* tabs = _tabs.get(); - for (Tab* tab in tabs) { + for (Tab* tab in self) { if ([tab.webController isViewAlive]) count++; } @@ -924,7 +982,9 @@ if (!sessions.count) return NO; - size_t oldCount = [_tabs count]; + int oldCount = _webStateList.count(); + DCHECK_GE(oldCount, 0); + web::WebState::CreateParams params(_browserState); scoped_refptr<web::CertificatePolicyCache> policyCache = web::BrowserState::GetCertificatePolicyCache(_browserState); @@ -934,19 +994,19 @@ web::WebState::Create(params, session); DCHECK_EQ(webState->GetBrowserState(), _browserState); Tab* tab = - [self insertTabWithWebState:std::move(webState) atIndex:[_tabs count]]; + [self insertTabWithWebState:std::move(webState) atIndex:self.count]; tab.webController.usePlaceholderOverlay = YES; // Restore the CertificatePolicyCache (note that webState is invalid after // passing it via move semantic to -insertTabWithWebState:atIndex:). UpdateCertificatePolicyCacheFromWebState(policyCache, tab.webState); } - DCHECK_GT([_tabs count], oldCount); + DCHECK_GT(_webStateList.count(), oldCount); // Update the selected tab if there was a selected Tab in the saved session. if (window.selectedIndex != NSNotFound) { NSUInteger selectedIndex = window.selectedIndex + oldCount; - DCHECK_LT(selectedIndex, [_tabs count]); + DCHECK_LT(selectedIndex, self.count); DCHECK([self tabAtIndex:selectedIndex]); [self changeSelectedTabFrom:_currentTab to:[self tabAtIndex:selectedIndex] @@ -956,7 +1016,7 @@ // If there was only one tab and it was the new tab page, clobber it. BOOL closedNTPTab = NO; if (oldCount == 1) { - Tab* tab = [_tabs objectAtIndex:0]; + Tab* tab = [self tabAtIndex:0]; if (tab.url == GURL(kChromeUINewTabURL)) { [self closeTab:tab]; closedNTPTab = YES; @@ -964,10 +1024,13 @@ } } if (_tabUsageRecorder) { - _tabUsageRecorder->InitialRestoredTabs( - _currentTab, - [_tabs - subarrayWithRange:NSMakeRange(oldCount, [_tabs count] - oldCount)]); + NSMutableArray<Tab*>* restoredTabs = + [NSMutableArray arrayWithCapacity:_webStateList.count() - oldCount]; + for (int index = oldCount; index < _webStateList.count(); ++index) { + web::WebState* webState = _webStateList.GetWebStateAt(index); + [restoredTabs addObject:LegacyTabHelper::GetTabForWebState(webState)]; + } + _tabUsageRecorder->InitialRestoredTabs(_currentTab, restoredTabs); } return closedNTPTab; } @@ -992,7 +1055,8 @@ CleanCertificatePolicyCache( &_clearPoliciesTaskTracker, web::WebThread::GetTaskRunnerForThread(web::WebThread::IO), - web::BrowserState::GetCertificatePolicyCache(_browserState), self); + web::BrowserState::GetCertificatePolicyCache(_browserState), + &_webStateList); if (_tabUsageRecorder) _tabUsageRecorder->AppDidEnterBackground();
diff --git a/ios/chrome/browser/tabs/tab_model_order_controller_unittest.mm b/ios/chrome/browser/tabs/tab_model_order_controller_unittest.mm index bde32a3..052ef9c 100644 --- a/ios/chrome/browser/tabs/tab_model_order_controller_unittest.mm +++ b/ios/chrome/browser/tabs/tab_model_order_controller_unittest.mm
@@ -86,10 +86,10 @@ IOSChromeScopedTestingChromeBrowserStateManager scoped_browser_state_manager_; base::scoped_nsobject<SessionWindowIOS> sessionWindow_; std::unique_ptr<TestChromeBrowserState> chrome_browser_state_; + base::mac::ScopedNSAutoreleasePool pool_; base::scoped_nsobject<Tab> dummy_tab_; base::scoped_nsobject<TabModelOrderController> orderController_; base::scoped_nsobject<TabModel> tabModel_; - base::mac::ScopedNSAutoreleasePool pool_; }; // Verifies that tabs added in the background (e.g. from context menu -> Open in
diff --git a/ios/chrome/browser/ui/reading_list/resources/reading_list_side_swipe.png b/ios/chrome/browser/ui/reading_list/resources/reading_list_side_swipe.png index 69c1f5a..ef386f07 100644 --- a/ios/chrome/browser/ui/reading_list/resources/reading_list_side_swipe.png +++ b/ios/chrome/browser/ui/reading_list/resources/reading_list_side_swipe.png Binary files differ
diff --git a/ios/chrome/browser/ui/reading_list/resources/reading_list_side_swipe@2x.png b/ios/chrome/browser/ui/reading_list/resources/reading_list_side_swipe@2x.png index b8d99dd..11a90f5a 100644 --- a/ios/chrome/browser/ui/reading_list/resources/reading_list_side_swipe@2x.png +++ b/ios/chrome/browser/ui/reading_list/resources/reading_list_side_swipe@2x.png Binary files differ
diff --git a/ios/chrome/browser/ui/reading_list/resources/reading_list_side_swipe@3x.png b/ios/chrome/browser/ui/reading_list/resources/reading_list_side_swipe@3x.png index 601c28c..e910790 100644 --- a/ios/chrome/browser/ui/reading_list/resources/reading_list_side_swipe@3x.png +++ b/ios/chrome/browser/ui/reading_list/resources/reading_list_side_swipe@3x.png Binary files differ
diff --git a/ios/chrome/share_extension/share_extension_view.mm b/ios/chrome/share_extension/share_extension_view.mm index a072574..3a0e146 100644 --- a/ios/chrome/share_extension/share_extension_view.mm +++ b/ios/chrome/share_extension/share_extension_view.mm
@@ -309,10 +309,13 @@ [navigationBar setTranslucent:YES]; [navigationBar setTranslatesAutoresizingMaskIntoConstraints:NO]; + UIButton* systemButton = [UIButton buttonWithType:UIButtonTypeSystem]; + UIColor* systemColor = [systemButton titleColorForState:UIControlStateNormal]; UIBarButtonItem* cancelButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(cancelPressed:)]; + [cancelButton setTintColor:systemColor]; NSString* appName = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"];
diff --git a/ios/web/BUILD.gn b/ios/web/BUILD.gn index 322051c..5a84a02 100644 --- a/ios/web/BUILD.gn +++ b/ios/web/BUILD.gn
@@ -418,8 +418,6 @@ "public/test/http_server_util.mm", "public/test/js_test_util.h", "public/test/js_test_util.mm", - "public/test/mock_image_data_fetcher.h", - "public/test/mock_image_data_fetcher.mm", "public/test/native_controller_test_util.h", "public/test/native_controller_test_util.mm", "public/test/navigation_test_util.h",
diff --git a/ios/web/public/image_fetcher/BUILD.gn b/ios/web/public/image_fetcher/BUILD.gn index 7c93ce1d..3a1cf83 100644 --- a/ios/web/public/image_fetcher/BUILD.gn +++ b/ios/web/public/image_fetcher/BUILD.gn
@@ -5,14 +5,11 @@ source_set("image_fetcher") { configs += [ "//build/config/compiler:enable_arc" ] sources = [ - "image_data_fetcher.h", - "image_data_fetcher.mm", "webp_decoder.h", "webp_decoder.mm", ] deps = [ "//base", - "//net", "//third_party/libwebp:libwebp_dec", ] } @@ -21,15 +18,12 @@ configs += [ "//build/config/compiler:enable_arc" ] testonly = true sources = [ - "image_data_fetcher_unittest.mm", "webp_decoder_unittest.mm", ] deps = [ ":image_fetcher", ":webp_transcode_unit_tests_bundle_data", "//base", - "//net", - "//net:test_support", "//testing/gmock", "//testing/gtest", ]
diff --git a/ios/web/public/image_fetcher/image_data_fetcher.h b/ios/web/public/image_fetcher/image_data_fetcher.h deleted file mode 100644 index 797a2d3e9..0000000 --- a/ios/web/public/image_fetcher/image_data_fetcher.h +++ /dev/null
@@ -1,96 +0,0 @@ -// Copyright 2011 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 IOS_WEB_PUBLIC_IMAGE_FETCHER_IMAGE_DATA_FETCHER_H_ -#define IOS_WEB_PUBLIC_IMAGE_FETCHER_IMAGE_DATA_FETCHER_H_ - -#include <map> - -#include "base/mac/scoped_block.h" -#include "base/memory/ref_counted.h" -#include "base/memory/weak_ptr.h" -#include "net/url_request/url_fetcher_delegate.h" -#include "net/url_request/url_request.h" - -class GURL; -@class NSData; - -namespace base { -class TaskRunner; -} - -namespace net { -class URLRequestContextGetter; -} - -namespace web { - -// Callback that informs of the download of an image encoded in |data|, -// downloaded from |url|, and with the http status |http_response_code|. If the -// url is a data URL, |http_response_code| is always 200. -using ImageFetchedCallback = void (^)(const GURL& url, - int http_response_code, - NSData* data); - -// Utility class that will retrieve an image from an URL. The image is returned -// as NSData which can be used with +[UIImage imageWithData:]. This class -// usually returns the raw bytes retrieved from the network without any -// processing, with the exception of WebP encoded images. Those are decoded and -// then reencoded in a format suitable for UIImage. -// An instance of this class can download a number of images at the same time. -class ImageDataFetcher : public net::URLFetcherDelegate { - public: - // The TaskRunner is used to eventually decode the image. - explicit ImageDataFetcher(const scoped_refptr<base::TaskRunner>& task_runner); - ~ImageDataFetcher() override; - - // Start downloading the image at the given |url|. The |callback| will be - // called with the downloaded image, or nil if any error happened. The - // |referrer| and |referrer_policy| will be passed on to the underlying - // URLFetcher. - // This method assumes the request context getter has been set. - // (virtual for testing) - virtual void StartDownload(const GURL& url, - ImageFetchedCallback callback, - const std::string& referrer, - net::URLRequest::ReferrerPolicy referrer_policy); - - // Helper method to call StartDownload without a referrer. - // (virtual for testing) - virtual void StartDownload(const GURL& url, ImageFetchedCallback callback); - - // A valid request context getter is required before starting the download. - // (virtual for testing) - virtual void SetRequestContextGetter( - const scoped_refptr<net::URLRequestContextGetter>& - request_context_getter); - - // net::URLFetcherDelegate: - void OnURLFetchComplete(const net::URLFetcher* source) override; - - private: - // Runs the callback with the given arguments. - void RunCallback(const base::mac::ScopedBlock<ImageFetchedCallback>& callback, - const GURL& url, - const int http_response_code, - NSData* data); - - // Tracks open download requests. The key is the URLFetcher object doing the - // fetch; the value is the callback to use when the download request - // completes. When a download request completes, the URLFetcher must be - // deleted and the callback called and released. - std::map<const net::URLFetcher*, ImageFetchedCallback> downloads_in_progress_; - scoped_refptr<net::URLRequestContextGetter> request_context_getter_; - - // The task runner used to decode images if necessary. - const scoped_refptr<base::TaskRunner> task_runner_; - - // The WeakPtrFactory is used to cancel callbacks if ImageDataFetcher is - // destroyed during WebP decoding. - base::WeakPtrFactory<ImageDataFetcher> weak_factory_; -}; - -#endif // IOS_WEB_PUBLIC_IMAGE_FETCHER_IMAGE_DATA_FETCHER_H_ - -} // namespace web
diff --git a/ios/web/public/image_fetcher/image_data_fetcher.mm b/ios/web/public/image_fetcher/image_data_fetcher.mm deleted file mode 100644 index 11a237a..0000000 --- a/ios/web/public/image_fetcher/image_data_fetcher.mm +++ /dev/null
@@ -1,179 +0,0 @@ -// Copyright 2012 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. - -#import "ios/web/public/image_fetcher/image_data_fetcher.h" - -#import <Foundation/Foundation.h> -#include <stddef.h> - -#include "base/bind.h" -#include "base/location.h" -#import "base/mac/scoped_nsobject.h" -#include "base/task_runner.h" -#include "base/task_runner_util.h" -#import "ios/web/public/image_fetcher/webp_decoder.h" -#include "net/base/load_flags.h" -#include "net/http/http_response_headers.h" -#include "net/url_request/url_fetcher.h" -#include "net/url_request/url_request_context_getter.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -namespace { - -class WebpDecoderDelegate : public webp_transcode::WebpDecoder::Delegate { - public: - NSData* data() const { return decoded_image_; } - - // WebpDecoder::Delegate methods - void OnFinishedDecoding(bool success) override { - if (!success) - decoded_image_.reset(); - } - void SetImageFeatures( - size_t total_size, - webp_transcode::WebpDecoder::DecodedImageFormat format) override { - decoded_image_.reset([[NSMutableData alloc] initWithCapacity:total_size]); - } - void OnDataDecoded(NSData* data) override { - DCHECK(decoded_image_); - [decoded_image_ appendData:data]; - } - - private: - ~WebpDecoderDelegate() override {} - base::scoped_nsobject<NSMutableData> decoded_image_; -}; - -// Content-type header for WebP images. -static const char kWEBPMimeType[] = "image/webp"; - -// Returns a NSData object containing the decoded image. -// Returns nil in case of failure. -base::scoped_nsobject<NSData> DecodeWebpImage( - const base::scoped_nsobject<NSData>& webp_image) { - scoped_refptr<WebpDecoderDelegate> delegate(new WebpDecoderDelegate); - scoped_refptr<webp_transcode::WebpDecoder> decoder( - new webp_transcode::WebpDecoder(delegate.get())); - decoder->OnDataReceived(webp_image); - DLOG_IF(ERROR, !delegate->data()) << "WebP image decoding failed."; - return base::scoped_nsobject<NSData>(delegate->data()); -} - -} // namespace - -namespace web { - -ImageDataFetcher::ImageDataFetcher( - const scoped_refptr<base::TaskRunner>& task_runner) - : request_context_getter_(nullptr), - task_runner_(task_runner), - weak_factory_(this) { - DCHECK(task_runner_.get()); -} - -ImageDataFetcher::~ImageDataFetcher() { - // Delete all the entries in the |downloads_in_progress_| map. This will in - // turn cancel all of the requests. - for (const auto& pair : downloads_in_progress_) { - delete pair.first; - } -} - -void ImageDataFetcher::StartDownload( - const GURL& url, - ImageFetchedCallback callback, - const std::string& referrer, - net::URLRequest::ReferrerPolicy referrer_policy) { - DCHECK(request_context_getter_.get()); - net::URLFetcher* fetcher = - net::URLFetcher::Create(url, net::URLFetcher::GET, this).release(); - downloads_in_progress_[fetcher] = [callback copy]; - fetcher->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES | - net::LOAD_DO_NOT_SAVE_COOKIES | - net::LOAD_DO_NOT_SEND_AUTH_DATA); - fetcher->SetRequestContext(request_context_getter_.get()); - fetcher->SetReferrer(referrer); - fetcher->SetReferrerPolicy(referrer_policy); - fetcher->Start(); -} - -void ImageDataFetcher::StartDownload(const GURL& url, - ImageFetchedCallback callback) { - ImageDataFetcher::StartDownload(url, callback, std::string(), - net::URLRequest::NEVER_CLEAR_REFERRER); -} - -// Delegate callback that is called when URLFetcher completes. If the image -// was fetched successfully, creates a new NSData and returns it to the -// callback, otherwise returns nil to the callback. -void ImageDataFetcher::OnURLFetchComplete(const net::URLFetcher* fetcher) { - if (downloads_in_progress_.find(fetcher) == downloads_in_progress_.end()) { - LOG(ERROR) << "Received callback for unknown URLFetcher " << fetcher; - return; - } - - // Ensures that |fetcher| will be deleted in the event of early return. - std::unique_ptr<const net::URLFetcher> fetcher_deleter(fetcher); - - // Retrieves the callback and ensures that it will be deleted in the event - // of early return. - base::mac::ScopedBlock<ImageFetchedCallback> callback( - downloads_in_progress_[fetcher]); - - // Remove |fetcher| from the map. - downloads_in_progress_.erase(fetcher); - - // Make sure the request was successful. For "data" requests, the response - // code has no meaning, because there is no actual server (data is encoded - // directly in the URL). In that case, set the response code to 200 (OK). - const GURL& original_url = fetcher->GetOriginalURL(); - const int http_response_code = - original_url.SchemeIs("data") ? 200 : fetcher->GetResponseCode(); - if (http_response_code != 200) { - (callback.get())(original_url, http_response_code, nil); - return; - } - - std::string response; - if (!fetcher->GetResponseAsString(&response)) { - (callback.get())(original_url, http_response_code, nil); - return; - } - - // Create a NSData from the returned data and notify the callback. - base::scoped_nsobject<NSData> data([[NSData alloc] - initWithBytes:reinterpret_cast<const unsigned char*>(response.data()) - length:response.size()]); - - if (fetcher->GetResponseHeaders()) { - std::string mime_type; - fetcher->GetResponseHeaders()->GetMimeType(&mime_type); - if (mime_type == kWEBPMimeType) { - base::PostTaskAndReplyWithResult( - task_runner_.get(), FROM_HERE, base::Bind(&DecodeWebpImage, data), - base::Bind(&ImageDataFetcher::RunCallback, weak_factory_.GetWeakPtr(), - callback, original_url, http_response_code)); - return; - } - } - (callback.get())(original_url, http_response_code, data); -} - -void ImageDataFetcher::RunCallback( - const base::mac::ScopedBlock<ImageFetchedCallback>& callback, - const GURL& url, - int http_response_code, - NSData* data) { - (callback.get())(url, http_response_code, data); -} - -void ImageDataFetcher::SetRequestContextGetter( - const scoped_refptr<net::URLRequestContextGetter>& request_context_getter) { - request_context_getter_ = request_context_getter; -} - -} // namespace web
diff --git a/ios/web/public/image_fetcher/image_data_fetcher_unittest.mm b/ios/web/public/image_fetcher/image_data_fetcher_unittest.mm deleted file mode 100644 index 72d79419..0000000 --- a/ios/web/public/image_fetcher/image_data_fetcher_unittest.mm +++ /dev/null
@@ -1,212 +0,0 @@ -// Copyright 2011 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. - -#import "ios/web/public/image_fetcher/image_data_fetcher.h" - -#import <UIKit/UIKit.h> - -#include "base/ios/ios_util.h" -#include "base/mac/scoped_block.h" -#include "base/macros.h" -#include "base/memory/ptr_util.h" -#include "base/memory/ref_counted.h" -#include "base/run_loop.h" -#include "base/threading/thread.h" -#include "base/threading/thread_task_runner_handle.h" -#include "build/build_config.h" -#include "net/http/http_response_headers.h" -#include "net/url_request/test_url_fetcher_factory.h" -#include "net/url_request/url_request_test_util.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "testing/platform_test.h" - -namespace { - -static unsigned char kJPGImage[] = { - 255, 216, 255, 224, 0, 16, 74, 70, 73, 70, 0, 1, 1, 1, 0, - 72, 0, 72, 0, 0, 255, 254, 0, 19, 67, 114, 101, 97, 116, 101, - 100, 32, 119, 105, 116, 104, 32, 71, 73, 77, 80, 255, 219, 0, 67, - 0, 5, 3, 4, 4, 4, 3, 5, 4, 4, 4, 5, 5, 5, 6, - 7, 12, 8, 7, 7, 7, 7, 15, 11, 11, 9, 12, 17, 15, 18, - 18, 17, 15, 17, 17, 19, 22, 28, 23, 19, 20, 26, 21, 17, 17, - 24, 33, 24, 26, 29, 29, 31, 31, 31, 19, 23, 34, 36, 34, 30, - 36, 28, 30, 31, 30, 255, 219, 0, 67, 1, 5, 5, 5, 7, 6, - 7, 14, 8, 8, 14, 30, 20, 17, 20, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 255, - 192, 0, 17, 8, 0, 1, 0, 1, 3, 1, 34, 0, 2, 17, 1, - 3, 17, 1, 255, 196, 0, 21, 0, 1, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 255, 196, 0, 20, - 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 255, 196, 0, 20, 1, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 196, 0, 20, 17, - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 255, 218, 0, 12, 3, 1, 0, 2, 17, 3, 17, 0, 63, - 0, 178, 192, 7, 255, 217}; - -static unsigned char kPNGImage[] = { - 137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, - 82, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 55, - 110, 249, 36, 0, 0, 0, 2, 98, 75, 71, 68, 0, 1, 221, 138, - 19, 164, 0, 0, 0, 9, 112, 72, 89, 115, 0, 0, 11, 18, 0, - 0, 11, 18, 1, 210, 221, 126, 252, 0, 0, 0, 9, 118, 112, 65, - 103, 0, 0, 0, 1, 0, 0, 0, 1, 0, 199, 149, 95, 237, 0, - 0, 0, 10, 73, 68, 65, 84, 8, 215, 99, 104, 0, 0, 0, 130, - 0, 129, 221, 67, 106, 244, 0, 0, 0, 25, 116, 69, 88, 116, 99, - 111, 109, 109, 101, 110, 116, 0, 67, 114, 101, 97, 116, 101, 100, 32, - 119, 105, 116, 104, 32, 71, 73, 77, 80, 231, 175, 64, 203, 0, 0, - 0, 37, 116, 69, 88, 116, 100, 97, 116, 101, 58, 99, 114, 101, 97, - 116, 101, 0, 50, 48, 49, 49, 45, 48, 54, 45, 50, 50, 84, 49, - 54, 58, 49, 54, 58, 52, 54, 43, 48, 50, 58, 48, 48, 31, 248, - 231, 223, 0, 0, 0, 37, 116, 69, 88, 116, 100, 97, 116, 101, 58, - 109, 111, 100, 105, 102, 121, 0, 50, 48, 49, 49, 45, 48, 54, 45, - 50, 50, 84, 49, 54, 58, 49, 54, 58, 52, 54, 43, 48, 50, 58, - 48, 48, 110, 165, 95, 99, 0, 0, 0, 17, 116, 69, 88, 116, 106, - 112, 101, 103, 58, 99, 111, 108, 111, 114, 115, 112, 97, 99, 101, 0, - 50, 44, 117, 85, 159, 0, 0, 0, 32, 116, 69, 88, 116, 106, 112, - 101, 103, 58, 115, 97, 109, 112, 108, 105, 110, 103, 45, 102, 97, 99, - 116, 111, 114, 0, 50, 120, 50, 44, 49, 120, 49, 44, 49, 120, 49, - 73, 250, 166, 180, 0, 0, 0, 0, 73, 69, 78, 68, 174, 66, 96, - 130}; - -static unsigned char kWEBPImage[] = { - 82, 73, 70, 70, 74, 0, 0, 0, 87, 69, 66, 80, 86, 80, 56, 88, 10, - 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 65, 76, 80, 72, - 12, 0, 0, 0, 1, 7, 16, 17, 253, 15, 68, 68, 255, 3, 0, 0, 86, - 80, 56, 32, 24, 0, 0, 0, 48, 1, 0, 157, 1, 42, 1, 0, 1, 0, - 3, 0, 52, 37, 164, 0, 3, 112, 0, 254, 251, 253, 80, 0}; - -static const char kTestUrl[] = "http://www.img.com"; - -static const char kWEBPHeaderResponse[] = - "HTTP/1.1 200 OK\0Content-type: image/webp\0\0"; - -} // namespace - -namespace web { - -class ImageDataFetcherTest : public PlatformTest { - protected: - ImageDataFetcherTest() - : worker_thread_("TestThread"), - callback_( - [^(const GURL& original_url, int http_response_code, NSData* data) { - result_ = [UIImage imageWithData:data]; - called_ = true; - } copy]) { - worker_thread_.Start(); - - image_fetcher_ = - base::MakeUnique<ImageDataFetcher>(worker_thread_.task_runner()); - image_fetcher_->SetRequestContextGetter( - new net::TestURLRequestContextGetter( - base::ThreadTaskRunnerHandle::Get())); - } - - net::TestURLFetcher* SetupFetcher() { - image_fetcher_->StartDownload(GURL(kTestUrl), callback_); - EXPECT_EQ(nil, result_); - EXPECT_EQ(false, called_); - net::TestURLFetcher* fetcher = factory_.GetFetcherByID(0); - DCHECK(fetcher); - DCHECK(fetcher->delegate()); - return fetcher; - } - - // Message loop for the main test thread. - base::MessageLoop loop_; - - // Worker thread used for ImageFetcher's asynchronous work. - base::Thread worker_thread_; - - base::mac::ScopedBlock<ImageFetchedCallback> callback_; - net::TestURLFetcherFactory factory_; - std::unique_ptr<ImageDataFetcher> image_fetcher_; - UIImage* result_ = nil; - bool called_ = false; - - private: - DISALLOW_COPY_AND_ASSIGN(ImageDataFetcherTest); -}; - -TEST_F(ImageDataFetcherTest, TestError) { - net::TestURLFetcher* fetcher = SetupFetcher(); - fetcher->set_response_code(404); - fetcher->delegate()->OnURLFetchComplete(fetcher); - EXPECT_EQ(nil, result_); - EXPECT_TRUE(called_); -} - -TEST_F(ImageDataFetcherTest, TestJpg) { - net::TestURLFetcher* fetcher = SetupFetcher(); - fetcher->set_response_code(200); - fetcher->SetResponseString(std::string((char*)kJPGImage, sizeof(kJPGImage))); - fetcher->delegate()->OnURLFetchComplete(fetcher); - EXPECT_NE(nil, result_); - EXPECT_TRUE(called_); -} - -TEST_F(ImageDataFetcherTest, TestPng) { - net::TestURLFetcher* fetcher = SetupFetcher(); - fetcher->set_response_code(200); - fetcher->SetResponseString(std::string((char*)kPNGImage, sizeof(kPNGImage))); - fetcher->delegate()->OnURLFetchComplete(fetcher); - EXPECT_NE(nil, result_); - EXPECT_TRUE(called_); -} - -TEST_F(ImageDataFetcherTest, TestGoodWebP) { - net::TestURLFetcher* fetcher = SetupFetcher(); - fetcher->set_response_code(200); - fetcher->SetResponseString( - std::string((char*)kWEBPImage, sizeof(kWEBPImage))); - scoped_refptr<net::HttpResponseHeaders> headers(new net::HttpResponseHeaders( - std::string(kWEBPHeaderResponse, arraysize(kWEBPHeaderResponse)))); - fetcher->set_response_headers(headers); - fetcher->delegate()->OnURLFetchComplete(fetcher); - worker_thread_.FlushForTesting(); - base::RunLoop().RunUntilIdle(); - EXPECT_NE(nil, result_); - EXPECT_TRUE(called_); -} - -TEST_F(ImageDataFetcherTest, TestBadWebP) { - net::TestURLFetcher* fetcher = SetupFetcher(); - fetcher->set_response_code(200); - fetcher->SetResponseString("This is not a valid WebP image"); - scoped_refptr<net::HttpResponseHeaders> headers(new net::HttpResponseHeaders( - std::string(kWEBPHeaderResponse, arraysize(kWEBPHeaderResponse)))); - fetcher->set_response_headers(headers); - fetcher->delegate()->OnURLFetchComplete(fetcher); - worker_thread_.FlushForTesting(); - base::RunLoop().RunUntilIdle(); - EXPECT_EQ(nil, result_); - EXPECT_TRUE(called_); -} - -TEST_F(ImageDataFetcherTest, DeleteDuringWebPDecoding) { - net::TestURLFetcher* fetcher = SetupFetcher(); - fetcher->set_response_code(200); - fetcher->SetResponseString( - std::string((char*)kWEBPImage, sizeof(kWEBPImage))); - scoped_refptr<net::HttpResponseHeaders> headers(new net::HttpResponseHeaders( - std::string(kWEBPHeaderResponse, arraysize(kWEBPHeaderResponse)))); - fetcher->set_response_headers(headers); - fetcher->delegate()->OnURLFetchComplete(fetcher); - // Delete the image fetcher, and check that the callback is not called. - image_fetcher_.reset(); - worker_thread_.FlushForTesting(); - base::RunLoop().RunUntilIdle(); - EXPECT_EQ(nil, result_); - EXPECT_FALSE(called_); -} - -TEST_F(ImageDataFetcherTest, TestCallbacksNotCalledDuringDeletion) { - image_fetcher_->StartDownload(GURL(kTestUrl), callback_); - image_fetcher_.reset(); - EXPECT_FALSE(called_); -} - -} // namespace web
diff --git a/ios/web/public/test/mock_image_data_fetcher.h b/ios/web/public/test/mock_image_data_fetcher.h deleted file mode 100644 index 65e7b40..0000000 --- a/ios/web/public/test/mock_image_data_fetcher.h +++ /dev/null
@@ -1,36 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef IOS_WEB_PUBLIC_TEST_MOCK_IMAGE_DATA_FETCHER_H_ -#define IOS_WEB_PUBLIC_TEST_MOCK_IMAGE_DATA_FETCHER_H_ - -#import "ios/web/public/image_fetcher/image_data_fetcher.h" - -#include "testing/gmock/include/gmock/gmock.h" - -namespace web { - -// Mocks the ImageDataFetcher utility class, which can be used to asynchronously -// retrieve an image from an URL. -class MockImageDataFetcher : public ImageDataFetcher { - public: - explicit MockImageDataFetcher( - const scoped_refptr<base::TaskRunner>& task_runner); - ~MockImageDataFetcher() override; - - MOCK_METHOD4(StartDownload, - void(const GURL& url, - ImageFetchedCallback callback, - const std::string& referrer, - net::URLRequest::ReferrerPolicy referrer_policy)); - MOCK_METHOD2(StartDownload, - void(const GURL& url, ImageFetchedCallback callback)); - MOCK_METHOD1(SetRequestContextGetter, - void(const scoped_refptr<net::URLRequestContextGetter>& - request_context_getter)); -}; - -} // namespace web - -#endif // IOS_WEB_PUBLIC_TEST_MOCK_IMAGE_DATA_FETCHER_H_
diff --git a/ios/web/public/test/mock_image_data_fetcher.mm b/ios/web/public/test/mock_image_data_fetcher.mm deleted file mode 100644 index fbdfd57..0000000 --- a/ios/web/public/test/mock_image_data_fetcher.mm +++ /dev/null
@@ -1,15 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import "ios/web/public/test/mock_image_data_fetcher.h" - -namespace web { - -MockImageDataFetcher::MockImageDataFetcher( - const scoped_refptr<base::TaskRunner>& task_runner) - : ImageDataFetcher(task_runner) {} - -MockImageDataFetcher::~MockImageDataFetcher() {} - -} // namespace web
diff --git a/media/capture/content/OWNERS b/media/capture/content/OWNERS index 02bdb39..980d5f2 100644 --- a/media/capture/content/OWNERS +++ b/media/capture/content/OWNERS
@@ -1 +1,3 @@ miu@chromium.org + +# COMPONENT: UI>Browser>TabCapture
diff --git a/media/cast/OWNERS b/media/cast/OWNERS index 586a2f54..41c70ee 100644 --- a/media/cast/OWNERS +++ b/media/cast/OWNERS
@@ -1,2 +1,4 @@ hubbe@chromium.org miu@chromium.org + +# COMPONENT: Internals>Cast>Streaming
diff --git a/media/remoting/OWNERS b/media/remoting/OWNERS index 98698443..e85c2ba 100644 --- a/media/remoting/OWNERS +++ b/media/remoting/OWNERS
@@ -1,2 +1,4 @@ erickung@chromium.org miu@chromium.org + +# COMPONENT: Internals>Cast>Streaming
diff --git a/net/proxy/polling_proxy_config_service.cc b/net/proxy/polling_proxy_config_service.cc index defe507..af6fc9cb 100644 --- a/net/proxy/polling_proxy_config_service.cc +++ b/net/proxy/polling_proxy_config_service.cc
@@ -11,8 +11,8 @@ #include "base/observer_list.h" #include "base/single_thread_task_runner.h" #include "base/synchronization/lock.h" +#include "base/task_scheduler/post_task.h" #include "base/threading/thread_task_runner_handle.h" -#include "base/threading/worker_pool.h" #include "net/proxy/proxy_config.h" namespace net { @@ -90,17 +90,17 @@ last_poll_time_ = base::TimeTicks::Now(); poll_task_outstanding_ = true; poll_task_queued_ = false; - base::WorkerPool::PostTask( - FROM_HERE, - base::Bind(&Core::PollOnWorkerThread, this, get_config_func_), - true); + base::PostTaskWithTraits( + FROM_HERE, base::TaskTraits().MayBlock().WithShutdownBehavior( + base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN), + base::Bind(&Core::PollAsync, this, get_config_func_)); } private: friend class base::RefCountedThreadSafe<Core>; ~Core() {} - void PollOnWorkerThread(GetConfigFunction func) { + void PollAsync(GetConfigFunction func) { ProxyConfig config; func(&config);
diff --git a/net/url_request/url_request_context_builder_unittest.cc b/net/url_request/url_request_context_builder_unittest.cc index cd8f21d..dabd8c5 100644 --- a/net/url_request/url_request_context_builder_unittest.cc +++ b/net/url_request/url_request_context_builder_unittest.cc
@@ -7,7 +7,9 @@ #include <memory> #include "base/memory/ptr_util.h" +#include "base/message_loop/message_loop.h" #include "base/run_loop.h" +#include "base/test/scoped_task_scheduler.h" #include "build/build_config.h" #include "net/base/request_priority.h" #include "net/http/http_auth_challenge_tokenizer.h" @@ -58,7 +60,8 @@ class URLRequestContextBuilderTest : public PlatformTest { protected: - URLRequestContextBuilderTest() { + URLRequestContextBuilderTest() + : scoped_task_scheduler_(base::MessageLoop::current()) { test_server_.AddDefaultHandlers( base::FilePath(FILE_PATH_LITERAL("net/data/url_request_unittest"))); #if defined(OS_LINUX) || defined(OS_ANDROID) @@ -69,6 +72,9 @@ EmbeddedTestServer test_server_; URLRequestContextBuilder builder_; + + private: + base::test::ScopedTaskScheduler scoped_task_scheduler_; }; TEST_F(URLRequestContextBuilderTest, DefaultSettings) {
diff --git a/sandbox/linux/OWNERS b/sandbox/linux/OWNERS index c05fa11..84977847 100644 --- a/sandbox/linux/OWNERS +++ b/sandbox/linux/OWNERS
@@ -5,3 +5,6 @@ # Emeritus mdempsky@chromium.org rickyz@chromium.org + +# TEAM: security-dev@chromium.org +# COMPONENT: Internals>Sandbox
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations index 2c4cc74c..13a3833 100644 --- a/third_party/WebKit/LayoutTests/TestExpectations +++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -1847,9 +1847,14 @@ crbug.com/688854 external/wpt/hr-time/window-worker-time-origin.html [ Failure ] # 2017-02-14: These directories were just imported but expectations and baselines haven't been set yet. -crbug.com/692105 external/wpt/referrer-policy [ Skip ] crbug.com/692105 external/wpt/mixed-content [ Skip ] +# These policies are not implemented yet. +crbug.com/627968 external/wpt/referrer-policy/origin-when-cross-origin/http-rp/same-origin/ [ Skip ] +crbug.com/627968 external/wpt/referrer-policy/same-origin/ [ Skip ] +crbug.com/627968 external/wpt/referrer-policy/strict-origin/ [ Skip ] +crbug.com/627968 external/wpt/referrer-policy/strict-origin-when-cross-origin/ [ Skip ] + # ====== New tests from w3c-test-autoroller added here ====== crbug.com/626703 external/wpt/webvtt/rendering/cues-with-video/processing-model/2_cues_overlapping_completely_move_up.html [ Failure ] crbug.com/626703 external/wpt/webvtt/rendering/cues-with-video/processing-model/2_cues_overlapping_partially_move_down.html [ Failure ] @@ -1909,6 +1914,8 @@ crbug.com/626703 external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/white-space_pre-wrap_wrapped.html [ Failure ] crbug.com/626703 external/wpt/webvtt/rendering/cues-with-video/processing-model/too_many_cues.html [ Failure ] crbug.com/626703 external/wpt/webvtt/rendering/cues-with-video/processing-model/too_many_cues_wrapped.html [ Failure ] +crbug.com/626703 external/wpt/referrer-policy/generic/subresource-test/image-decoding.html [ Timeout ] +crbug.com/626703 external/wpt/referrer-policy/generic/unsupported-csp-referrer-directive.html [ Timeout ] crbug.com/626703 external/wpt/streams/writable-streams/close.dedicatedworker.html [ Timeout ] crbug.com/626703 external/wpt/streams/writable-streams/close.html [ Timeout ] crbug.com/626703 external/wpt/streams/writable-streams/close.serviceworker.https.html [ Timeout ]
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/canvas-drawImage-shadow.html b/third_party/WebKit/LayoutTests/fast/canvas/canvas-drawImage-shadow.html index b4f72581..fc46ba6 100644 --- a/third_party/WebKit/LayoutTests/fast/canvas/canvas-drawImage-shadow.html +++ b/third_party/WebKit/LayoutTests/fast/canvas/canvas-drawImage-shadow.html
@@ -18,7 +18,6 @@ // Create the image object to be drawn on the master canvas. var img = new Image(); -img.onload = drawImageToCanvasAndCheckPixels; img.src = aCanvas.toDataURL(); // set a data URI of the base64 enconded image as the source // Create master canvas. @@ -28,6 +27,34 @@ canvas.setAttribute('height', '600'); var ctx = canvas.getContext('2d'); +var testScenarios = [ + ['Test solid shadow 1', 260, 300, [0, 0, 0, 0]], + ['Test solid shadow 2', 350, 100, [240, 50, 50, 255]], + ['Test solid shadow 3', 400, 200, [240, 50, 50, 255]], + ['Test solid shadow 4', 490, 65, [0, 0, 0, 0]], + ['Test solid shadow 5', 485, 65, [0, 0, 0, 0]], + + ['Test blurry shadow 1', 260, 400, [0, 0, 0, 0]], + ['Test blurry shadow 2', 350, 300, [0, 0, 255, 'neq', 255]], + ['Test blurry shadow 3', 300, 400, [0, 0, 255, 'neq', 255]], + ['Test blurry shadow 4', 300, 500, [0, 0, 255, 'neq', 255]], + ['Test blurry shadow 5', 400, 500, [0, 0, 255, 'neq', 255]], + ['Test blurry shadow 6', 400, 400, [0, 0, 255]], + ['Test blurry shadow 7', 490, 315, [0, 0, 0, 0]], + ['Test blurry shadow 8', 485, 320, [0, 0, 0, 0]], +]; + +function runTestScenario(x, y, expectedColor) +{ + imageData = ctx.getImageData(x, y, 1, 1).data; + if (expectedColor.length == 5) { + assert_array_equals(imageData.slice(0,3), expectedColor.slice(0,3)); + assert_not_equals(imageData[3], expectedColor[4]); + } else { + assert_array_equals(imageData.slice(0, expectedColor.length), expectedColor); + } +} + function drawImageToCanvasAndCheckPixels() { ctx.shadowOffsetX = 250; ctx.shadowColor = 'rgba(240, 50, 50, 1.0)'; @@ -39,106 +66,16 @@ ctx.shadowColor = 'rgba(0, 0, 255, 1.0)'; ctx.drawImage(img, 50, 300); - checkPixels(); -} + for (var i = 0; i < testScenarios.length; i++) + runTestScenario(testScenarios[i][1], + testScenarios[i][2], + testScenarios[i][3]);} -function checkPixels() { - test(function(t) { - var imageData, data; - - // Verify solid shadow. - imageData = ctx.getImageData(260, 300, 1, 1); - d = imageData.data; - assert_equals(d[0], 0); - assert_equals(d[1], 0); - assert_equals(d[2], 0); - assert_equals(d[3], 0); - - imageData = ctx.getImageData(350, 100, 1, 1); - d = imageData.data; - assert_equals(d[0], 240); - assert_equals(d[1], 50); - assert_equals(d[2], 50); - assert_equals(d[3], 255); - - imageData = ctx.getImageData(400, 200, 1, 1); - d = imageData.data; - assert_equals(d[0], 240); - assert_equals(d[1], 50); - assert_equals(d[2], 50); - assert_equals(d[3], 255); - - imageData = ctx.getImageData(490, 65, 1, 1); - d = imageData.data; - assert_equals(d[0], 0); - assert_equals(d[1], 0); - assert_equals(d[2], 0); - assert_equals(d[3], 0); - - imageData = ctx.getImageData(485, 65, 1, 1); - d = imageData.data; - assert_equals(d[0], 0); - assert_equals(d[1], 0); - assert_equals(d[2], 0); - assert_equals(d[3], 0); - - // Verify blurry shadow. - imageData = ctx.getImageData(260, 400, 1, 1); - d = imageData.data; - assert_equals(d[0], 0); - assert_equals(d[1], 0); - assert_equals(d[2], 0); - assert_equals(d[3], 0); - - imageData = ctx.getImageData(350, 300, 1, 1); - d = imageData.data; - assert_equals(d[0], 0); - assert_equals(d[1], 0); - assert_equals(d[2], 255); - assert_not_equals(d[3], 255); - - imageData = ctx.getImageData(300, 400, 1, 1); - d = imageData.data; - assert_equals(d[0], 0); - assert_equals(d[1], 0); - assert_equals(d[2], 255); - assert_not_equals(d[3], 255); - - imageData = ctx.getImageData(300, 500, 1, 1); - d = imageData.data; - assert_equals(d[0], 0); - assert_equals(d[1], 0); - assert_equals(d[2], 255); - assert_not_equals(d[3], 255); - - imageData = ctx.getImageData(400, 500, 1, 1); - d = imageData.data; - assert_equals(d[0], 0); - assert_equals(d[1], 0); - assert_equals(d[2], 255); - assert_not_equals(d[3], 255); - - imageData = ctx.getImageData(400, 400, 1, 1); - d = imageData.data; - assert_equals(d[0], 0); - assert_equals(d[1], 0); - assert_equals(d[2], 255); - - imageData = ctx.getImageData(490, 315, 1, 1); - d = imageData.data; - assert_equals(d[0], 0); - assert_equals(d[1], 0); - assert_equals(d[2], 0); - assert_equals(d[3], 0); - - imageData = ctx.getImageData(485, 320, 1, 1); - d = imageData.data; - assert_equals(d[0], 0); - assert_equals(d[1], 0); - assert_equals(d[2], 0); - assert_equals(d[3], 0); - - }, "Ensure correct behavior of canvas with image shadow. A square with a cut-out top-right corner should be displayed with solid shadow (top) and blur shadow (bottom)."); -} +async_test(t => { + img.onload = function() { + t.step(drawImageToCanvasAndCheckPixels); + t.done(); + } +}, "Ensure correct behavior of canvas with image shadow. A square with a cut-out top-right corner should be displayed with solid shadow (top) and blur shadow (bottom)."); </script> </body>
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/canvas-quadratic-same-endpoint-expected.txt b/third_party/WebKit/LayoutTests/fast/canvas/canvas-quadratic-same-endpoint-expected.txt deleted file mode 100644 index 3625dcb7..0000000 --- a/third_party/WebKit/LayoutTests/fast/canvas/canvas-quadratic-same-endpoint-expected.txt +++ /dev/null
@@ -1,11 +0,0 @@ -Bug 105650: Test correct rendering of quadratic and bezier curves with coincident endpoints - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - - -PASS blue_value is 255 -PASS blue_value is 0 -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/canvas-quadratic-same-endpoint.html b/third_party/WebKit/LayoutTests/fast/canvas/canvas-quadratic-same-endpoint.html index a6becb96..5147b9a 100644 --- a/third_party/WebKit/LayoutTests/fast/canvas/canvas-quadratic-same-endpoint.html +++ b/third_party/WebKit/LayoutTests/fast/canvas/canvas-quadratic-same-endpoint.html
@@ -1,44 +1,40 @@ -<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> -<html> -<head> -<script src="../../resources/js-test.js"></script> -</head> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> <body> <canvas id="canvas" width="100" height="100"></canvas> <script> -description("Bug 105650: Test correct rendering of quadratic and bezier curves with coincident endpoints"); var ctx = document.getElementById('canvas').getContext('2d'); -var data; -function shouldBeYellow(x,y) +function shouldBeYellow(x, y) { - blue_value = ctx.getImageData(x, y, 1, 1).data[2]; - shouldBe("blue_value", "0"); + blue_value = ctx.getImageData(x, y, 1, 1).data[2]; + assert_equals(blue_value, 0); } -function shouldBeBlue(x,y) +function shouldBeBlue(x, y) { - blue_value = ctx.getImageData(x, y, 1, 1).data[2]; - shouldBe("blue_value", "255"); + blue_value = ctx.getImageData(x, y, 1, 1).data[2]; + assert_equals(blue_value, 255); } -ctx.fillStyle = '#00f'; -ctx.strokeStyle = '#ff0'; -ctx.lineWidth = 30; - -ctx.beginPath(); -ctx.fillRect(0,0,100,100); - -// quadratic with coincident endpoint -ctx.moveTo(20,20); - -//Next line should be close to ctx.bezierCurveTo(81,80,80,80,20,20); -ctx.quadraticCurveTo(110,110,20,20); - -shouldBeBlue(70,70); -ctx.stroke(); -shouldBeYellow(70,70); +test(function(t) { + ctx.fillStyle = '#00f'; + ctx.strokeStyle = '#ff0'; + ctx.lineWidth = 30; + + ctx.beginPath(); + ctx.fillRect(0, 0, 100, 100); + + // quadratic with coincident endpoint + ctx.moveTo(20, 20); + + //Next line should be close to ctx.bezierCurveTo(81, 80, 80, 80, 20, 20); + ctx.quadraticCurveTo(110, 110, 20, 20); + + shouldBeBlue(70, 70); + ctx.stroke(); + shouldBeYellow(70, 70); +}, "Bug 105650: Test correct rendering of quadratic and bezier curves with coincident endpoints"); </script> </body> -</html>
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/canvas-radial-gradient-spreadMethod-expected.txt b/third_party/WebKit/LayoutTests/fast/canvas/canvas-radial-gradient-spreadMethod-expected.txt deleted file mode 100644 index c3bcf64..0000000 --- a/third_party/WebKit/LayoutTests/fast/canvas/canvas-radial-gradient-spreadMethod-expected.txt +++ /dev/null
@@ -1,13 +0,0 @@ -Series of tests to ensure correct behaviour of spreadMethod to a radial gradient. - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - - -PASS imgdata[4] is 0 -PASS imgdata[5] is 128 -PASS imgdata[6] is 0 -PASS imgdata[7] is 255 -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/canvas-radial-gradient-spreadMethod.html b/third_party/WebKit/LayoutTests/fast/canvas/canvas-radial-gradient-spreadMethod.html index b736225..cea3732 100644 --- a/third_party/WebKit/LayoutTests/fast/canvas/canvas-radial-gradient-spreadMethod.html +++ b/third_party/WebKit/LayoutTests/fast/canvas/canvas-radial-gradient-spreadMethod.html
@@ -1,9 +1,16 @@ -<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> -<html> -<head> -<script src="../../resources/js-test.js"></script> -</head> -<body> -<script src="canvas-radial-gradient-spreadMethod.js"></script> -</body> -</html> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<script> +test(function(t) { + var ctx = document.createElement('canvas').getContext('2d'); + + var radgrad = ctx.createRadialGradient(80, 90, 90, 80, 50, 100); + radgrad.addColorStop(0, 'green'); + radgrad.addColorStop(1, 'green'); + + ctx.fillStyle = radgrad; + ctx.fillRect(0, 0, 100, 100); + var imageData = ctx.getImageData(0, 0, 100, 100).data; + assert_array_equals(imageData.slice(4, 8), [0, 128, 0, 255]); +}, "Verify correct behaviour of spreadMethod to a radial gradient."); +</script>
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/canvas-radial-gradient-spreadMethod.js b/third_party/WebKit/LayoutTests/fast/canvas/canvas-radial-gradient-spreadMethod.js deleted file mode 100644 index 258c9479..0000000 --- a/third_party/WebKit/LayoutTests/fast/canvas/canvas-radial-gradient-spreadMethod.js +++ /dev/null
@@ -1,15 +0,0 @@ -description("Series of tests to ensure correct behaviour of spreadMethod to a radial gradient."); -var ctx = document.createElement('canvas').getContext('2d'); - -var radgrad = ctx.createRadialGradient(80,90,90,80,50,100); -radgrad.addColorStop(0, 'green'); -radgrad.addColorStop(1, 'green'); - -ctx.fillStyle = radgrad; -ctx.fillRect(0, 0, 100, 100); -var imageData = ctx.getImageData(0, 0, 100, 100); -var imgdata = imageData.data; -shouldBe("imgdata[4]", "0"); -shouldBe("imgdata[5]", "128"); -shouldBe("imgdata[6]", "0"); -shouldBe("imgdata[7]", "255");
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/canvas-resetTransform-expected.txt b/third_party/WebKit/LayoutTests/fast/canvas/canvas-resetTransform-expected.txt deleted file mode 100644 index 800c5b3..0000000 --- a/third_party/WebKit/LayoutTests/fast/canvas/canvas-resetTransform-expected.txt +++ /dev/null
@@ -1,36 +0,0 @@ -This test checks resetTransform in canvas v5 - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - - -resetTransform should reset other transforms. -PASS imgdata[0] is 0 -PASS imgdata[1] is 128 -PASS imgdata[2] is 0 -resetTransform should not affect CTM outside of save() and restore(). -PASS imgdata[0] is 0 -PASS imgdata[1] is 128 -PASS imgdata[2] is 0 -PASS imgdata[0] is 255 -PASS imgdata[1] is 0 -PASS imgdata[2] is 0 -resetTransform should restore the path transform to identity. -PASS imgdata[0] is 0 -PASS imgdata[1] is 128 -PASS imgdata[2] is 0 -resetTransform should resolve the non-invertible CTM state. -PASS imgdata[0] is 0 -PASS imgdata[1] is 128 -PASS imgdata[2] is 0 -The path object should not be updated on the non-invertible CTM state. -resetTransform should restore the path object just before CTM became non-invertible. -PASS imgdata[0] is 255 -PASS imgdata[1] is 0 -PASS imgdata[2] is 0 -PASS imgdata[0] is 0 -PASS imgdata[1] is 128 -PASS imgdata[2] is 0 -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/canvas-resetTransform.html b/third_party/WebKit/LayoutTests/fast/canvas/canvas-resetTransform.html index fe2d369d..f689b71 100644 --- a/third_party/WebKit/LayoutTests/fast/canvas/canvas-resetTransform.html +++ b/third_party/WebKit/LayoutTests/fast/canvas/canvas-resetTransform.html
@@ -1,9 +1,97 @@ -<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> -<html> -<head> -<script src="../../resources/js-test.js"></script> -</head> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> <body> -<script src="script-tests/canvas-resetTransform.js"></script> +<script> +test(function(t) { + + var canvas = document.createElement('canvas'); + document.body.appendChild(canvas); + canvas.setAttribute('width', '100'); + canvas.setAttribute('height', '100'); + var ctx = canvas.getContext('2d'); + + ctx.save(); + ctx.scale(0.5, 0.5); + ctx.resetTransform(); + ctx.fillStyle = 'green'; + ctx.fillRect(0, 0, 100, 100); + ctx.restore(); + + var imageData = ctx.getImageData(98, 98, 1, 1).data; + assert_array_equals(imageData.slice(0, 3), [0, 128, 0]); + + ctx.save(); + ctx.scale(0.5, 0.5); + ctx.save(); + ctx.resetTransform(); + ctx.fillStyle = 'green'; + ctx.fillRect(0, 0, 100, 100); + ctx.restore(); + ctx.fillStyle = 'red'; + ctx.fillRect(0, 0, 100, 100); + ctx.restore(); + + imageData = ctx.getImageData(98, 98, 1, 1).data; + assert_array_equals(imageData.slice(0, 3), [0, 128, 0]); + + imageData = ctx.getImageData(48, 48, 1, 1).data; + assert_array_equals(imageData.slice(0, 3), [255, 0, 0]); + + /* This should draw a green rectangle on on top of a red one. The red should not be visible. */ + ctx.save(); + ctx.beginPath(); + ctx.moveTo(0, 0); + ctx.lineTo(100, 0); + ctx.lineTo(100, 100); + ctx.lineTo(0, 100); + ctx.fillStyle = 'red'; + ctx.fill(); + ctx.translate(200, 0); + ctx.resetTransform(); + ctx.fillStyle = 'green'; + ctx.fill(); + ctx.restore(); + + imageData = ctx.getImageData(50, 50, 1, 1).data; + assert_array_equals(imageData.slice(0, 3), [0, 128, 0]); + + ctx.save(); + ctx.fillStyle = 'red'; + ctx.fillRect(0, 0, 100, 100); + ctx.beginPath(); + ctx.moveTo(0, 0); + ctx.lineTo(100, 0); + ctx.lineTo(100, 100); + ctx.lineTo(0, 100); + ctx.scale(0, 0); + ctx.resetTransform(); + ctx.fillStyle = 'green'; + ctx.fill(); + ctx.restore(); + + imageData = ctx.getImageData(98, 98, 1, 1).data; + assert_array_equals(imageData.slice(0, 3), [0, 128, 0]); + + ctx.save(); + ctx.fillStyle = 'red'; + ctx.fillRect(0, 0, 100, 100); + ctx.beginPath(); + ctx.moveTo(0, 0); + ctx.lineTo(100, 0); + ctx.lineTo(100, 50); + ctx.scale(0, 0); + ctx.lineTo(100, 100); + ctx.resetTransform(); + ctx.lineTo(0, 100); + ctx.fillStyle = 'green'; + ctx.fill(); + ctx.restore(); + + imageData = ctx.getImageData(98, 98, 1, 1).data; + assert_array_equals(imageData.slice(0, 3), [255, 0, 0]); + + imageData = ctx.getImageData(98, 48, 1, 1).data; + assert_array_equals(imageData.slice(0, 3), [0, 128, 0]); +}, "This test checks resetTransform in canvas v5"); +</script> </body> -</html>
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/canvas-save-restore-expected.txt b/third_party/WebKit/LayoutTests/fast/canvas/canvas-save-restore-expected.txt deleted file mode 100644 index c8a11fe..0000000 --- a/third_party/WebKit/LayoutTests/fast/canvas/canvas-save-restore-expected.txt +++ /dev/null
@@ -1,39 +0,0 @@ -Test of save and restore on canvas graphics context. - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - - -PASS pixel() is black -PASS pixel() is red -PASS pixel() is black -PASS pixel() is black -PASS pixel() is red -PASS pixel() is black -PASS pixel() is black -PASS pixel() is black -PASS pixel() is red -PASS pixel() is black -PASS pixel() is black -PASS pixel() is black -PASS pixel() is red -PASS pixel() is black -PASS pixel() is green -PASS pixel() is green -PASS pixel() is red -PASS pixel() is green -PASS pixel() is black -PASS pixel() is black -PASS pixel() is black -PASS pixel() is black -PASS pixel() is red -PASS pixel() is red -PASS pixel() is green -PASS pixel() is red -PASS pixel() is red -PASS pixel() is green -PASS pixel() is black -PASS pixel() is black -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/canvas-save-restore-with-path-expected.txt b/third_party/WebKit/LayoutTests/fast/canvas/canvas-save-restore-with-path-expected.txt deleted file mode 100644 index c3c69a8..0000000 --- a/third_party/WebKit/LayoutTests/fast/canvas/canvas-save-restore-with-path-expected.txt +++ /dev/null
@@ -1,15 +0,0 @@ -This test ensures that paths are correctly handled over save/restore boundaries - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - - -PASS getPixel(25,25) is [0,128,0,255] -PASS getPixel(75,25) is [0,128,0,255] -PASS getPixel(75,75) is [255,0,0,255] -PASS getPixel(25,75) is [0,128,0,255] -PASS getPixel(75,75) is [255,0,0,255] -PASS getPixel(75,75) is [0,128,0,255] -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/canvas-save-restore-with-path.html b/third_party/WebKit/LayoutTests/fast/canvas/canvas-save-restore-with-path.html index 41589b1..ef6ddcc 100644 --- a/third_party/WebKit/LayoutTests/fast/canvas/canvas-save-restore-with-path.html +++ b/third_party/WebKit/LayoutTests/fast/canvas/canvas-save-restore-with-path.html
@@ -1,2 +1,57 @@ -<script src="../../resources/js-test.js"></script> -<script src="canvas-save-restore-with-path.js"></script> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<script> +test(function(t) { +}, "This test ensures that paths are correctly handled over save/restore boundaries"); + +function pixelShouldBe(x, y, color) { + assert_array_equals(context.getImageData(x, y, 1, 1).data, color); +} + +var canvas = document.createElement("canvas"); +canvas.width = 100; +canvas.height = 100; + +var context = canvas.getContext("2d"); +context.fillStyle = "red"; +context.fillRect(0, 0, 100, 100); +context.fillStyle = "green"; + +// Test translate +context.beginPath(); +context.save(); +context.translate(100, 100); +context.rect(-100, -100, 50, 50); +context.restore(); +context.fill(); +pixelShouldBe(25, 25, [0, 128, 0, 255]); + +// Test scale +context.beginPath(); +context.save(); +context.scale(2, 2); +context.rect(25, 0, 25, 25); +context.restore(); +context.fill(); +pixelShouldBe(75, 25, [0, 128, 0, 255]); +pixelShouldBe(75, 75, [255, 0, 0, 255]); + +// Test rotate +context.beginPath(); +context.save(); +context.rotate(90/180 * Math.PI); +context.rect(50, -50, 50, 50); +context.restore(); +context.fill(); +pixelShouldBe(25, 75, [0, 128, 0, 255]); +pixelShouldBe(75, 75, [255, 0, 0, 255]); + +// Test transform +context.beginPath(); +context.save(); +context.transform(1, 0, 0, 1, 50, 50); +context.rect(0, 0, 50, 50); +context.restore(); +context.fill(); +pixelShouldBe(75, 75, [0, 128, 0, 255]); +</script>
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/canvas-save-restore-with-path.js b/third_party/WebKit/LayoutTests/fast/canvas/canvas-save-restore-with-path.js deleted file mode 100644 index 184c7e28..0000000 --- a/third_party/WebKit/LayoutTests/fast/canvas/canvas-save-restore-with-path.js +++ /dev/null
@@ -1,66 +0,0 @@ -description("This test ensures that paths are correctly handled over save/restore boundaries"); - -function dataToArray(data) { - var result = new Array(data.length) - for (var i = 0; i < data.length; i++) - result[i] = data[i]; - return result; -} - -function getPixel(x, y) { - var data = context.getImageData(x,y,1,1); - if (!data) // getImageData failed, which should never happen - return [-1,-1,-1,-1]; - return dataToArray(data.data); -} - -function pixelShouldBe(x, y, colour) { - shouldBe("getPixel(" + [x, y] +")", "["+colour+"]"); -} - -var canvas = document.createElement("canvas"); -canvas.width = 100; -canvas.height = 100; - -var context = canvas.getContext("2d"); -context.fillStyle = "red"; -context.fillRect(0,0,100,100); -context.fillStyle = "green"; - -// Test translate -context.beginPath(); -context.save(); -context.translate(100, 100); -context.rect(-100, -100, 50, 50); -context.restore(); -context.fill(); -pixelShouldBe(25, 25, [0, 128, 0, 255]); - -// Test scale -context.beginPath(); -context.save(); -context.scale(2, 2); -context.rect(25, 0,25,25); -context.restore(); -context.fill(); -pixelShouldBe(75, 25, [0, 128, 0, 255]); -pixelShouldBe(75, 75, [255, 0, 0, 255]); - -// Test rotate -context.beginPath(); -context.save(); -context.rotate(90/180 * Math.PI); -context.rect(50, -50, 50, 50); -context.restore(); -context.fill(); -pixelShouldBe(25, 75, [0, 128, 0, 255]); -pixelShouldBe(75, 75, [255, 0, 0, 255]); - -// Test transform -context.beginPath(); -context.save(); -context.transform(1, 0, 0, 1, 50, 50); -context.rect(0, 0, 50, 50); -context.restore(); -context.fill(); -pixelShouldBe(75, 75, [0, 128, 0, 255]);
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/canvas-save-restore.html b/third_party/WebKit/LayoutTests/fast/canvas/canvas-save-restore.html index 0c9be2d..64686b3 100644 --- a/third_party/WebKit/LayoutTests/fast/canvas/canvas-save-restore.html +++ b/third_party/WebKit/LayoutTests/fast/canvas/canvas-save-restore.html
@@ -1,9 +1,163 @@ -<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> -<html> -<head> -<script src="../../resources/js-test.js"></script> -</head> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> <body> -<script src="script-tests/canvas-save-restore.js"></script> +<script> +var canvas = document.createElement("canvas"); +var context = canvas.getContext('2d'); + +function hex(number) +{ + var hexDigits = "0123456789abcdef"; + return hexDigits[number >> 4] + hexDigits[number & 0xF]; +} + +function pixel() +{ + var imageData = context.getImageData(0, 0, 1, 1); + return "#" + hex(imageData.data[0]) + hex(imageData.data[1]) + hex(imageData.data[2]); +} + +var black="#000000"; +var red = "#ff0000"; +var green = "#008000"; + +test(function(t) { + // (save set restore) + context.fillStyle = "black"; + context.fillRect(0, 0, 1, 1); + assert_equals(pixel(), black); + + context.save(); + context.fillStyle = "red"; + context.fillRect(0, 0, 1, 1); + assert_equals(pixel(), red); + + context.restore(); + context.fillRect(0, 0, 1, 1); + assert_equals(pixel(), black); + + // (save (save set restore) restore) + context.fillStyle = "black"; + context.fillRect(0, 0, 1, 1); + assert_equals(pixel(), black); + + context.save(); + + context.save(); + context.fillStyle = "red"; + context.fillRect(0, 0, 1, 1); + assert_equals(pixel(), red); + + context.restore(); + context.fillRect(0, 0, 1, 1); + assert_equals(pixel(), black); + + context.restore(); + context.fillRect(0, 0, 1, 1); + assert_equals(pixel(), black); + + // (save (save restore) set restore) + context.fillStyle = "black"; + context.fillRect(0, 0, 1, 1); + assert_equals(pixel(), black); + + context.save(); + context.restore(); + + context.save(); + context.fillStyle = "red"; + context.fillRect(0, 0, 1, 1); + assert_equals(pixel(), red); + + context.restore(); + context.fillRect(0, 0, 1, 1); + assert_equals(pixel(), black); + + // (save (save (save set restore) set (save set restore) restore) restore) + context.fillStyle = "black"; + context.fillRect(0, 0, 1, 1); + assert_equals(pixel(), black); + + context.save(); + context.fillRect(0, 0, 1, 1); + assert_equals(pixel(), black); + + context.save(); + context.fillStyle = "red"; + context.fillRect(0, 0, 1, 1); + assert_equals(pixel(), red); + + context.restore(); + context.fillRect(0, 0, 1, 1); + assert_equals(pixel(), black); + + context.fillStyle = "green"; + context.fillRect(0, 0, 1, 1); + assert_equals(pixel(), green); + + context.save(); + context.fillRect(0, 0, 1, 1); + assert_equals(pixel(), green); + + context.fillStyle = "red"; + context.fillRect(0, 0, 1, 1); + assert_equals(pixel(), red); + + context.restore(); + context.fillRect(0, 0, 1, 1); + assert_equals(pixel(), green); + + context.restore(); + context.fillRect(0, 0, 1, 1); + assert_equals(pixel(), black); + + context.restore(); + context.fillRect(0, 0, 1, 1); + assert_equals(pixel(), black); + + // (save (save set (save (save set restore) restore) set restore) restore) + context.fillStyle = "black"; + context.fillRect(0, 0, 1, 1); + assert_equals(pixel(), black); + + context.save(); + context.fillRect(0, 0, 1, 1); + assert_equals(pixel(), black); + + context.save(); + context.fillStyle = "red"; + context.fillRect(0, 0, 1, 1); + assert_equals(pixel(), red); + + context.save(); + context.fillRect(0, 0, 1, 1); + assert_equals(pixel(), red); + + context.save(); + context.fillStyle = "green"; + context.fillRect(0, 0, 1, 1); + assert_equals(pixel(), green); + + context.restore(); + context.fillRect(0, 0, 1, 1); + assert_equals(pixel(), red); + + context.restore(); + context.fillRect(0, 0, 1, 1); + assert_equals(pixel(), red); + + context.fillStyle = "green"; + context.fillRect(0, 0, 1, 1); + assert_equals(pixel(), green); + + context.restore(); + context.fillRect(0, 0, 1, 1); + assert_equals(pixel(), black); + + context.restore(); + context.fillRect(0, 0, 1, 1); + assert_equals(pixel(), black); +}, "Verfiy canvas save and restore correct behavior."); +</script> </body> </html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/canvas-scale-drawImage-shadow-expected.txt b/third_party/WebKit/LayoutTests/fast/canvas/canvas-scale-drawImage-shadow-expected.txt deleted file mode 100644 index b54ef615..0000000 --- a/third_party/WebKit/LayoutTests/fast/canvas/canvas-scale-drawImage-shadow-expected.txt +++ /dev/null
@@ -1,89 +0,0 @@ -Ensure correct behavior of canvas with drawImage+shadow after scaling. A blue and red checkered pattern should be displayed. - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - - -PASS d[0] is 255 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is 255 -PASS d[0] is 255 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is 255 -PASS d[0] is 255 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is around 76 -PASS d[0] is 255 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is around 76 -PASS d[0] is 255 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is around 114 -PASS d[0] is 255 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is around 114 -PASS d[0] is 255 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is around 114 -PASS d[0] is 255 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is around 114 -PASS d[0] is 255 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is around 34 -PASS d[0] is 255 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is around 34 -PASS d[0] is 255 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is around 34 -PASS d[0] is 255 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is around 34 -PASS d[0] is 255 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is around 57 -PASS d[0] is 255 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is around 57 -PASS d[0] is 255 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is around 57 -PASS d[0] is 255 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is around 57 -PASS d[0] is 255 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is around 17 -PASS d[0] is 255 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is around 17 -PASS d[0] is 255 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is around 17 -PASS d[0] is 255 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is around 17 -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/canvas-scale-drawImage-shadow.html b/third_party/WebKit/LayoutTests/fast/canvas/canvas-scale-drawImage-shadow.html index f95053c..1e854e20 100644 --- a/third_party/WebKit/LayoutTests/fast/canvas/canvas-scale-drawImage-shadow.html +++ b/third_party/WebKit/LayoutTests/fast/canvas/canvas-scale-drawImage-shadow.html
@@ -1,9 +1,125 @@ -<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> -<html> -<head> -<script src="../../resources/js-test.js"></script> -</head> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> <body> -<script src="script-tests/canvas-scale-drawImage-shadow.js"></script> +<script> +async_test(t => { + // Create auxiliary canvas to draw to and create an image from. + // This is done instead of simply loading an image from the file system + // because that would throw a SECURITY_ERR DOM Exception. + var aCanvas = document.createElement('canvas'); + aCanvas.width = aCanvas.height = 10; + var aCtx = aCanvas.getContext('2d'); + aCtx.fillStyle = 'rgba(0, 0, 255, 1)'; + aCtx.fillRect(0, 0, 50, 50); + + // Create the image object to be drawn on the master canvas. + var img = new Image(); + img.onload = drawImageToCanvasAndCheckPixels; + img.src = aCanvas.toDataURL(); // set a data URI of the base64 encoded image as the source + + aCanvas.width = 10; + aCtx.fillStyle = 'rgba(0, 0, 255, 0.5)'; + aCtx.fillRect(0, 0, 50, 50); + // Create the image object to be drawn on the master canvas. + var transparentImg = new Image(); + transparentImg.onload = drawImageToCanvasAndCheckPixels; + transparentImg.src = aCanvas.toDataURL(); // set a data URI of the base64 encoded image as the source + + // Create master canvas. + var canvas = document.createElement('canvas'); + document.body.appendChild(canvas); + canvas.width = 150; + canvas.height = 110; + var ctx = canvas.getContext('2d'); + + function testPixelShadow(x, y, color) + { + assert_array_equals(ctx.getImageData(x, y, 1, 1).data, color); + } + + function testPixelShadowAlpha(x, y, color) + { + var data = ctx.getImageData(x, y, 1, 1).data; + assert_array_equals(data.slice(0,3), color.slice(0,3)); + assert_approx_equals(data[3], color[3], 10); + } + + var testPixelShadowScenarios = [ + ['Verify solid shadow 1', 40, 40, [255, 0, 0, 255]], + ['Verify solid shadow 2', 59, 59, [255, 0, 0, 255]], + ]; + + var testPixelShadowAlphaScenarios = [ + ['Verify solid alpha shadow 1', 41, 81, [255, 0, 0, 76]], + ['Verify solid alpha shadow 2', 59, 99, [255, 0, 0, 76]], + + ['Verify blurry shadow 1', 90, 39, [255, 0, 0, 114]], + ['Verify blurry shadow 2', 90, 60, [255, 0, 0, 114]], + ['Verify blurry shadow 3', 79, 50, [255, 0, 0, 114]], + ['Verify blurry shadow 4', 100, 50, [255, 0, 0, 114]], + + ['Verify blurry alpha shadow 1', 90, 79, [255, 0, 0, 34]], + ['Verify blurry alpha shadow 2', 90, 100, [255, 0, 0, 34]], + ['Verify blurry alpha shadow 3', 79, 90, [255, 0, 0, 34]], + ['Verify blurry alpha shadow 4', 100, 90, [255, 0, 0, 34]], + + ['Verify blurry shadow of image with alpha 1', 130, 39, [255, 0, 0, 57]], + ['Verify blurry shadow of image with alpha 2', 130, 60, [255, 0, 0, 57]], + ['Verify blurry shadow of image with alpha 3', 119, 50, [255, 0, 0, 57]], + ['Verify blurry shadow of image with alpha 4', 140, 50, [255, 0, 0, 57]], + + ['Verify blurry alpha shadow of image with alpha 1', 130, 79, [255, 0, 0, 17]], + ['Verify blurry alpha shadow of image with alpha 2', 130, 100, [255, 0, 0, 17]], + ['Verify blurry alpha shadow of image with alpha 3', 119, 90, [255, 0, 0, 17]], + ['Verify blurry alpha shadow of image with alpha 4', 140, 90, [255, 0, 0, 17]], + ]; + + var imagesLoaded = 0; + function drawImageToCanvasAndCheckPixels() { + imagesLoaded = imagesLoaded + 1; + if (imagesLoaded == 2) { + ctx.scale(2, 2); + ctx.shadowOffsetX = 20; + ctx.shadowOffsetY = 20; + ctx.fillStyle = 'rgba(0, 0, 255, 1)'; + + ctx.shadowColor = 'rgba(255, 0, 0, 1.0)'; + ctx.drawImage(img, 10, 10); + + ctx.shadowColor = 'rgba(255, 0, 0, 0.3)'; + ctx.drawImage(img, 10, 30); + + ctx.shadowColor = 'rgba(255, 0, 0, 1.0)'; + ctx.shadowBlur = 10; + ctx.drawImage(img, 30, 10); + + ctx.shadowColor = 'rgba(255, 0, 0, 0.3)'; + ctx.drawImage(img, 30, 30); + + ctx.shadowColor = 'rgba(255, 0, 0, 1.0)'; + ctx.drawImage(transparentImg, 50, 10); + + ctx.shadowColor = 'rgba(255, 0, 0, 0.3)'; + ctx.drawImage(transparentImg, 50, 30); + + t.step(runTests); + t.done(); + + } + } + + function runTests() { + for (var i = 0; i < testPixelShadowScenarios.length; i++) + testPixelShadow(testPixelShadowScenarios[i][1], + testPixelShadowScenarios[i][2], + testPixelShadowScenarios[i][3]); + + for (var i = 0; i < testPixelShadowAlphaScenarios.length; i++) + testPixelShadowAlpha(testPixelShadowAlphaScenarios[i][1], + testPixelShadowAlphaScenarios[i][2], + testPixelShadowAlphaScenarios[i][3]); + } + +}, 'Ensure correct behavior of canvas with drawImage+shadow after scaling. A blue and red checkered pattern should be displayed.'); +</script> </body> -</html>
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/canvas-scale-fillPath-shadow-expected.txt b/third_party/WebKit/LayoutTests/fast/canvas/canvas-scale-fillPath-shadow-expected.txt deleted file mode 100644 index 5a9fb84..0000000 --- a/third_party/WebKit/LayoutTests/fast/canvas/canvas-scale-fillPath-shadow-expected.txt +++ /dev/null
@@ -1,57 +0,0 @@ -Ensure correct behavior of canvas with path fill + shadow after scaling. A blue and red checkered pattern should be displayed. - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - - -PASS d[0] is 255 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is 255 -PASS d[0] is 255 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is 255 -PASS d[0] is 255 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is 255 -PASS d[0] is 255 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is around 76 -PASS d[0] is 255 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is around 76 -PASS d[0] is 255 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is around 76 -PASS d[0] is 255 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is around 83 -PASS d[0] is 255 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is around 83 -PASS d[0] is 255 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is around 53 -PASS d[0] is 255 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is around 24 -PASS d[0] is 255 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is around 24 -PASS d[0] is 255 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is around 24 -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/canvas-scale-fillPath-shadow.html b/third_party/WebKit/LayoutTests/fast/canvas/canvas-scale-fillPath-shadow.html index 0da6772..e1d7a5c 100644 --- a/third_party/WebKit/LayoutTests/fast/canvas/canvas-scale-fillPath-shadow.html +++ b/third_party/WebKit/LayoutTests/fast/canvas/canvas-scale-fillPath-shadow.html
@@ -1,9 +1,86 @@ -<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> -<html> -<head> -<script src="../../resources/js-test.js"></script> -</head> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> <body> -<script src="script-tests/canvas-scale-fillPath-shadow.js"></script> +<script> +// Ensure correct behavior of canvas with path fill + shadow after scaling. A blue and red checkered pattern should be displayed. + +var canvas = document.createElement('canvas'); +document.body.appendChild(canvas); +canvas.setAttribute('width', '1000'); +canvas.setAttribute('height', '1000'); +var ctx = canvas.getContext('2d'); + +ctx.scale(2, 2); +ctx.shadowOffsetX = 100; +ctx.shadowOffsetY = 100; +ctx.fillStyle = 'rgba(0, 0, 255, 1)'; + +ctx.shadowColor = 'rgba(255, 0, 0, 1.0)'; +ctx.beginPath(); +ctx.moveTo(50, 50); +ctx.lineTo(100, 50); +ctx.lineTo(100, 100); +ctx.lineTo(50, 100); +ctx.fill(); + +ctx.shadowColor = 'rgba(255, 0, 0, 0.3)'; +ctx.beginPath(); +ctx.moveTo(50, 150); +ctx.lineTo(100, 150); +ctx.lineTo(100, 200); +ctx.lineTo(50, 200); +ctx.fill(); + +ctx.shadowColor = 'rgba(255, 0, 0, 1.0)'; +ctx.shadowBlur = 10; +ctx.beginPath(); +ctx.moveTo(150, 50); +ctx.lineTo(200, 50); +ctx.lineTo(200, 100); +ctx.lineTo(150, 100); +ctx.fill(); + +ctx.shadowColor = 'rgba(255, 0, 0, 0.3)'; +ctx.beginPath(); +ctx.moveTo(150, 150); +ctx.lineTo(200, 150); +ctx.lineTo(200, 200); +ctx.lineTo(150, 200); +ctx.fill(); + +function testPixelShadow(x, y, color) +{ + assert_array_equals(ctx.getImageData(x, y, 1, 1).data, color); +} + +function testPixelShadowAlpha(x, y, color) +{ + var data = ctx.getImageData(x, y, 1, 1).data; + assert_array_equals(data.slice(0,3), color.slice(0,3)); + assert_approx_equals(data[3], color[3], 20); +} + +var testPixelShadowScenarios = [ + ['Verify solid shadow 1', 201, 205, [255, 0, 0, 255]], + ['Verify solid shadow 2', 298, 295, [255, 0, 0, 255]], + ['Verify solid shadow 3', 201, 298, [255, 0, 0, 255]], +]; + +var testPixelShadowAlphaScenarios = [ + ['Verify solid alpha shadow 1', 201, 405, [255, 0, 0, 76]], + ['Verify solid alpha shadow 2', 298, 405, [255, 0, 0, 76]], + ['Verify solid alpha shadow 3', 205, 498, [255, 0, 0, 76]], + + ['Verify blurry shadow 1', 398, 205, [255, 0, 0, 83]], + ['Verify blurry shadow 2', 501, 205, [255, 0, 0, 83]], + ['Verify blurry shadow 3', 500, 300, [255, 0, 0, 53]], + + ['Verify blurry alpha shadow 1', 398, 405, [255, 0, 0, 24]], + ['Verify blurry alpha shadow 2', 405, 501, [255, 0, 0, 24]], +]; + +generate_tests(testPixelShadow, testPixelShadowScenarios); +generate_tests(testPixelShadowAlpha, testPixelShadowAlphaScenarios); + +</script> </body> -</html>
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/canvas-scale-fillRect-shadow-expected.txt b/third_party/WebKit/LayoutTests/fast/canvas/canvas-scale-fillRect-shadow-expected.txt deleted file mode 100644 index 94f0a8e2..0000000 --- a/third_party/WebKit/LayoutTests/fast/canvas/canvas-scale-fillRect-shadow-expected.txt +++ /dev/null
@@ -1,57 +0,0 @@ -Ensure correct behavior of canvas with fillRect+shadow after scaling. A blue and red checkered pattern should be displayed. - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - - -PASS d[0] is 255 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is 255 -PASS d[0] is 255 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is 255 -PASS d[0] is 255 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is 255 -PASS d[0] is 255 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is around 76 -PASS d[0] is 255 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is around 76 -PASS d[0] is 255 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is around 76 -PASS d[0] is 255 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is around 83 -PASS d[0] is 255 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is around 83 -PASS d[0] is 255 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is around 53 -PASS d[0] is 255 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is around 24 -PASS d[0] is 255 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is around 24 -PASS d[0] is 255 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is around 24 -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/canvas-scale-fillRect-shadow.html b/third_party/WebKit/LayoutTests/fast/canvas/canvas-scale-fillRect-shadow.html index eed9534..67afaef7 100644 --- a/third_party/WebKit/LayoutTests/fast/canvas/canvas-scale-fillRect-shadow.html +++ b/third_party/WebKit/LayoutTests/fast/canvas/canvas-scale-fillRect-shadow.html
@@ -1,9 +1,66 @@ -<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> -<html> -<head> -<script src="../../resources/js-test.js"></script> -</head> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> <body> -<script src="script-tests/canvas-scale-fillRect-shadow.js"></script> +<script> +// Ensure correct behavior of canvas with fillRect+shadow after scaling. A blue and red checkered pattern should be displayed. + +var canvas = document.createElement('canvas'); +document.body.appendChild(canvas); +canvas.setAttribute('width', '1000'); +canvas.setAttribute('height', '1000'); +var ctx = canvas.getContext('2d'); + +ctx.scale(2, 2); +ctx.shadowOffsetX = 100; +ctx.shadowOffsetY = 100; +ctx.fillStyle = 'rgba(0, 0, 255, 1)'; + +ctx.shadowColor = 'rgba(255, 0, 0, 1.0)'; +ctx.fillRect(50, 50, 50, 50); + +ctx.shadowColor = 'rgba(255, 0, 0, 0.3)'; +ctx.fillRect(50, 150, 50, 50); + +ctx.shadowColor = 'rgba(255, 0, 0, 1.0)'; +ctx.shadowBlur = 10; +ctx.fillRect(150, 50, 50, 50); + +ctx.shadowColor = 'rgba(255, 0, 0, 0.3)'; +ctx.fillRect(150, 150, 50, 50); + +function testPixelShadow(x, y, color) +{ + assert_array_equals(ctx.getImageData(x, y, 1, 1).data, color); +} + +function testPixelShadowAlpha(x, y, color) +{ + var data = ctx.getImageData(x, y, 1, 1).data; + assert_array_equals(data.slice(0,3), color.slice(0,3)); + assert_approx_equals(data[3], color[3], 20); +} + +var testPixelShadowScenarios = [ + ['Verify solid shadow 1', 201, 205, [255, 0, 0, 255]], + ['Verify solid shadow 2', 298, 298, [255, 0, 0, 255]], + ['Verify solid shadow 3', 201, 298, [255, 0, 0, 255]], +]; + +var testPixelShadowAlphaScenarios = [ + ['Verify solid alpha shadow 1', 201, 405, [255, 0, 0, 76]], + ['Verify solid alpha shadow 2', 298, 405, [255, 0, 0, 76]], + ['Verify solid alpha shadow 3', 205, 498, [255, 0, 0, 76]], + + ['Verify blurry shadow 1', 398, 205, [255, 0, 0, 83]], + ['Verify blurry shadow 2', 501, 205, [255, 0, 0, 83]], + ['Verify blurry shadow 3', 500, 300, [255, 0, 0, 53]], + + ['Verify blurry alpha shadow 1', 398, 405, [255, 0, 0, 24]], + ['Verify blurry alpha shadow 2', 405, 501, [255, 0, 0, 24]], +]; + +generate_tests(testPixelShadow, testPixelShadowScenarios); +generate_tests(testPixelShadowAlpha, testPixelShadowAlphaScenarios); + +</script> </body> -</html>
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/canvas-scale-shadowBlur-expected.txt b/third_party/WebKit/LayoutTests/fast/canvas/canvas-scale-shadowBlur-expected.txt deleted file mode 100644 index a2bb3a9..0000000 --- a/third_party/WebKit/LayoutTests/fast/canvas/canvas-scale-shadowBlur-expected.txt +++ /dev/null
@@ -1,93 +0,0 @@ -Ensure that canvas shadowBlur is not affected by transformations. - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - - -PASS d[0] is 255 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is around 255 -PASS d[0] is 0 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is 0 -PASS d[0] is 0 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is 0 -PASS d[0] is 0 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is 0 -PASS d[0] is 0 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is 0 -PASS d[0] is 255 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is around 126 -PASS d[0] is 0 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is 0 -PASS d[0] is 0 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is 0 -PASS d[0] is 0 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is 0 -PASS d[0] is 0 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is 0 -PASS d[0] is 255 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is around 255 -PASS d[0] is 255 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is around 255 -PASS d[0] is 0 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is 0 -PASS d[0] is 0 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is 0 -PASS d[0] is 0 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is 0 -PASS d[0] is 0 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is 0 -PASS d[0] is 255 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is around 126 -PASS d[0] is 0 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is 0 -PASS d[0] is 0 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is 0 -PASS d[0] is 0 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is 0 -PASS d[0] is 0 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is 0 -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/canvas-scale-shadowBlur.html b/third_party/WebKit/LayoutTests/fast/canvas/canvas-scale-shadowBlur.html index 7af0f50b..6dba9da 100644 --- a/third_party/WebKit/LayoutTests/fast/canvas/canvas-scale-shadowBlur.html +++ b/third_party/WebKit/LayoutTests/fast/canvas/canvas-scale-shadowBlur.html
@@ -1,9 +1,82 @@ -<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> -<html> -<head> -<script src="../../resources/js-test.js"></script> -</head> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> <body> -<script src="script-tests/canvas-scale-shadowBlur.js"></script> +<script> +// Ensure that canvas shadowBlur is not affected by transformations. + +var canvas = document.createElement('canvas'); +document.body.appendChild(canvas); +canvas.setAttribute('width', '600'); +canvas.setAttribute('height', '600'); +var ctx = canvas.getContext('2d'); + +ctx.shadowBlur = 25; +ctx.shadowOffsetX = 100; +ctx.shadowOffsetY = 100; +ctx.fillStyle = 'rgba(0, 0, 255, 1)'; + +// top left +ctx.shadowColor = 'rgba(255, 0, 0, 1.0)'; +ctx.scale(4, 4); +ctx.rotate(Math.PI/2); +ctx.translate(25, -50); +ctx.fillRect(0, 0, 25, 25); + +// bottom left +ctx.shadowColor = 'rgba(255, 0, 0, 0.5)'; +ctx.setTransform(1, 0, 0, 1, 0, 0); +ctx.scale(0.5, 0.5); +ctx.fillRect(200, 600, 200, 200); + +// top right +ctx.shadowColor = 'rgba(255, 0, 0, 1.0)'; +ctx.scale(2, 2); +ctx.fillRect(300, 100, 100, 100); + +// bottom right +ctx.shadowColor = 'rgba(255, 0, 0, 0.5)'; +ctx.fillRect(300, 300, 100, 100); + +function testPixelShadowBlur(x, y, color) +{ + if (color.length == 4) { + assert_array_equals(ctx.getImageData(x, y, 1, 1).data, color); + } else { // we expect to have [r, g, b, a, alphaApprox] + var data = ctx.getImageData(x, y, 1, 1).data; + assert_array_equals(data.slice(0,3), color.slice(0,3)); + assert_approx_equals(data[3], color[3], color[4]); + } +} + +var testPixelShadowBlurScenarios = [ + ['Verify top left 1', 250, 250, [255, 0, 0, 255]], + ['Verify top left 2', 250, 175, [0, 0, 0, 0]], + ['Verify top left 3', 250, 325, [0, 0, 0, 0]], + ['Verify top left 4', 175, 250, [0, 0, 0, 0]], + ['Verify top left 5', 325, 250, [0, 0, 0, 0]], + + ['Verify bottom left 1', 250, 450, [255, 0, 0, 126, 20]], + ['Verify bottom left 2', 250, 375, [0, 0, 0, 0]], + ['Verify bottom left 3', 250, 525, [0, 0, 0, 0]], + ['Verify bottom left 4', 175, 450, [0, 0, 0, 0]], + ['Verify bottom left 5', 325, 450, [0, 0, 0, 0]], + ['Verify bottom left 6', 250, 250, [255, 0, 0, 255, 20]], + + ['Verify top right 1', 450, 250, [255, 0, 0, 255, 20]], + ['Verify top right 2', 450, 175, [0, 0, 0, 0]], + ['Verify top right 3', 450, 325, [0, 0, 0, 0]], + ['Verify top right 4', 375, 250, [0, 0, 0, 0]], + ['Verify top right 5', 525, 250, [0, 0, 0, 0]], + + ['Verify bottom right 1', 450, 450, [255, 0, 0, 126, 20]], + ['Verify bottom right 2', 450, 375, [0, 0, 0, 0]], + ['Verify bottom right 3', 450, 525, [0, 0, 0, 0]], + ['Verify bottom right 2', 375, 450, [0, 0, 0, 0]], + ['Verify bottom right 2', 525, 450, [0, 0, 0, 0]], + +]; + +generate_tests(testPixelShadowBlur, testPixelShadowBlurScenarios); + +</script> </body> -</html>
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/script-tests/canvas-resetTransform.js b/third_party/WebKit/LayoutTests/fast/canvas/script-tests/canvas-resetTransform.js deleted file mode 100644 index 05cbe575..0000000 --- a/third_party/WebKit/LayoutTests/fast/canvas/script-tests/canvas-resetTransform.js +++ /dev/null
@@ -1,117 +0,0 @@ -description("This test checks resetTransform in canvas v5"); - -var canvas = document.createElement('canvas'); -document.body.appendChild(canvas); -canvas.setAttribute('width', '100'); -canvas.setAttribute('height', '100'); -var ctx = canvas.getContext('2d'); - -debug("resetTransform should reset other transforms."); -ctx.save(); -ctx.scale(0.5, 0.5); -ctx.resetTransform(); -ctx.fillStyle = 'green'; -ctx.fillRect(0, 0, 100, 100); -ctx.restore(); - -var imageData = ctx.getImageData(98, 98, 1, 1); -var imgdata = imageData.data; -shouldBe("imgdata[0]", "0"); -shouldBe("imgdata[1]", "128"); -shouldBe("imgdata[2]", "0"); - -debug("resetTransform should not affect CTM outside of save() and restore()."); -ctx.save(); -ctx.scale(0.5, 0.5); -ctx.save(); -ctx.resetTransform(); -ctx.fillStyle = 'green'; -ctx.fillRect(0, 0, 100, 100); -ctx.restore(); -ctx.fillStyle = 'red'; -ctx.fillRect(0, 0, 100, 100); -ctx.restore(); - -imageData = ctx.getImageData(98, 98, 1, 1); -imgdata = imageData.data; -shouldBe("imgdata[0]", "0"); -shouldBe("imgdata[1]", "128"); -shouldBe("imgdata[2]", "0"); - -imageData = ctx.getImageData(48, 48, 1, 1); -imgdata = imageData.data; -shouldBe("imgdata[0]", "255"); -shouldBe("imgdata[1]", "0"); -shouldBe("imgdata[2]", "0"); - -debug("resetTransform should restore the path transform to identity."); -/* This should draw a green rectangle on on top of a red one. The red should not be visible. */ -ctx.save(); -ctx.beginPath(); -ctx.moveTo(0, 0); -ctx.lineTo(100, 0); -ctx.lineTo(100, 100); -ctx.lineTo(0, 100); -ctx.fillStyle = 'red'; -ctx.fill(); -ctx.translate(200, 0); -ctx.resetTransform(); -ctx.fillStyle = 'green'; -ctx.fill(); -ctx.restore(); - -imageData = ctx.getImageData(50, 50, 1, 1); -imgdata = imageData.data; -shouldBe("imgdata[0]", "0"); -shouldBe("imgdata[1]", "128"); -shouldBe("imgdata[2]", "0"); - -debug("resetTransform should resolve the non-invertible CTM state."); -ctx.save(); -ctx.fillStyle = 'red'; -ctx.fillRect(0, 0, 100, 100); -ctx.beginPath(); -ctx.moveTo(0, 0); -ctx.lineTo(100, 0); -ctx.lineTo(100, 100); -ctx.lineTo(0, 100); -ctx.scale(0, 0); -ctx.resetTransform(); -ctx.fillStyle = 'green'; -ctx.fill(); -ctx.restore(); - -imageData = ctx.getImageData(98, 98, 1, 1); -imgdata = imageData.data; -shouldBe("imgdata[0]", "0"); -shouldBe("imgdata[1]", "128"); -shouldBe("imgdata[2]", "0"); - -debug("The path object should not be updated on the non-invertible CTM state."); -debug("resetTransform should restore the path object just before CTM became non-invertible."); -ctx.save(); -ctx.fillStyle = 'red'; -ctx.fillRect(0, 0, 100, 100); -ctx.beginPath(); -ctx.moveTo(0, 0); -ctx.lineTo(100, 0); -ctx.lineTo(100, 50); -ctx.scale(0, 0); -ctx.lineTo(100, 100); -ctx.resetTransform(); -ctx.lineTo(0, 100); -ctx.fillStyle = 'green'; -ctx.fill(); -ctx.restore(); - -imageData = ctx.getImageData(98, 98, 1, 1); -imgdata = imageData.data; -shouldBe("imgdata[0]", "255"); -shouldBe("imgdata[1]", "0"); -shouldBe("imgdata[2]", "0"); - -imageData = ctx.getImageData(98, 48, 1, 1); -imgdata = imageData.data; -shouldBe("imgdata[0]", "0"); -shouldBe("imgdata[1]", "128"); -shouldBe("imgdata[2]", "0");
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/script-tests/canvas-save-restore.js b/third_party/WebKit/LayoutTests/fast/canvas/script-tests/canvas-save-restore.js deleted file mode 100644 index cd68a5a9..0000000 --- a/third_party/WebKit/LayoutTests/fast/canvas/script-tests/canvas-save-restore.js +++ /dev/null
@@ -1,161 +0,0 @@ -description("Test of save and restore on canvas graphics context."); - -var canvas = document.createElement("canvas"); -var context = canvas.getContext('2d'); - -function hex(number) -{ - var hexDigits = "0123456789abcdef"; - return hexDigits[number >> 4] + hexDigits[number & 0xF]; -} - -function pixel() -{ - var imageData = context.getImageData(0, 0, 1, 1); - return "#" + hex(imageData.data[0]) + hex(imageData.data[1]) + hex(imageData.data[2]); -} - -var black="#000000"; -var red = "#ff0000"; -var green = "#008000"; - -// (save set restore) -context.fillStyle = "black"; -context.fillRect(0, 0, 1, 1); -shouldBe("pixel()", "black"); - -context.save(); -context.fillStyle = "red"; -context.fillRect(0, 0, 1, 1); -shouldBe("pixel()", "red"); - -context.restore(); -context.fillRect(0, 0, 1, 1); -shouldBe("pixel()", "black"); - - -// (save (save set restore) restore) -context.fillStyle = "black"; -context.fillRect(0, 0, 1, 1); -shouldBe("pixel()", "black"); - -context.save(); - -context.save(); -context.fillStyle = "red"; -context.fillRect(0, 0, 1, 1); -shouldBe("pixel()", "red"); - -context.restore(); -context.fillRect(0, 0, 1, 1); -shouldBe("pixel()", "black"); - -context.restore(); -context.fillRect(0, 0, 1, 1); -shouldBe("pixel()", "black"); - - -// (save (save restore) set restore) -context.fillStyle = "black"; -context.fillRect(0, 0, 1, 1); -shouldBe("pixel()", "black"); - -context.save(); -context.restore(); - -context.save(); -context.fillStyle = "red"; -context.fillRect(0, 0, 1, 1); -shouldBe("pixel()", "red"); - -context.restore(); -context.fillRect(0, 0, 1, 1); -shouldBe("pixel()", "black"); - - -// (save (save (save set restore) set (save set restore) restore) restore) -context.fillStyle = "black"; -context.fillRect(0, 0, 1, 1); -shouldBe("pixel()", "black"); - -context.save(); -context.fillRect(0, 0, 1, 1); -shouldBe("pixel()", "black"); - -context.save(); -context.fillStyle = "red"; -context.fillRect(0, 0, 1, 1); -shouldBe("pixel()", "red"); - -context.restore(); -context.fillRect(0, 0, 1, 1); -shouldBe("pixel()", "black"); - -context.fillStyle = "green"; -context.fillRect(0, 0, 1, 1); -shouldBe("pixel()", "green"); - -context.save(); -context.fillRect(0, 0, 1, 1); -shouldBe("pixel()", "green"); - -context.fillStyle = "red"; -context.fillRect(0, 0, 1, 1); -shouldBe("pixel()", "red"); - -context.restore(); -context.fillRect(0, 0, 1, 1); -shouldBe("pixel()", "green"); - -context.restore(); -context.fillRect(0, 0, 1, 1); -shouldBe("pixel()", "black"); - -context.restore(); -context.fillRect(0, 0, 1, 1); -shouldBe("pixel()", "black"); - - -// (save (save set (save (save set restore) restore) set restore) restore) -context.fillStyle = "black"; -context.fillRect(0, 0, 1, 1); -shouldBe("pixel()", "black"); - -context.save(); -context.fillRect(0, 0, 1, 1); -shouldBe("pixel()", "black"); - -context.save(); -context.fillStyle = "red"; -context.fillRect(0, 0, 1, 1); -shouldBe("pixel()", "red"); - -context.save(); -context.fillRect(0, 0, 1, 1); -shouldBe("pixel()", "red"); - -context.save(); -context.fillStyle = "green"; -context.fillRect(0, 0, 1, 1); -shouldBe("pixel()", "green"); - -context.restore(); -context.fillRect(0, 0, 1, 1); -shouldBe("pixel()", "red"); - -context.restore(); -context.fillRect(0, 0, 1, 1); -shouldBe("pixel()", "red"); - -context.fillStyle = "green"; -context.fillRect(0, 0, 1, 1); -shouldBe("pixel()", "green"); - -context.restore(); -context.fillRect(0, 0, 1, 1); -shouldBe("pixel()", "black"); - -context.restore(); -context.fillRect(0, 0, 1, 1); -shouldBe("pixel()", "black"); -
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/script-tests/canvas-scale-drawImage-shadow.js b/third_party/WebKit/LayoutTests/fast/canvas/script-tests/canvas-scale-drawImage-shadow.js deleted file mode 100644 index e713688..0000000 --- a/third_party/WebKit/LayoutTests/fast/canvas/script-tests/canvas-scale-drawImage-shadow.js +++ /dev/null
@@ -1,224 +0,0 @@ -description("Ensure correct behavior of canvas with drawImage+shadow after scaling. A blue and red checkered pattern should be displayed."); - -function print(message, color) -{ - var paragraph = document.createElement("div"); - paragraph.appendChild(document.createTextNode(message)); - paragraph.style.fontFamily = "monospace"; - if (color) - paragraph.style.color = color; - document.getElementById("console").appendChild(paragraph); -} - -function shouldBeAround(a, b) -{ - var evalA; - try { - evalA = eval(a); - } catch(e) { - evalA = e; - } - - if (Math.abs(evalA - b) < 10) - print("PASS " + a + " is around " + b , "green") - else - print("FAIL " + a + " is not around " + b + " (actual: " + evalA + ")", "red"); -} - -// Create auxiliary canvas to draw to and create an image from. -// This is done instead of simply loading an image from the file system -// because that would throw a SECURITY_ERR DOM Exception. -var aCanvas = document.createElement('canvas'); -aCanvas.width = 10; -aCanvas.height = 10; -aCanvas.setAttribute('height', '10'); -var aCtx = aCanvas.getContext('2d'); -aCtx.fillStyle = 'rgba(0, 0, 255, 1)'; -aCtx.fillRect(0, 0, 50, 50); - -// Create the image object to be drawn on the master canvas. -var img = new Image(); -img.onload = drawImageToCanvasAndCheckPixels; -img.src = aCanvas.toDataURL(); // set a data URI of the base64 encoded image as the source - -aCanvas.width = 10; -aCtx.fillStyle = 'rgba(0, 0, 255, 0.5)'; -aCtx.fillRect(0, 0, 50, 50); -// Create the image object to be drawn on the master canvas. -var transparentImg = new Image(); -transparentImg.onload = drawImageToCanvasAndCheckPixels; -transparentImg.src = aCanvas.toDataURL(); // set a data URI of the base64 encoded image as the source - -// Create master canvas. -var canvas = document.createElement('canvas'); -document.body.appendChild(canvas); -canvas.setAttribute('width', '150'); -canvas.setAttribute('height', '110'); -var ctx = canvas.getContext('2d'); - -var imagesLoaded = 0; - -function drawImageToCanvasAndCheckPixels() { - imagesLoaded = imagesLoaded + 1; - if (imagesLoaded == 2) { - ctx.scale(2, 2); - ctx.shadowOffsetX = 20; - ctx.shadowOffsetY = 20; - ctx.fillStyle = 'rgba(0, 0, 255, 1)'; - - ctx.shadowColor = 'rgba(255, 0, 0, 1.0)'; - ctx.drawImage(img, 10, 10); - - ctx.shadowColor = 'rgba(255, 0, 0, 0.3)'; - ctx.drawImage(img, 10, 30); - - ctx.shadowColor = 'rgba(255, 0, 0, 1.0)'; - ctx.shadowBlur = 10; - ctx.drawImage(img, 30, 10); - - ctx.shadowColor = 'rgba(255, 0, 0, 0.3)'; - ctx.drawImage(img, 30, 30); - - ctx.shadowColor = 'rgba(255, 0, 0, 1.0)'; - ctx.drawImage(transparentImg, 50, 10); - - ctx.shadowColor = 'rgba(255, 0, 0, 0.3)'; - ctx.drawImage(transparentImg, 50, 30); - - checkPixels(); - } -} - -var d; // imageData.data - -function checkPixels() { - - // Verify solid shadow. - d = ctx.getImageData(40, 40, 1, 1).data; - shouldBe('d[0]', '255'); - shouldBe('d[1]', '0'); - shouldBe('d[2]', '0'); - shouldBe('d[3]', '255'); - - d = ctx.getImageData(59, 59, 1, 1).data; - shouldBe('d[0]', '255'); - shouldBe('d[1]', '0'); - shouldBe('d[2]', '0'); - shouldBe('d[3]', '255'); - - // Verify solid alpha shadow. - d = ctx.getImageData(41, 81, 1, 1).data; - shouldBe('d[0]', '255'); - shouldBe('d[1]', '0'); - shouldBe('d[2]', '0'); - shouldBeAround('d[3]', '76'); - - d = ctx.getImageData(59, 99, 1, 1).data; - shouldBe('d[0]', '255'); - shouldBe('d[1]', '0'); - shouldBe('d[2]', '0'); - shouldBeAround('d[3]', '76'); - - // Verify blurry shadow. - d = ctx.getImageData(90, 39, 1, 1).data; - shouldBe('d[0]', '255'); - shouldBe('d[1]', '0'); - shouldBe('d[2]', '0'); - shouldBeAround('d[3]', '114'); - - d = ctx.getImageData(90, 60, 1, 1).data; - shouldBe('d[0]', '255'); - shouldBe('d[1]', '0'); - shouldBe('d[2]', '0'); - shouldBeAround('d[3]', '114'); - - d = ctx.getImageData(79, 50, 1, 1).data; - shouldBe('d[0]', '255'); - shouldBe('d[1]', '0'); - shouldBe('d[2]', '0'); - shouldBeAround('d[3]', '114'); - - d = ctx.getImageData(100, 50, 1, 1).data; - shouldBe('d[0]', '255'); - shouldBe('d[1]', '0'); - shouldBe('d[2]', '0'); - shouldBeAround('d[3]', '114'); - - // Verify blurry alpha shadow. - d = ctx.getImageData(90, 79, 1, 1).data; - shouldBe('d[0]', '255'); - shouldBe('d[1]', '0'); - shouldBe('d[2]', '0'); - shouldBeAround('d[3]', '34'); - - d = ctx.getImageData(90, 100, 1, 1).data; - shouldBe('d[0]', '255'); - shouldBe('d[1]', '0'); - shouldBe('d[2]', '0'); - shouldBeAround('d[3]', '34'); - - d = ctx.getImageData(79, 90, 1, 1).data; - shouldBe('d[0]', '255'); - shouldBe('d[1]', '0'); - shouldBe('d[2]', '0'); - shouldBeAround('d[3]', '34'); - - d = ctx.getImageData(100, 90, 1, 1).data; - shouldBe('d[0]', '255'); - shouldBe('d[1]', '0'); - shouldBe('d[2]', '0'); - shouldBeAround('d[3]', '34'); - - // Verify blurry shadow of image with alpha - d = ctx.getImageData(130, 39, 1, 1).data; - shouldBe('d[0]', '255'); - shouldBe('d[1]', '0'); - shouldBe('d[2]', '0'); - shouldBeAround('d[3]', '57'); - - d = ctx.getImageData(130, 60, 1, 1).data; - shouldBe('d[0]', '255'); - shouldBe('d[1]', '0'); - shouldBe('d[2]', '0'); - shouldBeAround('d[3]', '57'); - - d = ctx.getImageData(119, 50, 1, 1).data; - shouldBe('d[0]', '255'); - shouldBe('d[1]', '0'); - shouldBe('d[2]', '0'); - shouldBeAround('d[3]', '57'); - - d = ctx.getImageData(140, 50, 1, 1).data; - shouldBe('d[0]', '255'); - shouldBe('d[1]', '0'); - shouldBe('d[2]', '0'); - shouldBeAround('d[3]', '57'); - - // Verify blurry alpha shadow of image with alpha. - d = ctx.getImageData(130, 79, 1, 1).data; - shouldBe('d[0]', '255'); - shouldBe('d[1]', '0'); - shouldBe('d[2]', '0'); - shouldBeAround('d[3]', '17'); - - d = ctx.getImageData(130, 100, 1, 1).data; - shouldBe('d[0]', '255'); - shouldBe('d[1]', '0'); - shouldBe('d[2]', '0'); - shouldBeAround('d[3]', '17'); - - d = ctx.getImageData(119, 90, 1, 1).data; - shouldBe('d[0]', '255'); - shouldBe('d[1]', '0'); - shouldBe('d[2]', '0'); - shouldBeAround('d[3]', '17'); - - d = ctx.getImageData(140, 90, 1, 1).data; - shouldBe('d[0]', '255'); - shouldBe('d[1]', '0'); - shouldBe('d[2]', '0'); - shouldBeAround('d[3]', '17'); - finishJSTest(); -} - -window.jsTestIsAsync = true;
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/script-tests/canvas-scale-fillPath-shadow.js b/third_party/WebKit/LayoutTests/fast/canvas/script-tests/canvas-scale-fillPath-shadow.js deleted file mode 100644 index 98675134..0000000 --- a/third_party/WebKit/LayoutTests/fast/canvas/script-tests/canvas-scale-fillPath-shadow.js +++ /dev/null
@@ -1,148 +0,0 @@ -description("Ensure correct behavior of canvas with path fill + shadow after scaling. A blue and red checkered pattern should be displayed."); - -function print(message, color) -{ - var paragraph = document.createElement("div"); - paragraph.appendChild(document.createTextNode(message)); - paragraph.style.fontFamily = "monospace"; - if (color) - paragraph.style.color = color; - document.getElementById("console").appendChild(paragraph); -} - -function shouldBeAround(a, b) -{ - var evalA; - try { - evalA = eval(a); - } catch(e) { - evalA = e; - } - - if (Math.abs(evalA - b) < 20) - print("PASS " + a + " is around " + b , "green") - else - print("FAIL " + a + " is not around " + b + " (actual: " + evalA + ")", "red"); -} - -var canvas = document.createElement('canvas'); -document.body.appendChild(canvas); -canvas.setAttribute('width', '1000'); -canvas.setAttribute('height', '1000'); -var ctx = canvas.getContext('2d'); - -ctx.scale(2, 2); -ctx.shadowOffsetX = 100; -ctx.shadowOffsetY = 100; -ctx.fillStyle = 'rgba(0, 0, 255, 1)'; - -ctx.shadowColor = 'rgba(255, 0, 0, 1.0)'; -ctx.beginPath(); -ctx.moveTo(50, 50); -ctx.lineTo(100, 50); -ctx.lineTo(100, 100); -ctx.lineTo(50, 100); -ctx.fill(); - -ctx.shadowColor = 'rgba(255, 0, 0, 0.3)'; -ctx.beginPath(); -ctx.moveTo(50, 150); -ctx.lineTo(100, 150); -ctx.lineTo(100, 200); -ctx.lineTo(50, 200); -ctx.fill(); - -ctx.shadowColor = 'rgba(255, 0, 0, 1.0)'; -ctx.shadowBlur = 10; -ctx.beginPath(); -ctx.moveTo(150, 50); -ctx.lineTo(200, 50); -ctx.lineTo(200, 100); -ctx.lineTo(150, 100); -ctx.fill(); - -ctx.shadowColor = 'rgba(255, 0, 0, 0.3)'; -ctx.beginPath(); -ctx.moveTo(150, 150); -ctx.lineTo(200, 150); -ctx.lineTo(200, 200); -ctx.lineTo(150, 200); -ctx.fill(); - -var d; // imageData.data - -// Verify solid shadow. -d = ctx.getImageData(201, 205, 1, 1).data; -shouldBe('d[0]', '255'); -shouldBe('d[1]', '0'); -shouldBe('d[2]', '0'); -shouldBe('d[3]', '255'); - -d = ctx.getImageData(298, 295, 1, 1).data; -shouldBe('d[0]', '255'); -shouldBe('d[1]', '0'); -shouldBe('d[2]', '0'); -shouldBe('d[3]', '255'); - -d = ctx.getImageData(201, 298, 1, 1).data; -shouldBe('d[0]', '255'); -shouldBe('d[1]', '0'); -shouldBe('d[2]', '0'); -shouldBe('d[3]', '255'); - -// Verify solid alpha shadow. -d = ctx.getImageData(201, 405, 1, 1).data; -shouldBe('d[0]', '255'); -shouldBe('d[1]', '0'); -shouldBe('d[2]', '0'); -shouldBeAround('d[3]', '76'); - -d = ctx.getImageData(298, 405, 1, 1).data; -shouldBe('d[0]', '255'); -shouldBe('d[1]', '0'); -shouldBe('d[2]', '0'); -shouldBeAround('d[3]', '76'); - -d = ctx.getImageData(205, 498, 1, 1).data; -shouldBe('d[0]', '255'); -shouldBe('d[1]', '0'); -shouldBe('d[2]', '0'); -shouldBeAround('d[3]', '76'); - -// Verify blurry shadow. -d = ctx.getImageData(398, 205, 1, 1).data; -shouldBe('d[0]', '255'); -shouldBe('d[1]', '0'); -shouldBe('d[2]', '0'); -shouldBeAround('d[3]', '83'); - -d = ctx.getImageData(501, 205, 1, 1).data; -shouldBe('d[0]', '255'); -shouldBe('d[1]', '0'); -shouldBe('d[2]', '0'); -shouldBeAround('d[3]', '83'); - -d = ctx.getImageData(500, 300, 1, 1).data; -shouldBe('d[0]', '255'); -shouldBe('d[1]', '0'); -shouldBe('d[2]', '0'); -shouldBeAround('d[3]', '53'); - -// Verify blurry alpha shadow. -d = ctx.getImageData(398, 405, 1, 1).data; -shouldBe('d[0]', '255'); -shouldBe('d[1]', '0'); -shouldBe('d[2]', '0'); -shouldBeAround('d[3]', '24'); - -d = ctx.getImageData(405, 501, 1, 1).data; -shouldBe('d[0]', '255'); -shouldBe('d[1]', '0'); -shouldBe('d[2]', '0'); -shouldBeAround('d[3]', '24'); - -d = ctx.getImageData(405, 501, 1, 1).data; -shouldBe('d[0]', '255'); -shouldBe('d[1]', '0'); -shouldBe('d[2]', '0'); -shouldBeAround('d[3]', '24');
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/script-tests/canvas-scale-fillRect-shadow.js b/third_party/WebKit/LayoutTests/fast/canvas/script-tests/canvas-scale-fillRect-shadow.js deleted file mode 100644 index 8fdc17ef..0000000 --- a/third_party/WebKit/LayoutTests/fast/canvas/script-tests/canvas-scale-fillRect-shadow.js +++ /dev/null
@@ -1,128 +0,0 @@ -description("Ensure correct behavior of canvas with fillRect+shadow after scaling. A blue and red checkered pattern should be displayed."); - -function print(message, color) -{ - var paragraph = document.createElement("div"); - paragraph.appendChild(document.createTextNode(message)); - paragraph.style.fontFamily = "monospace"; - if (color) - paragraph.style.color = color; - document.getElementById("console").appendChild(paragraph); -} - -function shouldBeAround(a, b) -{ - var evalA; - try { - evalA = eval(a); - } catch(e) { - evalA = e; - } - - if (Math.abs(evalA - b) < 20) - print("PASS " + a + " is around " + b , "green") - else - print("FAIL " + a + " is not around " + b + " (actual: " + evalA + ")", "red"); -} - -var canvas = document.createElement('canvas'); -document.body.appendChild(canvas); -canvas.setAttribute('width', '1000'); -canvas.setAttribute('height', '1000'); -var ctx = canvas.getContext('2d'); - -ctx.scale(2, 2); -ctx.shadowOffsetX = 100; -ctx.shadowOffsetY = 100; -ctx.fillStyle = 'rgba(0, 0, 255, 1)'; - -ctx.shadowColor = 'rgba(255, 0, 0, 1.0)'; -ctx.fillRect(50, 50, 50, 50); - -ctx.shadowColor = 'rgba(255, 0, 0, 0.3)'; -ctx.fillRect(50, 150, 50, 50); - -ctx.shadowColor = 'rgba(255, 0, 0, 1.0)'; -ctx.shadowBlur = 10; -ctx.fillRect(150, 50, 50, 50); - -ctx.shadowColor = 'rgba(255, 0, 0, 0.3)'; -ctx.fillRect(150, 150, 50, 50); - -var d; // imageData.data - -// Verify solid shadow. -d = ctx.getImageData(201, 205, 1, 1).data; -shouldBe('d[0]', '255'); -shouldBe('d[1]', '0'); -shouldBe('d[2]', '0'); -shouldBe('d[3]', '255'); - -d = ctx.getImageData(298, 298, 1, 1).data; -shouldBe('d[0]', '255'); -shouldBe('d[1]', '0'); -shouldBe('d[2]', '0'); -shouldBe('d[3]', '255'); - -d = ctx.getImageData(201, 298, 1, 1).data; -shouldBe('d[0]', '255'); -shouldBe('d[1]', '0'); -shouldBe('d[2]', '0'); -shouldBe('d[3]', '255'); - -// Verify solid alpha shadow. -d = ctx.getImageData(201, 405, 1, 1).data; -shouldBe('d[0]', '255'); -shouldBe('d[1]', '0'); -shouldBe('d[2]', '0'); -shouldBeAround('d[3]', '76'); - -d = ctx.getImageData(298, 405, 1, 1).data; -shouldBe('d[0]', '255'); -shouldBe('d[1]', '0'); -shouldBe('d[2]', '0'); -shouldBeAround('d[3]', '76'); - -d = ctx.getImageData(205, 498, 1, 1).data; -shouldBe('d[0]', '255'); -shouldBe('d[1]', '0'); -shouldBe('d[2]', '0'); -shouldBeAround('d[3]', '76'); - -// Verify blurry shadow. -d = ctx.getImageData(398, 205, 1, 1).data; -shouldBe('d[0]', '255'); -shouldBe('d[1]', '0'); -shouldBe('d[2]', '0'); -shouldBeAround('d[3]', '83'); - -d = ctx.getImageData(501, 205, 1, 1).data; -shouldBe('d[0]', '255'); -shouldBe('d[1]', '0'); -shouldBe('d[2]', '0'); -shouldBeAround('d[3]', '83'); - -d = ctx.getImageData(500, 300, 1, 1).data; -shouldBe('d[0]', '255'); -shouldBe('d[1]', '0'); -shouldBe('d[2]', '0'); -shouldBeAround('d[3]', '53'); - -// Verify blurry alpha shadow. -d = ctx.getImageData(398, 405, 1, 1).data; -shouldBe('d[0]', '255'); -shouldBe('d[1]', '0'); -shouldBe('d[2]', '0'); -shouldBeAround('d[3]', '24'); - -d = ctx.getImageData(405, 501, 1, 1).data; -shouldBe('d[0]', '255'); -shouldBe('d[1]', '0'); -shouldBe('d[2]', '0'); -shouldBeAround('d[3]', '24'); - -d = ctx.getImageData(405, 501, 1, 1).data; -shouldBe('d[0]', '255'); -shouldBe('d[1]', '0'); -shouldBe('d[2]', '0'); -shouldBeAround('d[3]', '24');
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/script-tests/canvas-scale-shadowBlur.js b/third_party/WebKit/LayoutTests/fast/canvas/script-tests/canvas-scale-shadowBlur.js deleted file mode 100644 index 6fdb73f..0000000 --- a/third_party/WebKit/LayoutTests/fast/canvas/script-tests/canvas-scale-shadowBlur.js +++ /dev/null
@@ -1,191 +0,0 @@ -description("Ensure that canvas shadowBlur is not affected by transformations."); - -function print(message, color) -{ - var paragraph = document.createElement("div"); - paragraph.appendChild(document.createTextNode(message)); - paragraph.style.fontFamily = "monospace"; - if (color) - paragraph.style.color = color; - document.getElementById("console").appendChild(paragraph); -} - -function shouldBeAround(a, b) -{ - var evalA; - try { - evalA = eval(a); - } catch(e) { - evalA = e; - } - - if (Math.abs(evalA - b) < 10) - print("PASS " + a + " is around " + b , "green") - else - print("FAIL " + a + " is not around " + b + " (actual: " + evalA + ")", "red"); -} - -var canvas = document.createElement('canvas'); -document.body.appendChild(canvas); -canvas.setAttribute('width', '600'); -canvas.setAttribute('height', '600'); -var ctx = canvas.getContext('2d'); - -ctx.shadowBlur = 25; -ctx.shadowOffsetX = 100; -ctx.shadowOffsetY = 100; -ctx.fillStyle = 'rgba(0, 0, 255, 1)'; - -// top left -ctx.shadowColor = 'rgba(255, 0, 0, 1.0)'; -ctx.scale(4, 4); -ctx.rotate(Math.PI/2); -ctx.translate(25, -50); -ctx.fillRect(0, 0, 25, 25); - -// bottom left -ctx.shadowColor = 'rgba(255, 0, 0, 0.5)'; -ctx.setTransform(1, 0, 0, 1, 0, 0); -ctx.scale(0.5, 0.5); -ctx.fillRect(200, 600, 200, 200); - -// top right -ctx.shadowColor = 'rgba(255, 0, 0, 1.0)'; -ctx.scale(2, 2); -ctx.fillRect(300, 100, 100, 100); - -// bottom right -ctx.shadowColor = 'rgba(255, 0, 0, 0.5)'; -ctx.fillRect(300, 300, 100, 100); - -var d; - -// top left -d = ctx.getImageData(250, 250, 1, 1).data; -shouldBe('d[0]', '255'); -shouldBe('d[1]', '0'); -shouldBe('d[2]', '0'); -shouldBeAround('d[3]', '255'); - -d = ctx.getImageData(250, 175, 1, 1).data; -shouldBe('d[0]', '0'); -shouldBe('d[1]', '0'); -shouldBe('d[2]', '0'); -shouldBe('d[3]', '0'); - -d = ctx.getImageData(250, 325, 1, 1).data; -shouldBe('d[0]', '0'); -shouldBe('d[1]', '0'); -shouldBe('d[2]', '0'); -shouldBe('d[3]', '0'); - -d = ctx.getImageData(175, 250, 1, 1).data; -shouldBe('d[0]', '0'); -shouldBe('d[1]', '0'); -shouldBe('d[2]', '0'); -shouldBe('d[3]', '0'); - -d = ctx.getImageData(325, 250, 1, 1).data; -shouldBe('d[0]', '0'); -shouldBe('d[1]', '0'); -shouldBe('d[2]', '0'); -shouldBe('d[3]', '0'); - -// bottom left -d = ctx.getImageData(250, 450, 1, 1).data; -shouldBe('d[0]', '255'); -shouldBe('d[1]', '0'); -shouldBe('d[2]', '0'); -shouldBeAround('d[3]', '126'); - -d = ctx.getImageData(250, 375, 1, 1).data; -shouldBe('d[0]', '0'); -shouldBe('d[1]', '0'); -shouldBe('d[2]', '0'); -shouldBe('d[3]', '0'); - -d = ctx.getImageData(250, 525, 1, 1).data; -shouldBe('d[0]', '0'); -shouldBe('d[1]', '0'); -shouldBe('d[2]', '0'); -shouldBe('d[3]', '0'); - -d = ctx.getImageData(175, 450, 1, 1).data; -shouldBe('d[0]', '0'); -shouldBe('d[1]', '0'); -shouldBe('d[2]', '0'); -shouldBe('d[3]', '0'); - -d = ctx.getImageData(325, 450, 1, 1).data; -shouldBe('d[0]', '0'); -shouldBe('d[1]', '0'); -shouldBe('d[2]', '0'); -shouldBe('d[3]', '0'); - -d = ctx.getImageData(250, 250, 1, 1).data; -shouldBe('d[0]', '255'); -shouldBe('d[1]', '0'); -shouldBe('d[2]', '0'); -shouldBeAround('d[3]', '255'); - -// top right -d = ctx.getImageData(450, 250, 1, 1).data; -shouldBe('d[0]', '255'); -shouldBe('d[1]', '0'); -shouldBe('d[2]', '0'); -shouldBeAround('d[3]', '255'); - -d = ctx.getImageData(450, 175, 1, 1).data; -shouldBe('d[0]', '0'); -shouldBe('d[1]', '0'); -shouldBe('d[2]', '0'); -shouldBe('d[3]', '0'); - -d = ctx.getImageData(450, 325, 1, 1).data; -shouldBe('d[0]', '0'); -shouldBe('d[1]', '0'); -shouldBe('d[2]', '0'); -shouldBe('d[3]', '0'); - -d = ctx.getImageData(375, 250, 1, 1).data; -shouldBe('d[0]', '0'); -shouldBe('d[1]', '0'); -shouldBe('d[2]', '0'); -shouldBe('d[3]', '0'); - -d = ctx.getImageData(525, 250, 1, 1).data; -shouldBe('d[0]', '0'); -shouldBe('d[1]', '0'); -shouldBe('d[2]', '0'); -shouldBe('d[3]', '0'); - -// top right -d = ctx.getImageData(450, 450, 1, 1).data; -shouldBe('d[0]', '255'); -shouldBe('d[1]', '0'); -shouldBe('d[2]', '0'); -shouldBeAround('d[3]', '126'); - -d = ctx.getImageData(450, 375, 1, 1).data; -shouldBe('d[0]', '0'); -shouldBe('d[1]', '0'); -shouldBe('d[2]', '0'); -shouldBe('d[3]', '0'); - -d = ctx.getImageData(450, 525, 1, 1).data; -shouldBe('d[0]', '0'); -shouldBe('d[1]', '0'); -shouldBe('d[2]', '0'); -shouldBe('d[3]', '0'); - -d = ctx.getImageData(375, 450, 1, 1).data; -shouldBe('d[0]', '0'); -shouldBe('d[1]', '0'); -shouldBe('d[2]', '0'); -shouldBe('d[3]', '0'); - -d = ctx.getImageData(525, 450, 1, 1).data; -shouldBe('d[0]', '0'); -shouldBe('d[1]', '0'); -shouldBe('d[2]', '0'); -shouldBe('d[3]', '0');
diff --git a/third_party/WebKit/LayoutTests/virtual/gpu/fast/canvas/canvas-resetTransform-expected.txt b/third_party/WebKit/LayoutTests/virtual/gpu/fast/canvas/canvas-resetTransform-expected.txt deleted file mode 100644 index 800c5b3..0000000 --- a/third_party/WebKit/LayoutTests/virtual/gpu/fast/canvas/canvas-resetTransform-expected.txt +++ /dev/null
@@ -1,36 +0,0 @@ -This test checks resetTransform in canvas v5 - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - - -resetTransform should reset other transforms. -PASS imgdata[0] is 0 -PASS imgdata[1] is 128 -PASS imgdata[2] is 0 -resetTransform should not affect CTM outside of save() and restore(). -PASS imgdata[0] is 0 -PASS imgdata[1] is 128 -PASS imgdata[2] is 0 -PASS imgdata[0] is 255 -PASS imgdata[1] is 0 -PASS imgdata[2] is 0 -resetTransform should restore the path transform to identity. -PASS imgdata[0] is 0 -PASS imgdata[1] is 128 -PASS imgdata[2] is 0 -resetTransform should resolve the non-invertible CTM state. -PASS imgdata[0] is 0 -PASS imgdata[1] is 128 -PASS imgdata[2] is 0 -The path object should not be updated on the non-invertible CTM state. -resetTransform should restore the path object just before CTM became non-invertible. -PASS imgdata[0] is 255 -PASS imgdata[1] is 0 -PASS imgdata[2] is 0 -PASS imgdata[0] is 0 -PASS imgdata[1] is 128 -PASS imgdata[2] is 0 -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/WebKit/LayoutTests/virtual/gpu/fast/canvas/canvas-scale-drawImage-shadow-expected.txt b/third_party/WebKit/LayoutTests/virtual/gpu/fast/canvas/canvas-scale-drawImage-shadow-expected.txt deleted file mode 100644 index b54ef615..0000000 --- a/third_party/WebKit/LayoutTests/virtual/gpu/fast/canvas/canvas-scale-drawImage-shadow-expected.txt +++ /dev/null
@@ -1,89 +0,0 @@ -Ensure correct behavior of canvas with drawImage+shadow after scaling. A blue and red checkered pattern should be displayed. - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - - -PASS d[0] is 255 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is 255 -PASS d[0] is 255 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is 255 -PASS d[0] is 255 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is around 76 -PASS d[0] is 255 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is around 76 -PASS d[0] is 255 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is around 114 -PASS d[0] is 255 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is around 114 -PASS d[0] is 255 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is around 114 -PASS d[0] is 255 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is around 114 -PASS d[0] is 255 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is around 34 -PASS d[0] is 255 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is around 34 -PASS d[0] is 255 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is around 34 -PASS d[0] is 255 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is around 34 -PASS d[0] is 255 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is around 57 -PASS d[0] is 255 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is around 57 -PASS d[0] is 255 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is around 57 -PASS d[0] is 255 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is around 57 -PASS d[0] is 255 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is around 17 -PASS d[0] is 255 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is around 17 -PASS d[0] is 255 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is around 17 -PASS d[0] is 255 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is around 17 -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/WebKit/LayoutTests/virtual/gpu/fast/canvas/canvas-scale-shadowBlur-expected.txt b/third_party/WebKit/LayoutTests/virtual/gpu/fast/canvas/canvas-scale-shadowBlur-expected.txt deleted file mode 100644 index a2bb3a9..0000000 --- a/third_party/WebKit/LayoutTests/virtual/gpu/fast/canvas/canvas-scale-shadowBlur-expected.txt +++ /dev/null
@@ -1,93 +0,0 @@ -Ensure that canvas shadowBlur is not affected by transformations. - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - - -PASS d[0] is 255 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is around 255 -PASS d[0] is 0 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is 0 -PASS d[0] is 0 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is 0 -PASS d[0] is 0 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is 0 -PASS d[0] is 0 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is 0 -PASS d[0] is 255 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is around 126 -PASS d[0] is 0 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is 0 -PASS d[0] is 0 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is 0 -PASS d[0] is 0 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is 0 -PASS d[0] is 0 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is 0 -PASS d[0] is 255 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is around 255 -PASS d[0] is 255 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is around 255 -PASS d[0] is 0 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is 0 -PASS d[0] is 0 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is 0 -PASS d[0] is 0 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is 0 -PASS d[0] is 0 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is 0 -PASS d[0] is 255 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is around 126 -PASS d[0] is 0 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is 0 -PASS d[0] is 0 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is 0 -PASS d[0] is 0 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is 0 -PASS d[0] is 0 -PASS d[1] is 0 -PASS d[2] is 0 -PASS d[3] is 0 -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/WebKit/Source/core/workers/WorkerThread.cpp b/third_party/WebKit/Source/core/workers/WorkerThread.cpp index ca8983f..17b2c4a 100644 --- a/third_party/WebKit/Source/core/workers/WorkerThread.cpp +++ b/third_party/WebKit/Source/core/workers/WorkerThread.cpp
@@ -306,9 +306,6 @@ DCHECK(m_requestedToStart); { - // Prevent the deadlock between GC and an attempt to terminate a thread. - SafePointScope safePointScope(BlinkGC::HeapPointersOnStack); - // Protect against this method, initializeOnWorkerThread() or // termination via the global scope racing each other. MutexLocker lock(m_threadStateMutex);
diff --git a/third_party/WebKit/Source/devtools/front_end/Images/src/optimize_png.hashes b/third_party/WebKit/Source/devtools/front_end/Images/src/optimize_png.hashes index 1965213..45b233b 100644 --- a/third_party/WebKit/Source/devtools/front_end/Images/src/optimize_png.hashes +++ b/third_party/WebKit/Source/devtools/front_end/Images/src/optimize_png.hashes
@@ -5,9 +5,9 @@ "checkboxCheckmark.svg": "f039bf85cee42ad5c30ca3bfdce7912a", "errorWave.svg": "e183fa242a22ed4784a92f6becbc2c45", "smallIcons.svg": "044ba42204fd8ae030835e2ca78433bf", - "toolbarButtonGlyphs.svg": "fa5911823785a90273dfea76fe4ce512", + "toolbarButtonGlyphs.svg": "3db0c30256dd19d51b088f6855052030", "breakpoint.svg": "69cd92d807259c022791112809b97799", "treeoutlineTriangles.svg": "017d2f89437df0afc6b9cd5ff43735d9", "audits_logo_bw.svg": "203dcb2ba32ef0f4595ad45bb8feffab", "audits_logo.svg": "647095d7981857c22a816eef12f75b91" -} \ No newline at end of file +}
diff --git a/third_party/WebKit/Source/devtools/front_end/Images/src/svg2png.hashes b/third_party/WebKit/Source/devtools/front_end/Images/src/svg2png.hashes index 1965213..1eecefc 100644 --- a/third_party/WebKit/Source/devtools/front_end/Images/src/svg2png.hashes +++ b/third_party/WebKit/Source/devtools/front_end/Images/src/svg2png.hashes
@@ -5,7 +5,7 @@ "checkboxCheckmark.svg": "f039bf85cee42ad5c30ca3bfdce7912a", "errorWave.svg": "e183fa242a22ed4784a92f6becbc2c45", "smallIcons.svg": "044ba42204fd8ae030835e2ca78433bf", - "toolbarButtonGlyphs.svg": "fa5911823785a90273dfea76fe4ce512", + "toolbarButtonGlyphs.svg": "3db0c30256dd19d51b088f6855052030", "breakpoint.svg": "69cd92d807259c022791112809b97799", "treeoutlineTriangles.svg": "017d2f89437df0afc6b9cd5ff43735d9", "audits_logo_bw.svg": "203dcb2ba32ef0f4595ad45bb8feffab",
diff --git a/third_party/WebKit/Source/devtools/front_end/Images/src/toolbarButtonGlyphs.svg b/third_party/WebKit/Source/devtools/front_end/Images/src/toolbarButtonGlyphs.svg index c07f8f8d..c0a3f4d 100644 --- a/third_party/WebKit/Source/devtools/front_end/Images/src/toolbarButtonGlyphs.svg +++ b/third_party/WebKit/Source/devtools/front_end/Images/src/toolbarButtonGlyphs.svg
@@ -9,23 +9,23 @@ xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - height="168" + height="192" version="1.1" width="352" xml:space="preserve" id="svg3395" - inkscape:version="0.92.0 r" + inkscape:version="0.48.4 r9939" sodipodi:docname="toolbarButtonGlyphs.svg"><metadata id="metadata3773"><rdf:RDF><cc:Work rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><sodipodi:namedview showgrid="true" id="namedview3397" - inkscape:zoom="2.8284271" - inkscape:cx="196.27229" - inkscape:cy="85.656284" - inkscape:window-width="1278" - inkscape:window-height="746" + inkscape:zoom="11.313708" + inkscape:cx="83.592365" + inkscape:cy="12.060079" + inkscape:window-width="1941" + inkscape:window-height="1436" inkscape:window-x="0" inkscape:window-y="0" inkscape:window-maximized="0" @@ -621,7 +621,7 @@ style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /></g><g id="g2488"><path transform="matrix(0.36,0,0,0.36,125.49998,127.46)" - d="m 53,14 a 3,3 0 1 1 -6,0 3,3 0 1 1 6,0 z" + d="m 53,14 c 0,1.656854 -1.343146,3 -3,3 -1.656854,0 -3,-1.343146 -3,-3 0,-1.656854 1.343146,-3 3,-3 1.656854,0 3,1.343146 3,3 z" sodipodi:ry="3" sodipodi:rx="3" sodipodi:cy="14" @@ -658,11 +658,7 @@ id="g2472"><path id="path3509-0" d="m 240.76701,127 -1.53402,0 0,4.23299 -4.23299,0 0,1.53402 4.23299,0 0,4.23299 1.53402,0 0,-4.23299 4.23299,0 0,-1.53402 -4.23299,0 0,-4.23299 z" - inkscape:connector-curvature="0" /></g><path - style="fill:none" - inkscape:connector-curvature="0" - d="m 228.56466,156.76923 h 48 v 48 h -48 z" - id="path3712" /><g + inkscape:connector-curvature="0" /></g><g id="g2462"><path id="path3714" d="m 310.7696,127.0439 -1.81599,-1.81636 c -0.30331,-0.30338 -0.79716,-0.30338 -1.10048,0 l -2.43038,2.43089 -1.48935,-1.49354 -1.10047,1.1007 1.10437,1.1046 L 297,135.30504 V 139 h 3.69419 l 6.9373,-6.93874 1.10048,1.1046 1.10048,-1.10072 -1.49324,-1.49353 2.43039,-2.43089 c 0.3072,-0.30338 0.3072,-0.79345 0,-1.09682 z m -10.72092,10.40033 -1.49324,-1.49354 6.27235,-6.27365 1.49323,1.49354 -6.27234,6.27365 z" @@ -724,7 +720,7 @@ style="fill:none" /><g id="g2256"><path transform="matrix(1.4142135,0,0,1.4142135,-86.874996,-12.771743)" - d="m 209.92234,31.304852 a 1.0606602,1.0606602 0 1 1 -2.12132,0 1.0606602,1.0606602 0 1 1 2.12132,0 z" + d="m 209.92234,31.304852 c 0,0.585786 -0.47487,1.06066 -1.06066,1.06066 -0.58579,0 -1.06066,-0.474874 -1.06066,-1.06066 0,-0.585787 0.47487,-1.060661 1.06066,-1.060661 0.58579,0 1.06066,0.474874 1.06066,1.060661 z" sodipodi:ry="1.0606602" sodipodi:rx="1.0606602" sodipodi:cy="31.304852" @@ -739,10 +735,10 @@ sodipodi:cy="31.304852" sodipodi:rx="1.0606602" sodipodi:ry="1.0606602" - d="m 209.92234,31.304852 a 1.0606602,1.0606602 0 1 1 -2.12132,0 1.0606602,1.0606602 0 1 1 2.12132,0 z" + d="m 209.92234,31.304852 c 0,0.585786 -0.47487,1.06066 -1.06066,1.06066 -0.58579,0 -1.06066,-0.474874 -1.06066,-1.06066 0,-0.585787 0.47487,-1.060661 1.06066,-1.060661 0.58579,0 1.06066,0.474874 1.06066,1.060661 z" transform="matrix(1.4142135,0,0,1.4142135,-86.874986,-7.771742)" /><path transform="matrix(1.4142135,0,0,1.4142135,-86.874986,-2.771743)" - d="m 209.92234,31.304852 a 1.0606602,1.0606602 0 1 1 -2.12132,0 1.0606602,1.0606602 0 1 1 2.12132,0 z" + d="m 209.92234,31.304852 c 0,0.585786 -0.47487,1.06066 -1.06066,1.06066 -0.58579,0 -1.06066,-0.474874 -1.06066,-1.06066 0,-0.585787 0.47487,-1.060661 1.06066,-1.060661 0.58579,0 1.06066,0.474874 1.06066,1.060661 z" sodipodi:ry="1.0606602" sodipodi:rx="1.0606602" sodipodi:cy="31.304852" @@ -752,27 +748,36 @@ sodipodi:type="arc" /></g><g id="g2378"><path id="path3288" - d="m 23,157 -2,0 0,2 2,0 z" /><path + d="m 23,157 -2,0 0,2 2,0 z" + inkscape:connector-curvature="0" /><path id="path3286" - d="m 23,161 -2,0 0,2 c 1,0 2,-1 2,-2 z" /><path + d="m 23,161 -2,0 0,2 c 1,0 2,-1 2,-2 z" + inkscape:connector-curvature="0" /><path id="path3284" - d="m 23,153 -2,0 0,2 2,0 z" /><path + d="m 23,153 -2,0 0,2 2,0 z" + inkscape:connector-curvature="0" /><path id="path3282" - d="m 21,149 0,2 2,0 c 0,-1 -1,-2 -2,-2 z" /><path + d="m 21,149 0,2 2,0 c 0,-1 -1,-2 -2,-2 z" + inkscape:connector-curvature="0" /><path sodipodi:nodetypes="scccss" inkscape:connector-curvature="0" id="path3280" d="m 11,163 4,0 0,-6 -6,0 0,4 c 0,1.1 0.9,2 2,2 z" /><path id="path3278" - d="m 11,153 -2,0 0,2 2,0 z" /><path + d="m 11,153 -2,0 0,2 2,0 z" + inkscape:connector-curvature="0" /><path id="path3276" - d="m 19,149 -2,0 0,2 2,0 z" /><path + d="m 19,149 -2,0 0,2 2,0 z" + inkscape:connector-curvature="0" /><path id="path3274" - d="m 19,161 -2,0 0,2 2,0 z" /><path + d="m 19,161 -2,0 0,2 2,0 z" + inkscape:connector-curvature="0" /><path id="path3272" - d="m 11,149 c -1,0 -2,1 -2,2 l 2,0 z" /><path + d="m 11,149 c -1,0 -2,1 -2,2 l 2,0 z" + inkscape:connector-curvature="0" /><path id="path3231" - d="m 15,149 -2,0 0,2 2,0 z" /></g><g + d="m 15,149 -2,0 0,2 2,0 z" + inkscape:connector-curvature="0" /></g><g id="g2383"><g id="g4042"><path sodipodi:type="arc" @@ -782,7 +787,7 @@ sodipodi:cy="155.38257" sodipodi:rx="4.3973203" sodipodi:ry="4.6182914" - d="m 80.87534,155.38257 a 4.3973203,4.6182914 0 1 1 -8.794641,0 4.3973203,4.6182914 0 1 1 8.794641,0 z" + d="m 80.87534,155.38257 c 0,2.55061 -1.968747,4.61829 -4.39732,4.61829 -2.428573,0 -4.397321,-2.06768 -4.397321,-4.61829 0,-2.55061 1.968748,-4.61829 4.397321,-4.61829 2.428573,0 4.39732,2.06768 4.39732,4.61829 z" transform="matrix(1.1939089,0,0,1.1367841,-44.307792,-20.636427)" /><rect style="fill:#000000;fill-opacity:1;stroke:none" id="rect4010" @@ -792,9 +797,10 @@ y="155" rx="0.38569456" ry="0" /></g></g><path - d="M0 0h24v24H0z" - fill="none" - id="path3242" /><g + d="M 0,0 H 24 V 24 H 0 z" + id="path3242" + inkscape:connector-curvature="0" + style="fill:none" /><g id="g2387"><path inkscape:connector-curvature="0" id="path3240" @@ -942,7 +948,7 @@ sketch:type="MSShapeGroup" /></g></g></g></g><polygon style="opacity:0.5;fill:none;stroke:none" id="bounds-5" - points="16,0 16,16 0,16 0,0 " + points="0,0 16,0 16,16 0,16 " transform="translate(232.08128,27.81372)" /><g id="g3185"><path id="path3730" @@ -1024,12 +1030,13 @@ id="path3294" /></g><g id="g2191"><path id="path3555-5" - d="M 16 6 C 12.69 6 10 8.69 10 12 C 10 15.31 12.69 18 16 18 C 19.31 18 22 15.31 22 12 L 20 12 C 20 14.209139 18.209139 16 16 16 C 13.790861 16 12 14.209139 12 12 C 12 9.7908611 13.790861 8 16 8 C 17.275627 8 18.392569 8.6012713 19.125 9.53125 L 21.46875 9.53125 C 20.526539 7.4496106 18.430781 6 16 6 z " /><path + d="m 16,6 c -3.31,0 -6,2.69 -6,6 0,3.31 2.69,6 6,6 3.31,0 6,-2.69 6,-6 l -2,0 c 0,2.209139 -1.790861,4 -4,4 -2.209139,0 -4,-1.790861 -4,-4 0,-2.2091389 1.790861,-4 4,-4 1.275627,0 2.392569,0.6012713 3.125,1.53125 l 2.34375,0 C 20.526539,7.4496106 18.430781,6 16,6 z" + inkscape:connector-curvature="0" /><path sodipodi:nodetypes="cccc" inkscape:connector-curvature="0" id="path3660" d="m 21.090773,6.879988 0,3.0918004 -3.0918,0 z" - style="fill:#000000;stroke:#000000;stroke-width:1.06808328999999991px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /></g><path + style="fill:#000000;stroke:#000000;stroke-width:1.06808329px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /></g><path style="fill:none" inkscape:connector-curvature="0" d="m 169,29 h 18 v 18 h -18 z" @@ -1067,7 +1074,7 @@ id="path4367-6-6" /><path style="fill:none" inkscape:connector-curvature="0" - d="m 295.25,75.250001 h 20 v 20 h -20 z" + d="m 295.25,75.250001 h 20 V 95.25 h -20 z" id="path5182-06" /><path style="fill:none" inkscape:connector-curvature="0" @@ -1090,7 +1097,7 @@ id="path4367-6-8" /><path style="fill:none" inkscape:connector-curvature="0" - d="m 327.25,75.250001 h 20 v 20 h -20 z" + d="m 327.25,75.250001 h 20 V 95.25 h -20 z" id="path5182-7" /><path style="fill:none" inkscape:connector-curvature="0" @@ -1118,7 +1125,7 @@ style="fill:#ffffff;fill-opacity:0;stroke:none" id="bg-2" x="191.87378" - y="-0.0435686" + y="-0.043567657" width="14" height="14" /><g id="g2271"><circle @@ -1140,7 +1147,7 @@ style="fill:#000000;stroke:none" /></g><path style="fill:none" inkscape:connector-curvature="0" - d="m 292.76613,72.135146 h 24 v 24 h -24 z" + d="m 292.76613,72.135146 h 24 V 96.13515 h -24 z" id="path3652" /><path style="fill:none" inkscape:connector-curvature="0" @@ -1148,7 +1155,7 @@ id="path3763" /><path style="fill:none" inkscape:connector-curvature="0" - d="m 236.19418,70.013825 h 24 v 24 h -24 z" + d="m 236.19418,70.013825 h 24 V 94.01382 h -24 z" id="path3343" /><g id="g2237"><path id="path3345" @@ -1233,7 +1240,7 @@ id="rect3639-9" transform="scale(-1,1)" /></g></g><g id="g2528"><g - transform="rotate(-90,241.5,153.5)" + transform="matrix(0,-1,1,0,88,395)" id="g1088"><rect height="12" width="14" @@ -1270,7 +1277,7 @@ width="1" height="13" /></g></g></g><g id="g2442"><g - transform="rotate(-90,273.5,105.5)" + transform="matrix(0,-1,1,0,168,379)" id="g1243"><rect height="12" width="14" @@ -1290,7 +1297,7 @@ transform="scale(-1,1)" /></g></g><g id="g2448"><g id="g1248-3" - transform="rotate(-90,257.5,57.5)"><rect + transform="matrix(0,-1,1,0,200,315)"><rect height="12" width="14" x="-214.5" @@ -1306,4 +1313,131 @@ x="-211" y="102" id="rect3633-4-9" - transform="scale(-1,1)" /></g></g></svg> \ No newline at end of file + transform="scale(-1,1)" /></g></g><g + id="g3829" + transform="translate(1,0)"><path + inkscape:connector-curvature="0" + id="path3519-7" + d="m 20,180 0,-7 2,0 0,7 -2,0 z" /><path + inkscape:connector-curvature="0" + id="path3521-5" + d="m 17,179 0,-6 2,0 0,6 -2,0 z" /><path + inkscape:connector-curvature="0" + id="path3523-3" + d="m 14,181 0,-8 2,0 0,8 -2,0 z" /><path + inkscape:connector-curvature="0" + id="path3525-5" + d="m 11,185 0,-12 2,0 0,12 -2,0 z" /><path + inkscape:connector-curvature="0" + id="path3525-5-6" + d="m 8,177 0,-4 2,0 0,4 -2,0 z" /><path + inkscape:connector-curvature="0" + id="path3519-7-2" + d="m 20,180 0,-7 2,0 0,7 -2,0 z" /><path + inkscape:connector-curvature="0" + id="path3521-5-9" + d="m 17,179 0,-6 2,0 0,6 -2,0 z" /><path + inkscape:connector-curvature="0" + id="path3523-3-1" + d="m 14,181 0,-8 2,0 0,8 -2,0 z" /><path + inkscape:connector-curvature="0" + id="path3525-5-2" + d="m 11,185 0,-12 2,0 0,12 -2,0 z" /><path + inkscape:connector-curvature="0" + id="path3525-5-6-7" + d="m 8,177 0,-4 2,0 0,4 -2,0 z" /></g><g + id="g3899"><path + inkscape:connector-curvature="0" + id="path3519-7-9" + d="m 48,185 -7,0 0,2 7,0 0,-2 z" /><path + inkscape:connector-curvature="0" + id="path3521-5-3" + d="m 47,182 -6,0 0,2 6,0 0,-2 z" /><path + inkscape:connector-curvature="0" + id="path3523-3-6" + d="m 49,179 -8,0 0,2 8,0 0,-2 z" /><path + inkscape:connector-curvature="0" + id="path3525-5-0" + d="m 53,176 -12,0 0,2 12,0 0,-2 z" /><path + inkscape:connector-curvature="0" + id="path3525-5-6-6" + d="m 45,173 -4,0 0,2 4,0 0,-2 z" /><path + inkscape:connector-curvature="0" + id="path3519-7-2-2" + d="m 48,185 -7,0 0,2 7,0 0,-2 z" /><path + inkscape:connector-curvature="0" + id="path3521-5-9-6" + d="m 47,182 -6,0 0,2 6,0 0,-2 z" /><path + inkscape:connector-curvature="0" + id="path3523-3-1-1" + d="m 53,179 -12,0 0,2 12,0 0,-2 z" /><path + inkscape:connector-curvature="0" + id="path3525-5-2-8" + d="m 55,176 -14,0 0,2 14,0 0,-2 z" /><path + inkscape:connector-curvature="0" + id="path3525-5-6-7-7" + d="m 45,173 -4,0 0,2 4,0 0,-2 z" /></g><g + id="g5005"><path + inkscape:connector-curvature="0" + id="path3519-7-9-2" + d="m 84,185 -8,0 0,2 8,0 0,-2 z" /><path + inkscape:connector-curvature="0" + id="path3523-3-6-2" + d="m 86,179 -7,0 0,2 7,0 0,-2 z" /><path + inkscape:connector-curvature="0" + id="path3521-5-9-6-9" + d="m 83,182 -4,0 0,2 4,0 0,-2 z" /><path + inkscape:connector-curvature="0" + id="path3525-5-2-8-2" + d="m 88,176 -12,0 0,2 12,0 0,-2 z" /><path + inkscape:connector-curvature="0" + id="path3525-5-6-7-7-8" + d="m 79,173 -6,0 0,2 6,0 0,-2 z" /><path + style="opacity:0.4" + inkscape:connector-curvature="0" + id="path3517-7-9" + d="m 77,176 0,2 -4,0 0,-2 4,0 z" /><path + style="opacity:0.4" + inkscape:connector-curvature="0" + id="path3517-7-9-3" + d="m 77,185 0,2 -4,0 0,-2 4,0 z" /><path + style="opacity:0.4" + inkscape:connector-curvature="0" + id="path3517-7-9-3-1" + d="m 80,179 0,2 -4,0 0,-2 4,0 z" /><path + style="opacity:0.4" + inkscape:connector-curvature="0" + id="path3517-7-9-3-1-7" + d="m 80,182 0,2 -4,0 0,-2 4,0 z" /></g><g + id="g5016"><path + inkscape:connector-curvature="0" + id="path3519-7-9-2-4" + d="m 104,175 8,0 0,-2 -8,0 0,2 z" /><path + inkscape:connector-curvature="0" + id="path3523-3-6-2-5" + d="m 104,181 7,0 0,-2 -7,0 0,2 z" /><path + inkscape:connector-curvature="0" + id="path3521-5-9-6-9-0" + d="m 104,178 4,0 0,-2 -4,0 0,2 z" /><path + inkscape:connector-curvature="0" + id="path3525-5-2-8-2-3" + d="m 104,184 12,0 0,-2 -12,0 0,2 z" /><path + inkscape:connector-curvature="0" + id="path3525-5-6-7-7-8-6" + d="m 113,187 6,0 0,-2 -6,0 0,2 z" /><path + style="opacity:0.4" + inkscape:connector-curvature="0" + id="path3517-7-9-1" + d="m 115,184 0,-2 4,0 0,2 -4,0 z" /><path + style="opacity:0.4" + inkscape:connector-curvature="0" + id="path3517-7-9-3-0" + d="m 112,175 0,-2 7,0 0,2 -7,0 z" /><path + style="opacity:0.4" + inkscape:connector-curvature="0" + id="path3517-7-9-3-1-6" + d="m 110,181 0,-2 6,0 0,2 -6,0 z" /><path + style="opacity:0.4" + inkscape:connector-curvature="0" + id="path3517-7-9-3-1-7-3" + d="m 108,178 0,-2 8,0 0,2 -8,0 z" /></g></svg> \ No newline at end of file
diff --git a/third_party/WebKit/Source/devtools/front_end/Images/toolbarButtonGlyphs.png b/third_party/WebKit/Source/devtools/front_end/Images/toolbarButtonGlyphs.png index 6e29b0e9..c3d678c 100644 --- a/third_party/WebKit/Source/devtools/front_end/Images/toolbarButtonGlyphs.png +++ b/third_party/WebKit/Source/devtools/front_end/Images/toolbarButtonGlyphs.png Binary files differ
diff --git a/third_party/WebKit/Source/devtools/front_end/Images/toolbarButtonGlyphs_2x.png b/third_party/WebKit/Source/devtools/front_end/Images/toolbarButtonGlyphs_2x.png index 46d3416..450877f 100644 --- a/third_party/WebKit/Source/devtools/front_end/Images/toolbarButtonGlyphs_2x.png +++ b/third_party/WebKit/Source/devtools/front_end/Images/toolbarButtonGlyphs_2x.png Binary files differ
diff --git a/third_party/WebKit/Source/devtools/front_end/timeline/TimelinePanel.js b/third_party/WebKit/Source/devtools/front_end/timeline/TimelinePanel.js index a9de61fd..295a7fd 100644 --- a/third_party/WebKit/Source/devtools/front_end/timeline/TimelinePanel.js +++ b/third_party/WebKit/Source/devtools/front_end/timeline/TimelinePanel.js
@@ -118,6 +118,10 @@ this._tabbedPane.appendTab(viewMode.BottomUp, Common.UIString('Bottom-Up'), new UI.VBox()); this._tabbedPane.appendTab(viewMode.CallTree, Common.UIString('Call Tree'), new UI.VBox()); this._tabbedPane.appendTab(viewMode.EventLog, Common.UIString('Event Log'), new UI.VBox()); + this._tabbedPane.setTabIcon(viewMode.FlameChart, UI.Icon.create('largeicon-perf-flamechart')); + this._tabbedPane.setTabIcon(viewMode.BottomUp, UI.Icon.create('largeicon-perf-bottom-up-tree')); + this._tabbedPane.setTabIcon(viewMode.CallTree, UI.Icon.create('largeicon-perf-call-tree')); + this._tabbedPane.setTabIcon(viewMode.EventLog, UI.Icon.create('largeicon-perf-event-list')); this._tabbedPane.addEventListener(UI.TabbedPane.Events.TabSelected, this._onMainViewChanged.bind(this)); this._tabbedPane.selectTab(this._viewModeSetting.get()); } else { @@ -139,9 +143,6 @@ Extensions.extensionServer.addEventListener( Extensions.ExtensionServer.Events.TraceProviderAdded, this._appendExtensionsToToolbar, this); SDK.targetManager.addEventListener(SDK.TargetManager.Events.SuspendStateChanged, this._onSuspendStateChanged, this); - - /** @type {!SDK.TracingModel.Event}|undefined */ - this._selectedSearchResult; } /**
diff --git a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineUIUtils.js b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineUIUtils.js index 24ed2206..ee40700 100644 --- a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineUIUtils.js +++ b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineUIUtils.js
@@ -1212,6 +1212,17 @@ contentHelper.addSection(Common.UIString('Invalidations')); Timeline.TimelineUIUtils._generateInvalidations(event, target, relatedNodesMap, contentHelper); } else if (initiator) { // Partial invalidation tracking. + var delay = event.startTime - initiator.startTime; + contentHelper.appendTextRow(Common.UIString('Pending for'), Number.preciseMillisToString(delay, 1)); + + var link = createElementWithClass('span', 'devtools-link'); + link.textContent = Common.UIString('reveal'); + link.addEventListener('click', () => { + Timeline.TimelinePanel.instance().select( + Timeline.TimelineSelection.fromTraceEvent(/** @type {!SDK.TracingModel.Event} */ (initiator))); + }); + contentHelper.appendElementRow(Common.UIString('Initiator'), link); + var initiatorStackTrace = TimelineModel.TimelineData.forEvent(initiator).stackTrace; if (initiatorStackTrace) { contentHelper.appendStackTrace(
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/Icon.js b/third_party/WebKit/Source/devtools/front_end/ui/Icon.js index 0b3c08a..4dd053c 100644 --- a/third_party/WebKit/Source/devtools/front_end/ui/Icon.js +++ b/third_party/WebKit/Source/devtools/front_end/ui/Icon.js
@@ -169,6 +169,10 @@ 'largeicon-dock-to-bottom': {x: -32, y: -24, width: 28, height: 24, spritesheet: 'largeicons', isMask: true}, 'largeicon-undock': {x: 0, y: -48, width: 28, height: 24, spritesheet: 'largeicons', isMask: true}, 'largeicon-settings-gear': {x: -288, y: -72, width: 28, height: 24, spritesheet: 'largeicons', isMask: true}, + 'largeicon-perf-flamechart': {x: -4, y: -168, width: 24, height: 24, spritesheet: 'largeicons', isMask: true}, + 'largeicon-perf-event-list': {x: -36, y: -168, width: 24, height: 24, spritesheet: 'largeicons', isMask: true}, + 'largeicon-perf-call-tree': {x: -68, y: -168, width: 24, height: 24, spritesheet: 'largeicons', isMask: true}, + 'largeicon-perf-bottom-up-tree': {x: -100, y: -168, width: 24, height: 24, spritesheet: 'largeicons', isMask: true}, 'largeicon-show-left-sidebar': {x: -160, y: -72, width: 28, height: 24, spritesheet: 'largeicons', isMask: true}, 'largeicon-hide-left-sidebar': {x: -192, y: -72, width: 28, height: 24, spritesheet: 'largeicons', isMask: true},
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/inspectorCommon.css b/third_party/WebKit/Source/devtools/front_end/ui/inspectorCommon.css index 009b7db..3c8faf08 100644 --- a/third_party/WebKit/Source/devtools/front_end/ui/inspectorCommon.css +++ b/third_party/WebKit/Source/devtools/front_end/ui/inspectorCommon.css
@@ -343,12 +343,12 @@ .spritesheet-largeicons:not(.icon-mask) { background-image: -webkit-image-set(url(Images/toolbarButtonGlyphs.png) 1x, url(Images/toolbarButtonGlyphs_2x.png) 2x); - background-size: 352px 168px; + background-size: 352px 192px; } .spritesheet-largeicons.icon-mask { -webkit-mask-image: -webkit-image-set(url(Images/toolbarButtonGlyphs.png) 1x, url(Images/toolbarButtonGlyphs_2x.png) 2x); - -webkit-mask-size: 352px 168px; + -webkit-mask-size: 352px 192px; } .spritesheet-resourceicons:not(.icon-mask) { @@ -372,7 +372,7 @@ .force-white-icons [is=ui-icon].spritesheet-largeicons, [is=ui-icon].force-white-icons.spritesheet-largeicons { -webkit-mask-image: -webkit-image-set(url(Images/toolbarButtonGlyphs.png) 1x, url(Images/toolbarButtonGlyphs_2x.png) 2x); - -webkit-mask-size: 352px 168px; + -webkit-mask-size: 352px 192px; background-image: unset; background-size: unset; background: unset;
diff --git a/tools/gritsettings/resource_ids b/tools/gritsettings/resource_ids index a946de5b..300ea7d9 100644 --- a/tools/gritsettings/resource_ids +++ b/tools/gritsettings/resource_ids
@@ -113,9 +113,6 @@ "chrome/browser/resources/quota_internals_resources.grd": { "includes": [11990], }, - "chrome/browser/resources/settings/settings_resources_vulcanized.grd": { - "includes": [12010], - }, "chrome/browser/resources/settings/settings_resources.grd": { "structures": [12020], },
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 1494ddb..096ec4e 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -77860,20 +77860,24 @@ </histogram> <histogram name="Welcome.Win10.NewPromoPageAdded" enum="BooleanShown"> + <owner>pmonette@chromium.org</owner> <owner>tmartino@chromium.org</owner> <summary> - Records whether or not the revamped WebUI-based welcome page was added to - the startup tabs list. This means there is a good chance it was shown to the - user. + Emits a "true" sample when the revamped WebUI-based welcome page + is added to the startup tabs list. This means that barring an error on + startup, it was shown to the user. This histogram can only be recorded + during first-run flow, when the EnableWelcomeWin10 experiment is enabled. </summary> </histogram> <histogram name="Welcome.Win10.OriginalPromoPageAdded" enum="BooleanShown"> + <owner>pmonette@chromium.org</owner> <owner>tmartino@chromium.org</owner> <summary> - Records whether or not the old external welcome page was added to the - startup tabs list. This means there is a good chance it was shown to the - user. + Emits a "true" sample when the old external welcome page is added + to the startup tabs list. This means that barring an error on startup, it + was shown to the user. This histogram can only be recorded during first-run + flow, when the EnableWelcomeWin10 experiment is disabled. </summary> </histogram>
diff --git a/ui/webui/resources/cr_elements/icons.html b/ui/webui/resources/cr_elements/icons.html index 12af690f..674926d52 100644 --- a/ui/webui/resources/cr_elements/icons.html +++ b/ui/webui/resources/cr_elements/icons.html
@@ -50,10 +50,7 @@ <g id="person"><path d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z"></path></g> <g id="print"><path d="M19 8H5c-1.66 0-3 1.34-3 3v6h4v4h12v-4h4v-6c0-1.66-1.34-3-3-3zm-3 11H8v-5h8v5zm3-7c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1zm-1-9H6v4h12V3z"></path></g> <g id="search"><path d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"></path></g> - <!-- The <g> IDs are exposed as global variables in Vulcanized mode, which - conflicts with the "settings" namespace of MD Settings. Using an "_icon" - suffix prevents the naming conflict. --> - <g id="settings_icon"><path d="M19.43 12.98c.04-.32.07-.64.07-.98s-.03-.66-.07-.98l2.11-1.65c.19-.15.24-.42.12-.64l-2-3.46c-.12-.22-.39-.3-.61-.22l-2.49 1c-.52-.4-1.08-.73-1.69-.98l-.38-2.65C14.46 2.18 14.25 2 14 2h-4c-.25 0-.46.18-.49.42l-.38 2.65c-.61.25-1.17.59-1.69.98l-2.49-1c-.23-.09-.49 0-.61.22l-2 3.46c-.13.22-.07.49.12.64l2.11 1.65c-.04.32-.07.65-.07.98s.03.66.07.98l-2.11 1.65c-.19.15-.24.42-.12.64l2 3.46c.12.22.39.3.61.22l2.49-1c.52.4 1.08.73 1.69.98l.38 2.65c.03.24.24.42.49.42h4c.25 0 .46-.18.49-.42l.38-2.65c.61-.25 1.17-.59 1.69-.98l2.49 1c.23.09.49 0 .61-.22l2-3.46c.12-.22.07-.49-.12-.64l-2.11-1.65zM12 15.5c-1.93 0-3.5-1.57-3.5-3.5s1.57-3.5 3.5-3.5 3.5 1.57 3.5 3.5-1.57 3.5-3.5 3.5z"></path></g> + <g id="settings"><path d="M19.43 12.98c.04-.32.07-.64.07-.98s-.03-.66-.07-.98l2.11-1.65c.19-.15.24-.42.12-.64l-2-3.46c-.12-.22-.39-.3-.61-.22l-2.49 1c-.52-.4-1.08-.73-1.69-.98l-.38-2.65C14.46 2.18 14.25 2 14 2h-4c-.25 0-.46.18-.49.42l-.38 2.65c-.61.25-1.17.59-1.69.98l-2.49-1c-.23-.09-.49 0-.61.22l-2 3.46c-.13.22-.07.49.12.64l2.11 1.65c-.04.32-.07.65-.07.98s.03.66.07.98l-2.11 1.65c-.19.15-.24.42-.12.64l2 3.46c.12.22.39.3.61.22l2.49-1c.52.4 1.08.73 1.69.98l.38 2.65c.03.24.24.42.49.42h4c.25 0 .46-.18.49-.42l.38-2.65c.61-.25 1.17-.59 1.69-.98l2.49 1c.23.09.49 0 .61-.22l2-3.46c.12-.22.07-.49-.12-.64l-2.11-1.65zM12 15.5c-1.93 0-3.5-1.57-3.5-3.5s1.57-3.5 3.5-3.5 3.5 1.57 3.5 3.5-1.57 3.5-3.5 3.5z"></path></g> <g id="star"><path d="M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z"></path></g> <g id="warning"><path d="M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z"></path></g> </defs>