diff --git a/DEPS b/DEPS index 48b461da1..0b902f3 100644 --- a/DEPS +++ b/DEPS
@@ -74,7 +74,7 @@ # 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': '06ab3836f779dbcbcd067a9261300616ff7cc594', + 'skia_revision': 'a3e9271ec41db6c3b6886e50053f37d345ab1d5c', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. @@ -130,7 +130,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. - 'catapult_revision': '37c17ee783f358fa01ae994ed89162722b961616', + 'catapult_revision': '09fc536c66c644ad0ec55b8048d5efe11e4af7c7', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other.
diff --git a/ash/wm/overview/window_selector_controller.cc b/ash/wm/overview/window_selector_controller.cc index d95d165..e6d3e3a 100644 --- a/ash/wm/overview/window_selector_controller.cc +++ b/ash/wm/overview/window_selector_controller.cc
@@ -20,6 +20,7 @@ #include "ash/wm/window_state.h" #include "ash/wm/window_util.h" #include "base/metrics/histogram_macros.h" +#include "base/metrics/user_metrics.h" namespace ash { @@ -165,6 +166,8 @@ // in overview mode. To work around this set |active_window| before exiting // split view. wm::ActivateWindow(active_window); + base::RecordAction( + base::UserMetricsAction("Tablet_LongPressOverviewButtonExitSplitView")); return; } @@ -187,6 +190,8 @@ // mode. split_view_controller->SnapWindow(active_window, SplitViewController::LEFT); ToggleOverview(); + base::RecordAction(base::UserMetricsAction( + "Tablet_LongPressOverviewButtonEnterSplitView")); return; } @@ -219,6 +224,8 @@ window_selector_->SetBoundsForWindowGridsInScreen( split_view_controller->GetSnappedWindowBoundsInScreen( window, SplitViewController::RIGHT)); + base::RecordAction( + base::UserMetricsAction("Tablet_LongPressOverviewButtonEnterSplitView")); } std::vector<aura::Window*>
diff --git a/ash/wm/splitview/split_view_controller.cc b/ash/wm/splitview/split_view_controller.cc index addf46b..5bbff42 100644 --- a/ash/wm/splitview/split_view_controller.cc +++ b/ash/wm/splitview/split_view_controller.cc
@@ -23,6 +23,8 @@ #include "ash/wm/window_util.h" #include "ash/wm/wm_event.h" #include "base/command_line.h" +#include "base/metrics/histogram_macros.h" +#include "base/metrics/user_metrics.h" #include "base/optional.h" #include "ui/aura/window.h" #include "ui/aura/window_delegate.h" @@ -151,6 +153,7 @@ default_snap_position_ = snap_position; split_view_divider_ = std::make_unique<SplitViewDivider>(this, window->GetRootWindow()); + splitview_start_time_ = base::Time::Now(); } State previous_state = state_; @@ -189,6 +192,7 @@ window->parent()->StackChildBelow(stacking_target, window); NotifySplitViewStateChanged(previous_state, state_); + base::RecordAction(base::UserMetricsAction("SplitView_SnapWindow")); } void SplitViewController::SwapWindows() { @@ -202,6 +206,9 @@ SnapWindow(new_left_window, LEFT); SnapWindow(new_right_window, RIGHT); + + base::RecordAction( + base::UserMetricsAction("SplitView_DoubleTapDividerSwapWindows")); } aura::Window* SplitViewController::GetDefaultSnappedWindow() { @@ -271,6 +278,7 @@ is_resizing_ = true; split_view_divider_->UpdateDividerBounds(is_resizing_); previous_event_location_ = location_in_screen; + base::RecordAction(base::UserMetricsAction("SplitView_ResizeWindows")); } void SplitViewController::Resize(const gfx::Point& location_in_screen) { @@ -358,6 +366,9 @@ NotifySplitViewStateChanged(previous_state, state_); Shell::Get()->NotifySplitViewModeEnded(); + base::RecordAction(base::UserMetricsAction("SplitView_EndSplitView")); + UMA_HISTOGRAM_LONG_TIMES("Ash.SplitView.TimeInSplitView", + base::Time::Now() - splitview_start_time_); } void SplitViewController::AddObserver(Observer* observer) {
diff --git a/ash/wm/splitview/split_view_controller.h b/ash/wm/splitview/split_view_controller.h index 515b70fde..84fc18d4 100644 --- a/ash/wm/splitview/split_view_controller.h +++ b/ash/wm/splitview/split_view_controller.h
@@ -11,6 +11,7 @@ #include "ash/wm/window_state_observer.h" #include "base/macros.h" #include "base/observer_list.h" +#include "base/time/time.h" #include "third_party/WebKit/public/platform/modules/screen_orientation/WebScreenOrientationLockType.h" #include "ui/aura/window_observer.h" #include "ui/display/display.h" @@ -280,6 +281,9 @@ // If the divider is currently being dragging. bool is_resizing_ = false; + // The time when splitview starts. Used for metric collection purpose. + base::Time splitview_start_time_; + base::ObserverList<Observer> observers_; DISALLOW_COPY_AND_ASSIGN(SplitViewController);
diff --git a/build/secondary/third_party/android_platform/development/scripts/BUILD.gn b/build/secondary/third_party/android_platform/development/scripts/BUILD.gn index d808824..2ac12d7 100644 --- a/build/secondary/third_party/android_platform/development/scripts/BUILD.gn +++ b/build/secondary/third_party/android_platform/development/scripts/BUILD.gn
@@ -13,5 +13,9 @@ sources = _py_files data = sources - data += [ "//third_party/llvm-build/Release+Asserts/bin/llvm-symbolizer" ] + data += [ + "${android_tool_prefix}addr2line", + "${android_tool_prefix}objdump", + "${android_tool_prefix}c++filt", + ] }
diff --git a/cc/trees/layer_tree_impl.cc b/cc/trees/layer_tree_impl.cc index 5026d38..00b78eac 100644 --- a/cc/trees/layer_tree_impl.cc +++ b/cc/trees/layer_tree_impl.cc
@@ -1878,6 +1878,7 @@ LayerImpl* root_layer, const Functor& func, FindClosestMatchingLayerState* state) { + base::ElapsedTimer timer; // We want to iterate from front to back when hit testing. for (auto* layer : base::Reversed(*root_layer->layer_tree_impl())) { if (!func(layer)) @@ -1906,6 +1907,12 @@ state->closest_match = layer; } } + if (const char* client_name = GetClientNameForMetrics()) { + UMA_HISTOGRAM_COUNTS_1M( + base::StringPrintf("Compositing.%s.HitTestTimeToFindClosestLayer", + client_name), + timer.Elapsed().InMicroseconds()); + } } struct FindScrollingLayerOrDrawnScrollbarFunctor {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrDaydreamApi.java b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrDaydreamApi.java index 0dd76d3..97df7f36 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrDaydreamApi.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrDaydreamApi.java
@@ -63,4 +63,10 @@ * Launch the stereoscopic, 3D VR launcher homescreen. */ boolean launchVrHomescreen(); + + /** + * @return Whether this device boots directly into VR mode. May be used to detect standalone VR + * devices. + */ + boolean bootsToVr(); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrDaydreamApiImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrDaydreamApiImpl.java index 2df7ff8..891cfa6 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrDaydreamApiImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrDaydreamApiImpl.java
@@ -14,8 +14,10 @@ import com.google.vr.ndk.base.DaydreamApi; import com.google.vr.ndk.base.GvrApi; +import org.chromium.base.Log; import org.chromium.ui.base.WindowAndroid; +import java.lang.reflect.Method; /** * A wrapper for DaydreamApi. Note that we have to recreate the DaydreamApi instance each time we @@ -24,6 +26,10 @@ public class VrDaydreamApiImpl implements VrDaydreamApi { private final Context mContext; + private Boolean mBootsToVr = null; + + public static final String VR_BOOT_SYSTEM_PROPERTY = "ro.boot.vr"; + public VrDaydreamApiImpl(Context context) { mContext = context; } @@ -112,4 +118,28 @@ daydreamApi.close(); return true; } + + @Override + public boolean bootsToVr() { + if (mBootsToVr == null) { + // TODO(mthiesse): Replace this with a Daydream API call when supported. + // Note that System.GetProperty is unable to read system ro properties, so we have to + // resort to reflection as seen below. This method of reading system properties has been + // available since API level 1. + mBootsToVr = getIntSystemProperty(VR_BOOT_SYSTEM_PROPERTY, 0) == 1; + } + return mBootsToVr; + } + + private int getIntSystemProperty(String key, int defaultValue) { + try { + final Class<?> systemProperties = Class.forName("android.os.SystemProperties"); + final Method getInt = systemProperties.getMethod("getInt", String.class, int.class); + return (Integer) getInt.invoke(null, key, defaultValue); + } catch (Exception e) { + Log.e("Exception while getting system property %s. Using default %s.", key, + defaultValue, e); + return defaultValue; + } + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java index 884fd25b..3b4f8f6 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java
@@ -318,7 +318,9 @@ */ public static int getVrSupportLevel(VrDaydreamApi daydreamApi, VrCoreVersionChecker versionChecker, Tab tabToShowInfobarIn) { - if (versionChecker == null || daydreamApi == null + // TODO(mthiesse, crbug.com/791090): Re-enable VR mode for devices that boot to VR once we + // support those devices. + if (versionChecker == null || daydreamApi == null || daydreamApi.bootsToVr() || !isVrCoreCompatible(versionChecker, tabToShowInfobarIn)) { return VR_NOT_AVAILABLE; }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/VrShellControllerInputTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/VrShellControllerInputTest.java index a064c65..369d743 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/VrShellControllerInputTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/VrShellControllerInputTest.java
@@ -19,7 +19,6 @@ import org.junit.runner.RunWith; import org.chromium.base.test.util.CommandLineFlags; -import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Restriction; import org.chromium.base.test.util.RetryOnFailure; import org.chromium.chrome.browser.ChromeSwitches; @@ -60,7 +59,6 @@ * Verifies that swiping up/down/left/right on the Daydream controller's * touchpad scrolls the webpage while in the VR browser. */ - @DisabledTest(message = "crbug.com/786200") @Test @MediumTest public void testControllerScrolling() throws InterruptedException {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/mock/MockVrDaydreamApi.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/mock/MockVrDaydreamApi.java index b90cb1b1..345070d 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/mock/MockVrDaydreamApi.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/mock/MockVrDaydreamApi.java
@@ -65,4 +65,9 @@ public boolean getLaunchInVrCalled() { return mLaunchInVrCalled; } + + @Override + public boolean bootsToVr() { + return false; + } }
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 7b7c832..f423a57b 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -3205,6 +3205,10 @@ "printing/print_view_manager_base.h", "printing/print_view_manager_common.cc", "printing/print_view_manager_common.h", + "printing/printer_manager_dialog.h", + "printing/printer_manager_dialog_linux.cc", + "printing/printer_manager_dialog_mac.mm", + "printing/printer_manager_dialog_win.cc", "printing/printer_query.cc", "printing/printer_query.h", "printing/printing_init.cc", @@ -3246,10 +3250,6 @@ "printing/print_preview_message_handler.h", "printing/print_view_manager.cc", "printing/print_view_manager.h", - "printing/printer_manager_dialog.h", - "printing/printer_manager_dialog_linux.cc", - "printing/printer_manager_dialog_mac.mm", - "printing/printer_manager_dialog_win.cc", "printing/pwg_raster_converter.cc", "printing/pwg_raster_converter.h", ]
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn index 39e13da..a297c35 100644 --- a/chrome/browser/chromeos/BUILD.gn +++ b/chrome/browser/chromeos/BUILD.gn
@@ -1401,6 +1401,8 @@ "printing/cups_print_job_notification_manager.h", "printing/cups_printers_manager.cc", "printing/cups_printers_manager.h", + "printing/external_printers.cc", + "printing/external_printers.h", "printing/ppd_provider_factory.cc", "printing/ppd_provider_factory.h", "printing/printer_configurer.cc", @@ -1927,6 +1929,7 @@ "power/renderer_freezer_unittest.cc", "preferences_unittest.cc", "printing/cups_printers_manager_unittest.cc", + "printing/external_printers_unittest.cc", "printing/printer_detector_test_util.h", "printing/printer_event_tracker_unittest.cc", "printing/printers_sync_bridge_unittest.cc",
diff --git a/chrome/browser/chromeos/printing/external_printers.cc b/chrome/browser/chromeos/printing/external_printers.cc new file mode 100644 index 0000000..1e1b325 --- /dev/null +++ b/chrome/browser/chromeos/printing/external_printers.cc
@@ -0,0 +1,233 @@ +// 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 "chrome/browser/chromeos/printing/external_printers.h" + +#include <set> +#include <utility> + +#include "base/json/json_reader.h" +#include "base/memory/ptr_util.h" +#include "base/memory/weak_ptr.h" +#include "base/observer_list.h" +#include "base/sequence_checker.h" +#include "base/stl_util.h" +#include "base/values.h" +#include "chromeos/printing/printer_translator.h" + +namespace chromeos { +namespace { + +constexpr int kMaxRecords = 20000; + +class ExternalPrintersImpl : public ExternalPrinters { + public: + ExternalPrintersImpl() = default; + ~ExternalPrintersImpl() override = default; + + // Resets the printer state fields. + void ClearData() override { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + bool notify = !printers_.empty(); + policy_retrieved_ = false; + printers_ready_ = false; + + // Swap with empty vectors to release the allocated memory. + std::vector<Printer> empty; + printers_.swap(empty); + std::vector<std::unique_ptr<Printer>> empty_ptrs; + all_printers_.swap(empty_ptrs); + + if (notify) { + Notify(); + } + } + + void SetData(std::unique_ptr<std::string> data) override { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + int error_code; + int error_line; + std::unique_ptr<base::Value> json_blob = + base::JSONReader::ReadAndReturnError( + *data, base::JSONParserOptions::JSON_PARSE_RFC, &error_code, + nullptr /* error_msg_out */, &error_line); + // It's not valid JSON. Invalidate config. + if (!json_blob || !json_blob->is_list()) { + LOG(WARNING) << "Failed to parse external policy (" << error_code + << ") on line " << error_line; + ClearData(); + return; + } + + const base::Value::ListStorage& printer_list = json_blob->GetList(); + if (printer_list.size() > kMaxRecords) { + LOG(ERROR) << "Too many records: " << printer_list.size(); + ClearData(); + return; + } + + for (const base::Value& val : printer_list) { + // TODO(skau): Convert to the new Value APIs. + const base::DictionaryValue* printer_dict; + if (!val.GetAsDictionary(&printer_dict)) { + LOG(WARNING) << "Entry is not a dictionary."; + continue; + } + + auto printer = RecommendedPrinterToPrinter(*printer_dict); + if (!printer) { + LOG(WARNING) << "Failed to parse printer configuration."; + continue; + } + all_printers_.push_back(std::move(printer)); + } + + policy_retrieved_ = true; + RecomputePrinters(); + } + + void AddObserver(Observer* observer) override { + observers_.AddObserver(observer); + } + + void RemoveObserver(Observer* observer) override { + observers_.RemoveObserver(observer); + } + + void SetAccessMode(AccessMode mode) override { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + mode_ = mode; + RecomputePrinters(); + } + + void SetBlacklist(const std::vector<std::string>& blacklist) override { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + blacklist_.clear(); + blacklist_.insert(blacklist.begin(), blacklist.end()); + has_blacklist_ = true; + RecomputePrinters(); + } + + void SetWhitelist(const std::vector<std::string>& whitelist) override { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + whitelist_.clear(); + whitelist_.insert(whitelist.begin(), whitelist.end()); + has_whitelist_ = true; + RecomputePrinters(); + } + + // Returns true if the printer configuration has been downloaded and parsed. + bool IsPolicySet() const override { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + return printers_ready_; + } + + // Returns all the printers available from the policy. + const std::vector<Printer>& GetPrinters() const override { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + return printers_; + } + + private: + // Returns true if all required attributes have been set to compute the list + // of printers. + bool IsReady() const { + if (!policy_retrieved_) { + return false; + } + + switch (mode_) { + case AccessMode::ALL_ACCESS: + return true; + case AccessMode::BLACKLIST_ONLY: + return has_blacklist_; + case AccessMode::WHITELIST_ONLY: + return has_whitelist_; + case AccessMode::UNSET: + return false; + } + NOTREACHED(); + return false; + } + + void RecomputePrinters() { + // Assume we're not ready. + printers_ready_ = false; + if (!IsReady()) { + return; + } + + // Drop all printers, we're recomputing. + printers_.clear(); + switch (mode_) { + case UNSET: + NOTREACHED(); + break; + case WHITELIST_ONLY: + for (const auto& printer : all_printers_) { + if (base::ContainsKey(whitelist_, printer->id())) { + printers_.push_back(*printer); + } + } + break; + case BLACKLIST_ONLY: + for (const auto& printer : all_printers_) { + if (!base::ContainsKey(blacklist_, printer->id())) { + printers_.push_back(*printer); + } + } + break; + case ALL_ACCESS: + for (const auto& printer : all_printers_) { + printers_.push_back(*printer); + } + break; + } + + // Everything has been computed. Results are ready. + printers_ready_ = true; + + // We assume something changed. Notify now. + Notify(); + } + + void Notify() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + for (auto& observer : observers_) { + observer.OnPrintersChanged(); + } + } + + // True if all necessary information has been set to compute the set of + // printers. + bool printers_ready_ = false; + // Only true after the external policy has been downloaded. + bool policy_retrieved_ = false; + + AccessMode mode_ = UNSET; + bool has_blacklist_ = false; + std::set<std::string> blacklist_; + bool has_whitelist_ = false; + std::set<std::string> whitelist_; + + // Cache of the parsed printer configuration file. + std::vector<std::unique_ptr<Printer>> all_printers_; + // The computed set of printers. + std::vector<Printer> printers_; + + base::ObserverList<ExternalPrinters::Observer> observers_; + + SEQUENCE_CHECKER(sequence_checker_); + + DISALLOW_COPY_AND_ASSIGN(ExternalPrintersImpl); +}; +} // namespace + +// static +std::unique_ptr<ExternalPrinters> ExternalPrinters::Create() { + return base::MakeUnique<ExternalPrintersImpl>(); +} + +} // namespace chromeos
diff --git a/chrome/browser/chromeos/printing/external_printers.h b/chrome/browser/chromeos/printing/external_printers.h new file mode 100644 index 0000000..e7a6033 --- /dev/null +++ b/chrome/browser/chromeos/printing/external_printers.h
@@ -0,0 +1,70 @@ +// 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 CHROME_BROWSER_CHROMEOS_PRINTING_EXTERNAL_PRINTERS_H_ +#define CHROME_BROWSER_CHROMEOS_PRINTING_EXTERNAL_PRINTERS_H_ + +#include <memory> +#include <string> +#include <utility> +#include <vector> + +#include "base/macros.h" +#include "chrome/browser/chromeos/policy/cloud_external_data_policy_observer.h" +#include "chromeos/printing/printer_configuration.h" + +namespace chromeos { + +// Manages download and parsing of the external policy printer configuration and +// enforces restrictions. +class ExternalPrinters { + public: + // Choose the policy for printer access. + enum AccessMode { + UNSET, + // Printers in the blacklist are disallowed. Others are allowed. + BLACKLIST_ONLY, + // Only printers in the whitelist are allowed. + WHITELIST_ONLY, + // All printers in the policy are allowed. + ALL_ACCESS + }; + + // Observer is notified when the computed set of printers change. It is + // assumed that the observer is on the same sequence as the object it is + // observing. + class Observer { + public: + // Called when the computed set of printers changes. + virtual void OnPrintersChanged() = 0; + }; + + // Creates a handler for the external printer policies. + static std::unique_ptr<ExternalPrinters> Create(); + + virtual ~ExternalPrinters() = default; + + // Parses |data| which is the contents of the bulk printes file and extracts + // printer information. The file format is assumed to be JSON. + virtual void SetData(std::unique_ptr<std::string> data) = 0; + // Removes all printer data and invalidates the configuration. + virtual void ClearData() = 0; + + virtual void AddObserver(Observer* observer) = 0; + virtual void RemoveObserver(Observer* observer) = 0; + + virtual void SetAccessMode(AccessMode mode) = 0; + virtual void SetBlacklist(const std::vector<std::string>& blacklist) = 0; + virtual void SetWhitelist(const std::vector<std::string>& whitelist) = 0; + + // Returns true if the printer configuration has been downloaded and parsed. + virtual bool IsPolicySet() const = 0; + + // Returns all the printers available from the policy. + virtual const std::vector<Printer>& GetPrinters() const = 0; +}; + +} // namespace chromeos + +#endif // CHROME_BROWSER_CHROMEOS_PRINTING_EXTERNAL_PRINTERS_H_
diff --git a/chrome/browser/chromeos/printing/external_printers_unittest.cc b/chrome/browser/chromeos/printing/external_printers_unittest.cc new file mode 100644 index 0000000..9ce3f10 --- /dev/null +++ b/chrome/browser/chromeos/printing/external_printers_unittest.cc
@@ -0,0 +1,173 @@ +// 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 "chrome/browser/chromeos/printing/external_printers.h" + +#include <string> +#include <vector> + +#include "base/bind.h" +#include "base/memory/ptr_util.h" +#include "base/strings/stringprintf.h" +#include "base/test/scoped_task_environment.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace chromeos { +namespace { + +// The number of printers in BulkPolicyContentsJson. +constexpr size_t kNumPrinters = 3; + +// An example bulk printer configuration file. +constexpr char kBulkPolicyContentsJson[] = R"json( +[ + { + "id": "First", + "display_name": "LexaPrint", + "description": "Laser on the test shelf", + "manufacturer": "LexaPrint, Inc.", + "model": "MS610de", + "uri": "ipp://192.168.1.5", + "ppd_resource": { + "effective_model": "MS610de" + } + }, { + "id": "Second", + "display_name": "Color Laser", + "description": "The printer next to the water cooler.", + "manufacturer": "Printer Manufacturer", + "model":"Color Laser 2004", + "uri":"ipps://print-server.intranet.example.com:443/ipp/cl2k4", + "uuid":"1c395fdb-5d93-4904-b246-b2c046e79d12", + "ppd_resource":{ + "effective_manufacturer": "MakesPrinters", + "effective_model": "ColorLaser2k4" + } + }, { + "id": "Third", + "display_name": "YaLP", + "description": "Fancy Fancy Fancy", + "manufacturer": "LexaPrint, Inc.", + "model": "MS610de", + "uri": "ipp://192.168.1.8", + "ppd_resource": { + "effective_manufacturer": "LexaPrint", + "effective_model": "MS610de" + } + } +])json"; + +class ExternalPrintersTest : public testing::Test { + public: + ExternalPrintersTest() : scoped_task_environment_() { + external_printers_ = ExternalPrinters::Create(); + } + + protected: + std::unique_ptr<ExternalPrinters> external_printers_; + + private: + base::test::ScopedTaskEnvironment scoped_task_environment_; +}; + +// Verify that we're initiall unset and empty. +TEST_F(ExternalPrintersTest, InitialConditions) { + EXPECT_FALSE(external_printers_->IsPolicySet()); + EXPECT_TRUE(external_printers_->GetPrinters().empty()); +} + +// Verifies that all IsPolicySet returns false until all necessary data is set. +TEST_F(ExternalPrintersTest, PolicyUnsetWithMissingData) { + auto data = base::MakeUnique<std::string>(kBulkPolicyContentsJson); + external_printers_->ClearData(); + external_printers_->SetData(std::move(data)); + + // Waiting for AccessMode. + EXPECT_FALSE(external_printers_->IsPolicySet()); + + external_printers_->SetAccessMode(ExternalPrinters::AccessMode::ALL_ACCESS); + EXPECT_TRUE(external_printers_->IsPolicySet()); + + external_printers_->SetAccessMode( + ExternalPrinters::AccessMode::WHITELIST_ONLY); + EXPECT_FALSE(external_printers_->IsPolicySet()); // Waiting for Whitelist. + + std::vector<std::string> whitelist = {"First", "Third"}; + external_printers_->SetWhitelist(whitelist); + EXPECT_TRUE(external_printers_->IsPolicySet()); // Everything is set. + + external_printers_->SetAccessMode( + ExternalPrinters::AccessMode::BLACKLIST_ONLY); + EXPECT_FALSE(external_printers_->IsPolicySet()); // Blacklist needed now. + + std::vector<std::string> blacklist = {"Second"}; + external_printers_->SetBlacklist(blacklist); + EXPECT_TRUE( + external_printers_->IsPolicySet()); // Blacklist was set. Ready again. +} + +// Verify printer list after all attributes have been set. +TEST_F(ExternalPrintersTest, AllPoliciesResultInPrinters) { + auto data = base::MakeUnique<std::string>(kBulkPolicyContentsJson); + external_printers_->SetAccessMode(ExternalPrinters::AccessMode::ALL_ACCESS); + external_printers_->ClearData(); + external_printers_->SetData(std::move(data)); + + EXPECT_TRUE(external_printers_->IsPolicySet()); + const std::vector<Printer>& printers = external_printers_->GetPrinters(); + EXPECT_EQ(kNumPrinters, printers.size()); + EXPECT_EQ("First", printers[0].id()); + EXPECT_EQ("Second", printers[1].id()); + EXPECT_EQ("Third", printers[2].id()); +} + +// The external policy was cleared, results should be invalidated. +TEST_F(ExternalPrintersTest, PolicyClearedNowUnset) { + auto data = base::MakeUnique<std::string>(kBulkPolicyContentsJson); + external_printers_->SetAccessMode(ExternalPrinters::AccessMode::ALL_ACCESS); + external_printers_->ClearData(); + external_printers_->SetData(std::move(data)); + + ASSERT_TRUE(external_printers_->IsPolicySet()); + + external_printers_->ClearData(); + EXPECT_FALSE(external_printers_->IsPolicySet()); + EXPECT_TRUE(external_printers_->GetPrinters().empty()); +} + +// Verify that the blacklist policy is applied correctly. Printers in the +// blacklist policy should not be available. Printers not in the blackslist +// should be available. +TEST_F(ExternalPrintersTest, BlacklistPolicySet) { + auto data = base::MakeUnique<std::string>(kBulkPolicyContentsJson); + external_printers_->ClearData(); + external_printers_->SetData(std::move(data)); + external_printers_->SetAccessMode(ExternalPrinters::BLACKLIST_ONLY); + EXPECT_FALSE(external_printers_->IsPolicySet()); + external_printers_->SetBlacklist({"Second", "Third"}); + EXPECT_TRUE(external_printers_->IsPolicySet()); + + auto printers = external_printers_->GetPrinters(); + ASSERT_EQ(1U, printers.size()); + EXPECT_EQ(printers[0].id(), "First"); +} + +// Verify that the whitelist policy is correctly applied. Only printers +// available in the whitelist are available. +TEST_F(ExternalPrintersTest, WhitelistPolicySet) { + auto data = base::MakeUnique<std::string>(kBulkPolicyContentsJson); + external_printers_->ClearData(); + external_printers_->SetData(std::move(data)); + external_printers_->SetAccessMode(ExternalPrinters::WHITELIST_ONLY); + EXPECT_FALSE(external_printers_->IsPolicySet()); + external_printers_->SetWhitelist({"First"}); + EXPECT_TRUE(external_printers_->IsPolicySet()); + + auto printers = external_printers_->GetPrinters(); + ASSERT_EQ(1U, printers.size()); + EXPECT_EQ(printers[0].id(), "First"); +} + +} // namespace +} // namespace chromeos
diff --git a/chrome/browser/extensions/api/feedback_private/feedback_browsertest.cc b/chrome/browser/extensions/api/feedback_private/feedback_browsertest.cc index eb9cb6e..46690d85 100644 --- a/chrome/browser/extensions/api/feedback_private/feedback_browsertest.cc +++ b/chrome/browser/extensions/api/feedback_private/feedback_browsertest.cc
@@ -100,7 +100,14 @@ VerifyFeedbackAppLaunch(); } -IN_PROC_BROWSER_TEST_F(FeedbackTest, ShowLoginFeedback) { +// Disabled for ASan due to flakiness on Mac ASan 64 Tests (1). +// See crbug.com/757243. +#if defined(ADDRESS_SANITIZER) +#define MAYBE_ShowLoginFeedback DISABLED_ShowLoginFeedback +#else +#define MAYBE_ShowLoginFeedback ShowLoginFeedback +#endif +IN_PROC_BROWSER_TEST_F(FeedbackTest, MAYBE_ShowLoginFeedback) { WaitForExtensionViewsToLoad(); ASSERT_TRUE(IsFeedbackAppAvailable()); @@ -122,9 +129,16 @@ EXPECT_TRUE(bool_result); } +// Disabled for ASan due to flakiness on Mac ASan 64 Tests (1). +// See crbug.com/757243. +#if defined(ADDRESS_SANITIZER) +#define MAYBE_AnonymousUser DISABLED_AnonymousUser +#else +#define MAYBE_AnonymousUser AnonymousUser +#endif // Tests that there's an option in the email drop down box with a value // 'anonymous_user'. -IN_PROC_BROWSER_TEST_F(FeedbackTest, AnonymousUser) { +IN_PROC_BROWSER_TEST_F(FeedbackTest, MAYBE_AnonymousUser) { WaitForExtensionViewsToLoad(); ASSERT_TRUE(IsFeedbackAppAvailable()); @@ -153,9 +167,16 @@ EXPECT_TRUE(bool_result); } +// Disabled for ASan due to flakiness on Mac ASan 64 Tests (1). +// See crbug.com/757243. +#if defined(ADDRESS_SANITIZER) +#define MAYBE_ExtraDiagnostics DISABLED_ExtraDiagnostics +#else +#define MAYBE_ExtraDiagnostics ExtraDiagnostics +#endif // Ensures that when extra diagnostics are provided with feedback, they are // injected properly in the system information. -IN_PROC_BROWSER_TEST_F(FeedbackTest, ExtraDiagnostics) { +IN_PROC_BROWSER_TEST_F(FeedbackTest, MAYBE_ExtraDiagnostics) { WaitForExtensionViewsToLoad(); ASSERT_TRUE(IsFeedbackAppAvailable());
diff --git a/chrome/browser/media/router/discovery/dial/dial_media_sink_service.h b/chrome/browser/media/router/discovery/dial/dial_media_sink_service.h index d303851..c96f8454 100644 --- a/chrome/browser/media/router/discovery/dial/dial_media_sink_service.h +++ b/chrome/browser/media/router/discovery/dial/dial_media_sink_service.h
@@ -50,20 +50,23 @@ // |dial_sink_added_cb_sequence|: The sequence |dial_sink_added_cb| is // invoked on, or nullptr if the callback is null. // Both callbacks may be invoked after |this| is destroyed. - void Start(const OnSinksDiscoveredCallback& sink_discovery_cb, - const OnDialSinkAddedCallback& dial_sink_added_cb, - const scoped_refptr<base::SequencedTaskRunner>& - dial_sink_added_cb_sequence); + // Marked virtual for tests. + virtual void Start(const OnSinksDiscoveredCallback& sink_discovery_cb, + const OnDialSinkAddedCallback& dial_sink_added_cb, + const scoped_refptr<base::SequencedTaskRunner>& + dial_sink_added_cb_sequence); // Forces the sink discovery callback to be invoked with the current list of // sinks. This method can only be called after |Start()|. - void ForceSinkDiscoveryCallback(); + // Marked virtual for tests. + virtual void ForceSinkDiscoveryCallback(); // Initiates discovery immediately in response to a user gesture // (i.e., opening the Media Router dialog). This method can only be called // after |Start()|. // TODO(imcheng): Rename to ManuallyInitiateDiscovery() or similar. - void OnUserGesture(); + // Marked virtual for tests. + virtual void OnUserGesture(); private: friend class DialMediaSinkServiceTest;
diff --git a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service.h b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service.h index 2c17e5bf..d768408 100644 --- a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service.h +++ b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service.h
@@ -53,16 +53,19 @@ // |sink_discovery_cb|: Callback to invoke when the list of discovered sinks // has been updated. The callback is invoked on the UI thread and may be // invoked after |this| is destroyed. - void Start(const OnSinksDiscoveredCallback& sinks_discovered_cb); + // Marked virtual for tests. + virtual void Start(const OnSinksDiscoveredCallback& sinks_discovered_cb); // Forces the sink discovery callback to be invoked with the current list of // sinks. - void ForceSinkDiscoveryCallback(); + // Marked virtual for tests. + virtual void ForceSinkDiscoveryCallback(); // Initiates discovery immediately in response to a user gesture // (i.e., opening the Media Router dialog). // TODO(imcheng): Rename to ManuallyInitiateDiscovery() or similar. - void OnUserGesture(); + // Marked virtual for tests. + virtual void OnUserGesture(); // Marked virtual for tests. virtual std::unique_ptr<CastMediaSinkServiceImpl> CreateImpl(
diff --git a/chrome/browser/media/router/media_router_feature.cc b/chrome/browser/media/router/media_router_feature.cc index 6ab6efdc..819252e 100644 --- a/chrome/browser/media/router/media_router_feature.cc +++ b/chrome/browser/media/router/media_router_feature.cc
@@ -20,8 +20,8 @@ #if !defined(OS_ANDROID) // Controls if browser side DIAL device discovery is enabled. -const base::Feature kEnableDialLocalDiscovery{ - "EnableDialLocalDiscovery", base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kEnableDialLocalDiscovery{"EnableDialLocalDiscovery", + base::FEATURE_ENABLED_BY_DEFAULT}; // Controls if browser side Cast device discovery is enabled. const base::Feature kEnableCastDiscovery{"EnableCastDiscovery",
diff --git a/chrome/browser/media/router/media_router_feature.h b/chrome/browser/media/router/media_router_feature.h index 744b128..45ac8a9 100644 --- a/chrome/browser/media/router/media_router_feature.h +++ b/chrome/browser/media/router/media_router_feature.h
@@ -18,6 +18,7 @@ #if !defined(OS_ANDROID) +extern const base::Feature kEnableDialLocalDiscovery; extern const base::Feature kEnableCastDiscovery; extern const base::Feature kEnableCastLocalMedia;
diff --git a/chrome/browser/media/router/mojo/media_route_controller.cc b/chrome/browser/media/router/mojo/media_route_controller.cc index cb3280a..a8acb3aa 100644 --- a/chrome/browser/media/router/mojo/media_route_controller.cc +++ b/chrome/browser/media/router/mojo/media_route_controller.cc
@@ -36,11 +36,12 @@ void MediaRouteController::Observer::OnControllerInvalidated() {} MediaRouteController::MediaRouteController(const MediaRoute::Id& route_id, - content::BrowserContext* context) + content::BrowserContext* context, + MediaRouter* router) : route_id_(route_id), request_manager_( EventPageRequestManagerFactory::GetApiForBrowserContext(context)), - media_router_(MediaRouterFactory::GetApiForBrowserContext(context)), + media_router_(router), binding_(this) { DCHECK(media_router_); DCHECK(request_manager_); @@ -167,8 +168,9 @@ HangoutsMediaRouteController::HangoutsMediaRouteController( const MediaRoute::Id& route_id, - content::BrowserContext* context) - : MediaRouteController(route_id, context) {} + content::BrowserContext* context, + MediaRouter* router) + : MediaRouteController(route_id, context, router) {} HangoutsMediaRouteController::~HangoutsMediaRouteController() {} @@ -217,8 +219,9 @@ MirroringMediaRouteController::MirroringMediaRouteController( const MediaRoute::Id& route_id, - content::BrowserContext* context) - : MediaRouteController(route_id, context), + content::BrowserContext* context, + MediaRouter* router) + : MediaRouteController(route_id, context, router), prefs_(Profile::FromBrowserContext(context)->GetPrefs()) { DCHECK(prefs_); media_remoting_enabled_ =
diff --git a/chrome/browser/media/router/mojo/media_route_controller.h b/chrome/browser/media/router/mojo/media_route_controller.h index eca6ebe..5027ba7 100644 --- a/chrome/browser/media/router/mojo/media_route_controller.h +++ b/chrome/browser/media/router/mojo/media_route_controller.h
@@ -97,7 +97,8 @@ // |mojo_media_controller_|. |media_router_| will be notified when the // MediaRouteController is destroyed via DetachRouteController(). MediaRouteController(const MediaRoute::Id& route_id, - content::BrowserContext* context); + content::BrowserContext* context, + MediaRouter* router); // Initializes the Mojo interfaces/bindings in this MediaRouteController. // This should only be called when the Mojo interfaces/bindings are not bound. @@ -203,7 +204,8 @@ static HangoutsMediaRouteController* From(MediaRouteController* controller); HangoutsMediaRouteController(const MediaRoute::Id& route_id, - content::BrowserContext* context); + content::BrowserContext* context, + MediaRouter* router); // MediaRouteController RouteControllerType GetType() const override; @@ -235,7 +237,8 @@ static MirroringMediaRouteController* From(MediaRouteController* controller); MirroringMediaRouteController(const MediaRoute::Id& route_id, - content::BrowserContext* context); + content::BrowserContext* context, + MediaRouter* router); // MediaRouteController RouteControllerType GetType() const override;
diff --git a/chrome/browser/media/router/mojo/media_route_controller_unittest.cc b/chrome/browser/media/router/mojo/media_route_controller_unittest.cc index 6b0d2a0..5b27ad9 100644 --- a/chrome/browser/media/router/mojo/media_route_controller_unittest.cc +++ b/chrome/browser/media/router/mojo/media_route_controller_unittest.cc
@@ -49,7 +49,8 @@ void TearDown() override { observer_.reset(); } virtual scoped_refptr<MediaRouteController> CreateMediaRouteController() { - return base::MakeRefCounted<MediaRouteController>(kRouteId, &profile_); + return base::MakeRefCounted<MediaRouteController>(kRouteId, &profile_, + &router_); } scoped_refptr<MediaRouteController> GetController() const { @@ -67,7 +68,7 @@ content::TestBrowserThreadBundle test_thread_bundle_; TestingProfile profile_; - MockMediaRouter* router_ = nullptr; + MockMediaRouter router_; MockEventPageRequestManager* request_manager_ = nullptr; MockMediaController mock_media_controller_; mojom::MediaStatusObserverPtr mojo_media_status_observer_; @@ -79,10 +80,6 @@ EventPageRequestManagerFactory::GetInstance()->SetTestingFactoryAndUse( &profile_, &MockEventPageRequestManager::Create)); request_manager_->set_mojo_connections_ready_for_test(true); - - router_ = static_cast<MockMediaRouter*>( - MediaRouterFactory::GetInstance()->SetTestingFactoryAndUse( - &profile_, &MockMediaRouter::Create)); } DISALLOW_COPY_AND_ASSIGN(MediaRouteControllerTest); @@ -99,8 +96,8 @@ } scoped_refptr<MediaRouteController> CreateMediaRouteController() override { - return base::MakeRefCounted<HangoutsMediaRouteController>(kRouteId, - &profile_); + return base::MakeRefCounted<HangoutsMediaRouteController>( + kRouteId, &profile_, &router_); } }; @@ -109,8 +106,8 @@ ~MirroringMediaRouteControllerTest() override {} scoped_refptr<MediaRouteController> CreateMediaRouteController() override { - return base::MakeRefCounted<MirroringMediaRouteController>(kRouteId, - &profile_); + return base::MakeRefCounted<MirroringMediaRouteController>( + kRouteId, &profile_, &router_); } }; @@ -207,14 +204,14 @@ // Get rid of |observer_| and its reference to the controller. observer_.reset(); - EXPECT_CALL(*router_, DetachRouteController(kRouteId, controller)).Times(0); + EXPECT_CALL(router_, DetachRouteController(kRouteId, controller)).Times(0); observer1.reset(); // DetachRouteController() should be called when the controller no longer // has any observers. - EXPECT_CALL(*router_, DetachRouteController(kRouteId, controller)).Times(1); + EXPECT_CALL(router_, DetachRouteController(kRouteId, controller)).Times(1); observer2.reset(); - EXPECT_TRUE(Mock::VerifyAndClearExpectations(router_)); + EXPECT_TRUE(Mock::VerifyAndClearExpectations(&router_)); } TEST_F(HangoutsMediaRouteControllerTest, HangoutsCommands) {
diff --git a/chrome/browser/media/router/mojo/media_router_desktop.cc b/chrome/browser/media/router/mojo/media_router_desktop.cc index e435276..d12b465d 100644 --- a/chrome/browser/media/router/mojo/media_router_desktop.cc +++ b/chrome/browser/media/router/mojo/media_router_desktop.cc
@@ -66,20 +66,27 @@ return MediaRouterMojoImpl::GetProviderIdForPresentation(presentation_id); } -MediaRouterDesktop::MediaRouterDesktop(content::BrowserContext* context, - FirewallCheck check_firewall) - : MediaRouterMojoImpl(context), - weak_factory_(this) { +MediaRouterDesktop::MediaRouterDesktop(content::BrowserContext* context) + : MediaRouterMojoImpl(context), weak_factory_(this) { InitializeMediaRouteProviders(); #if defined(OS_WIN) - if (check_firewall == FirewallCheck::RUN) { - CanFirewallUseLocalPorts( - base::BindOnce(&MediaRouterDesktop::OnFirewallCheckComplete, - weak_factory_.GetWeakPtr())); - } + CanFirewallUseLocalPorts( + base::BindOnce(&MediaRouterDesktop::OnFirewallCheckComplete, + weak_factory_.GetWeakPtr())); #endif } +MediaRouterDesktop::MediaRouterDesktop( + content::BrowserContext* context, + std::unique_ptr<DialMediaSinkService> dial_media_sink_service, + std::unique_ptr<CastMediaSinkService> cast_media_sink_service) + : MediaRouterMojoImpl(context), + dial_media_sink_service_(std::move(dial_media_sink_service)), + cast_media_sink_service_(std::move(cast_media_sink_service)), + weak_factory_(this) { + InitializeMediaRouteProviders(); +} + void MediaRouterDesktop::RegisterMediaRouteProvider( MediaRouteProviderId provider_id, mojom::MediaRouteProviderPtr media_route_provider_ptr,
diff --git a/chrome/browser/media/router/mojo/media_router_desktop.h b/chrome/browser/media/router/mojo/media_router_desktop.h index 1d6ea5a..a673273 100644 --- a/chrome/browser/media/router/mojo/media_router_desktop.h +++ b/chrome/browser/media/router/mojo/media_router_desktop.h
@@ -57,16 +57,16 @@ friend class MediaRouterFactory; FRIEND_TEST_ALL_PREFIXES(MediaRouterDesktopTest, TestProvideSinks); - enum class FirewallCheck { - // Skips the firewall check for the benefit of unit tests so they do not - // have to depend on the system's firewall configuration. - SKIP_FOR_TESTING, - // Perform the firewall check (default). - RUN, - }; + // This constructor performs a firewall check on Windows and is not suitable + // for use in unit tests; instead use the constructor below. + explicit MediaRouterDesktop(content::BrowserContext* context); - MediaRouterDesktop(content::BrowserContext* context, - FirewallCheck check_firewall = FirewallCheck::RUN); + // Used by tests only. This constructor skips the firewall check so unit tests + // do not have to depend on the system's firewall configuration. + MediaRouterDesktop( + content::BrowserContext* context, + std::unique_ptr<DialMediaSinkService> dial_media_sink_service, + std::unique_ptr<CastMediaSinkService> cast_media_sink_service); // mojom::MediaRouter implementation. void RegisterMediaRouteProvider(
diff --git a/chrome/browser/media/router/mojo/media_router_desktop_unittest.cc b/chrome/browser/media/router/mojo/media_router_desktop_unittest.cc index 3476acc..1e347d7 100644 --- a/chrome/browser/media/router/mojo/media_router_desktop_unittest.cc +++ b/chrome/browser/media/router/mojo/media_router_desktop_unittest.cc
@@ -12,10 +12,14 @@ #include "chrome/browser/media/router/mojo/media_router_desktop.h" #include "base/run_loop.h" +#include "base/test/scoped_feature_list.h" #include "build/build_config.h" +#include "chrome/browser/media/router/discovery/dial/dial_media_sink_service.h" +#include "chrome/browser/media/router/discovery/mdns/cast_media_sink_service.h" #include "chrome/browser/media/router/event_page_request_manager.h" #include "chrome/browser/media/router/event_page_request_manager_factory.h" #include "chrome/browser/media/router/media_router_factory.h" +#include "chrome/browser/media/router/media_router_feature.h" #include "chrome/browser/media/router/mojo/media_router_mojo_test.h" #include "chrome/common/media_router/media_source_helper.h" #include "testing/gmock/include/gmock/gmock.h" @@ -45,6 +49,31 @@ final {} }; +class MockDialMediaSinkService : public DialMediaSinkService { + public: + explicit MockDialMediaSinkService(content::BrowserContext* context) + : DialMediaSinkService(context) {} + ~MockDialMediaSinkService() override {} + + MOCK_METHOD3(Start, + void(const OnSinksDiscoveredCallback&, + const OnDialSinkAddedCallback&, + const scoped_refptr<base::SequencedTaskRunner>&)); + MOCK_METHOD0(ForceSinkDiscoveryCallback, void()); + MOCK_METHOD0(OnUserGesture, void()); +}; + +class MockCastMediaSinkService : public CastMediaSinkService { + public: + explicit MockCastMediaSinkService(content::BrowserContext* context) + : CastMediaSinkService(context) {} + ~MockCastMediaSinkService() override {} + + MOCK_METHOD1(Start, void(const OnSinksDiscoveredCallback&)); + MOCK_METHOD0(ForceSinkDiscoveryCallback, void()); + MOCK_METHOD0(OnUserGesture, void()); +}; + } // namespace class MediaRouterDesktopTest : public MediaRouterMojoTest { @@ -53,46 +82,76 @@ ~MediaRouterDesktopTest() override {} protected: - MediaRouterMojoImpl* SetTestingFactoryAndUse() override { - return static_cast<MediaRouterMojoImpl*>( - MediaRouterFactory::GetInstance()->SetTestingFactoryAndUse( - profile(), &CreateMediaRouter)); + void SetUp() override { + feature_list_.InitWithFeatures( + {kEnableDialLocalDiscovery, kEnableCastDiscovery}, {}); + MediaRouterMojoTest::SetUp(); + } + std::unique_ptr<MediaRouterMojoImpl> CreateMediaRouter() override { + auto dial_media_sink_service = + std::make_unique<MockDialMediaSinkService>(profile()); + dial_media_sink_service_ = dial_media_sink_service.get(); + EXPECT_CALL(*dial_media_sink_service_, ForceSinkDiscoveryCallback()); + + auto cast_media_sink_service = + std::make_unique<MockCastMediaSinkService>(profile()); + cast_media_sink_service_ = cast_media_sink_service.get(); + EXPECT_CALL(*cast_media_sink_service_, ForceSinkDiscoveryCallback()); + return std::unique_ptr<MediaRouterDesktop>( + new MediaRouterDesktop(profile(), std::move(dial_media_sink_service), + std::move(cast_media_sink_service))); + } + + MockDialMediaSinkService* dial_media_sink_service() const { + return dial_media_sink_service_; + } + + MockCastMediaSinkService* cast_media_sink_service() const { + return cast_media_sink_service_; } private: - static std::unique_ptr<KeyedService> CreateMediaRouter( - content::BrowserContext* context) { - return std::unique_ptr<KeyedService>(new MediaRouterDesktop( - context, MediaRouterDesktop::FirewallCheck::SKIP_FOR_TESTING)); - } + base::test::ScopedFeatureList feature_list_; + MockDialMediaSinkService* dial_media_sink_service_ = nullptr; + MockCastMediaSinkService* cast_media_sink_service_ = nullptr; + + DISALLOW_COPY_AND_ASSIGN(MediaRouterDesktopTest); }; #if defined(OS_WIN) TEST_F(MediaRouterDesktopTest, EnableMdnsAfterEachRegister) { EXPECT_CALL(mock_extension_provider_, EnableMdnsDiscovery()).Times(0); + EXPECT_CALL(*dial_media_sink_service(), ForceSinkDiscoveryCallback()); + EXPECT_CALL(*cast_media_sink_service(), ForceSinkDiscoveryCallback()); RegisterExtensionProvider(); base::RunLoop().RunUntilIdle(); EXPECT_CALL(mock_extension_provider_, UpdateMediaSinks(MediaSourceForDesktop().id())); EXPECT_CALL(mock_extension_provider_, EnableMdnsDiscovery()); + EXPECT_CALL(*dial_media_sink_service(), OnUserGesture()); + EXPECT_CALL(*cast_media_sink_service(), OnUserGesture()); router()->OnUserGesture(); base::RunLoop().RunUntilIdle(); // EnableMdnsDiscovery() is called on this RegisterExtensionProvider() because // we've already seen an mdns-enabling event. EXPECT_CALL(mock_extension_provider_, EnableMdnsDiscovery()); + EXPECT_CALL(*dial_media_sink_service(), ForceSinkDiscoveryCallback()); + EXPECT_CALL(*cast_media_sink_service(), ForceSinkDiscoveryCallback()); RegisterExtensionProvider(); base::RunLoop().RunUntilIdle(); } #endif -TEST_F(MediaRouterDesktopTest, UpdateMediaSinksOnUserGesture) { +TEST_F(MediaRouterDesktopTest, OnUserGesture) { #if defined(OS_WIN) EXPECT_CALL(mock_extension_provider_, EnableMdnsDiscovery()); #endif EXPECT_CALL(mock_extension_provider_, UpdateMediaSinks(MediaSourceForDesktop().id())); + EXPECT_CALL(*dial_media_sink_service(), OnUserGesture()); + EXPECT_CALL(*cast_media_sink_service(), OnUserGesture()); router()->OnUserGesture(); base::RunLoop().RunUntilIdle(); }
diff --git a/chrome/browser/media/router/mojo/media_router_mojo_impl.cc b/chrome/browser/media/router/mojo/media_router_mojo_impl.cc index 97279e8..bee5d359 100644 --- a/chrome/browser/media/router/mojo/media_router_mojo_impl.cc +++ b/chrome/browser/media/router/mojo/media_router_mojo_impl.cc
@@ -364,17 +364,18 @@ << __func__ << ": route does not support controller: " << route_id; return nullptr; case RouteControllerType::kGeneric: - route_controller = new MediaRouteController(route_id, context_); + route_controller = new MediaRouteController(route_id, context_, this); break; case RouteControllerType::kHangouts: - route_controller = new HangoutsMediaRouteController(route_id, context_); + route_controller = + new HangoutsMediaRouteController(route_id, context_, this); break; case RouteControllerType::kMirroring: // TODO(imcheng): Remove this check when remoting is default enabled. route_controller = base::FeatureList::IsEnabled(features::kMediaRemoting) - ? new MirroringMediaRouteController(route_id, context_) - : new MediaRouteController(route_id, context_); + ? new MirroringMediaRouteController(route_id, context_, this) + : new MediaRouteController(route_id, context_, this); break; } DCHECK(route_controller);
diff --git a/chrome/browser/media/router/mojo/media_router_mojo_impl_unittest.cc b/chrome/browser/media/router/mojo/media_router_mojo_impl_unittest.cc index d1714799..44a057e 100644 --- a/chrome/browser/media/router/mojo/media_router_mojo_impl_unittest.cc +++ b/chrome/browser/media/router/mojo/media_router_mojo_impl_unittest.cc
@@ -143,18 +143,12 @@ expected_count); } - MediaRouterMojoImpl* SetTestingFactoryAndUse() override { - return static_cast<MediaRouterMojoImpl*>( - MediaRouterFactory::GetInstance()->SetTestingFactoryAndUse( - profile(), &CreateMediaRouter)); + std::unique_ptr<MediaRouterMojoImpl> CreateMediaRouter() override { + return std::unique_ptr<MediaRouterMojoImpl>( + new MediaRouterMojoImpl(profile())); } private: - static std::unique_ptr<KeyedService> CreateMediaRouter( - content::BrowserContext* context) { - return std::unique_ptr<KeyedService>(new MediaRouterMojoImpl(context)); - } - base::HistogramTester histogram_tester_; };
diff --git a/chrome/browser/media/router/mojo/media_router_mojo_test.cc b/chrome/browser/media/router/mojo/media_router_mojo_test.cc index 3ebd8570..5cabbf9 100644 --- a/chrome/browser/media/router/mojo/media_router_mojo_test.cc +++ b/chrome/browser/media/router/mojo/media_router_mojo_test.cc
@@ -151,8 +151,9 @@ MockMediaRouteController::MockMediaRouteController( const MediaRoute::Id& route_id, - content::BrowserContext* context) - : MediaRouteController(route_id, context) {} + content::BrowserContext* context, + MediaRouter* router) + : MediaRouteController(route_id, context, router) {} MockMediaRouteController::~MockMediaRouteController() {} @@ -187,7 +188,7 @@ } void MediaRouterMojoTest::SetUp() { - media_router_ = SetTestingFactoryAndUse(); + media_router_ = CreateMediaRouter(); media_router_->set_instance_id_for_test(kInstanceId); RegisterExtensionProvider(); media_router_->Initialize();
diff --git a/chrome/browser/media/router/mojo/media_router_mojo_test.h b/chrome/browser/media/router/mojo/media_router_mojo_test.h index c7fb3e8..b5ae968 100644 --- a/chrome/browser/media/router/mojo/media_router_mojo_test.h +++ b/chrome/browser/media/router/mojo/media_router_mojo_test.h
@@ -244,7 +244,8 @@ class MockMediaRouteController : public MediaRouteController { public: MockMediaRouteController(const MediaRoute::Id& route_id, - content::BrowserContext* context); + content::BrowserContext* context, + MediaRouter* router); MOCK_METHOD0(Play, void()); MOCK_METHOD0(Pause, void()); MOCK_METHOD1(Seek, void(base::TimeDelta time)); @@ -277,9 +278,8 @@ void SetUp() override; void TearDown() override; - // Set the MediaRouter instance to be used by the MediaRouterFactory and - // return it. - virtual MediaRouterMojoImpl* SetTestingFactoryAndUse() = 0; + // Creates a MediaRouterMojoImpl instance to be used for this test. + virtual std::unique_ptr<MediaRouterMojoImpl> CreateMediaRouter() = 0; // Notify media router that the provider provides a route or a sink. // Need to be called after the provider is registered. @@ -308,7 +308,7 @@ const std::string& extension_id() const { return extension_->id(); } - MediaRouterMojoImpl* router() const { return media_router_; } + MediaRouterMojoImpl* router() const { return media_router_.get(); } Profile* profile() { return &profile_; } @@ -326,7 +326,7 @@ content::TestBrowserThreadBundle test_thread_bundle_; scoped_refptr<extensions::Extension> extension_; TestingProfile profile_; - MediaRouterMojoImpl* media_router_ = nullptr; + std::unique_ptr<MediaRouterMojoImpl> media_router_; mojo::BindingSet<mojom::MediaRouteProvider> provider_bindings_; std::unique_ptr<MediaRoutesObserver> routes_observer_; std::unique_ptr<MockMediaSinksObserver> sinks_observer_;
diff --git a/chrome/browser/metrics/tab_stats_tracker.cc b/chrome/browser/metrics/tab_stats_tracker.cc index ae58d27..77c50512 100644 --- a/chrome/browser/metrics/tab_stats_tracker.cc +++ b/chrome/browser/metrics/tab_stats_tracker.cc
@@ -158,10 +158,8 @@ size_t tab_count) { // Don't report the number of tabs on resume if Chrome is running in // background with no visible window. - if (g_browser_process && g_browser_process->background_mode_manager() - ->IsBackgroundWithoutWindows()) { + if (IsChromeBackgroundedWithoutWindows()) return; - } UMA_HISTOGRAM_COUNTS_10000(kNumberOfTabsOnResumeHistogramName, tab_count); } @@ -180,4 +178,13 @@ tab_stats.window_count_max); } +bool TabStatsTracker::UmaStatsReportingDelegate:: + IsChromeBackgroundedWithoutWindows() { + if (g_browser_process && g_browser_process->background_mode_manager() + ->IsBackgroundWithoutWindows()) { + return true; + } + return false; +} + } // namespace metrics
diff --git a/chrome/browser/metrics/tab_stats_tracker.h b/chrome/browser/metrics/tab_stats_tracker.h index 3b9cbe85..8e3ed6b 100644 --- a/chrome/browser/metrics/tab_stats_tracker.h +++ b/chrome/browser/metrics/tab_stats_tracker.h
@@ -85,6 +85,12 @@ return reporting_delegate_.get(); } + // Reset the |reporting_delegate_| object to |reporting_delegate|, for testing + // purposes. + void reset_reporting_delegate(UmaStatsReportingDelegate* reporting_delegate) { + reporting_delegate_.reset(reporting_delegate); + } + // Reset the DailyEvent object to |daily_event|, for testing purposes. void reset_daily_event(DailyEvent* daily_event) { daily_event_.reset(daily_event); @@ -148,7 +154,7 @@ static const char kMaxWindowsInADayHistogramName[]; UmaStatsReportingDelegate() {} - ~UmaStatsReportingDelegate() {} + virtual ~UmaStatsReportingDelegate() {} // Called at resume from sleep/hibernate. void ReportTabCountOnResume(size_t tab_count); @@ -156,6 +162,11 @@ // Called once per day to report the metrics. void ReportDailyMetrics(const TabStatsDataStore::TabsStats& tab_stats); + protected: + // Checks if Chrome is running in background with no visible windows, virtual + // for unittesting. + virtual bool IsChromeBackgroundedWithoutWindows(); + private: DISALLOW_COPY_AND_ASSIGN(UmaStatsReportingDelegate); };
diff --git a/chrome/browser/metrics/tab_stats_tracker_browsertest.cc b/chrome/browser/metrics/tab_stats_tracker_browsertest.cc new file mode 100644 index 0000000..b4ded2a --- /dev/null +++ b/chrome/browser/metrics/tab_stats_tracker_browsertest.cc
@@ -0,0 +1,96 @@ +// 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 "chrome/browser/metrics/tab_stats_tracker.h" + +#include "chrome/browser/profiles/profile_manager.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/test/base/in_process_browser_test.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace metrics { + +namespace { + +using TabsStats = TabStatsDataStore::TabsStats; + +class TabStatsTrackerBrowserTest : public InProcessBrowserTest { + public: + TabStatsTrackerBrowserTest() : tab_stats_tracker_(nullptr) {} + + void SetUpOnMainThread() override { + tab_stats_tracker_ = TabStatsTracker::GetInstance(); + ASSERT_TRUE(tab_stats_tracker_ != nullptr); + } + + protected: + TabStatsTracker* tab_stats_tracker_; + + DISALLOW_COPY_AND_ASSIGN(TabStatsTrackerBrowserTest); +}; + +void EnsureTabStatsMatchExpectations(const TabsStats& expected, + const TabsStats& actual) { + EXPECT_EQ(expected.total_tab_count, actual.total_tab_count); + EXPECT_EQ(expected.total_tab_count_max, actual.total_tab_count_max); + EXPECT_EQ(expected.max_tab_per_window, actual.max_tab_per_window); + EXPECT_EQ(expected.window_count, actual.window_count); + EXPECT_EQ(expected.window_count_max, actual.window_count_max); +} + +} // namespace + +IN_PROC_BROWSER_TEST_F(TabStatsTrackerBrowserTest, + TabsAndWindowsAreCountedAccurately) { + // Assert that the |TabStatsTracker| instance is initialized during the + // creation of the main browser. + ASSERT_NE(static_cast<TabStatsTracker*>(nullptr), tab_stats_tracker_); + + TabsStats expected_stats = {}; + + // There should be only one window with one tab at startup. + expected_stats.total_tab_count = 1; + expected_stats.total_tab_count_max = 1; + expected_stats.max_tab_per_window = 1; + expected_stats.window_count = 1; + expected_stats.window_count_max = 1; + + EnsureTabStatsMatchExpectations(expected_stats, + tab_stats_tracker_->tab_stats()); + + // Add a tab and make sure that the counters get updated. + AddTabAtIndex(1, GURL("about:blank"), ui::PAGE_TRANSITION_TYPED); + ++expected_stats.total_tab_count; + ++expected_stats.total_tab_count_max; + ++expected_stats.max_tab_per_window; + EnsureTabStatsMatchExpectations(expected_stats, + tab_stats_tracker_->tab_stats()); + + browser()->tab_strip_model()->CloseWebContentsAt(1, 0); + --expected_stats.total_tab_count; + EnsureTabStatsMatchExpectations(expected_stats, + tab_stats_tracker_->tab_stats()); + + Browser* browser = CreateBrowser(ProfileManager::GetActiveUserProfile()); + ++expected_stats.total_tab_count; + ++expected_stats.window_count; + ++expected_stats.window_count_max; + EnsureTabStatsMatchExpectations(expected_stats, + tab_stats_tracker_->tab_stats()); + + AddTabAtIndexToBrowser(browser, 1, GURL("about:blank"), + ui::PAGE_TRANSITION_TYPED, true); + ++expected_stats.total_tab_count; + ++expected_stats.total_tab_count_max; + EnsureTabStatsMatchExpectations(expected_stats, + tab_stats_tracker_->tab_stats()); + + CloseBrowserSynchronously(browser); + expected_stats.total_tab_count = 1; + expected_stats.window_count = 1; + EnsureTabStatsMatchExpectations(expected_stats, + tab_stats_tracker_->tab_stats()); +} + +} // namespace metrics
diff --git a/chrome/browser/metrics/tab_stats_tracker_unittests.cc b/chrome/browser/metrics/tab_stats_tracker_unittests.cc index 9b600a70..c877dcf 100644 --- a/chrome/browser/metrics/tab_stats_tracker_unittests.cc +++ b/chrome/browser/metrics/tab_stats_tracker_unittests.cc
@@ -7,12 +7,8 @@ #include "base/test/histogram_tester.h" #include "base/test/power_monitor_test_base.h" #include "base/test/scoped_task_environment.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/profiles/profile_manager.h" -#include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/common/pref_names.h" -#include "chrome/test/base/in_process_browser_test.h" #include "components/prefs/pref_registry_simple.h" #include "components/prefs/testing_pref_service.h" #include "testing/gtest/include/gtest/gtest.h" @@ -23,32 +19,11 @@ using TabsStats = TabStatsDataStore::TabsStats; -class TabStatsTrackerBrowserTest : public InProcessBrowserTest { - public: - TabStatsTrackerBrowserTest() : tab_stats_tracker_(nullptr) {} - - void SetUpOnMainThread() override { - tab_stats_tracker_ = TabStatsTracker::GetInstance(); - ASSERT_TRUE(tab_stats_tracker_ != nullptr); - } - - protected: - TabStatsTracker* tab_stats_tracker_; - - DISALLOW_COPY_AND_ASSIGN(TabStatsTrackerBrowserTest); -}; - class TestTabStatsTracker : public TabStatsTracker { public: using UmaStatsReportingDelegate = TabStatsTracker::UmaStatsReportingDelegate; - explicit TestTabStatsTracker(PrefService* pref_service) - : TabStatsTracker(pref_service), pref_service_(pref_service) { - // Stop the timer to ensure that the stats don't get reported (and reset) - // while running the tests. - EXPECT_TRUE(timer()->IsRunning()); - timer()->Stop(); - } + explicit TestTabStatsTracker(PrefService* pref_service); ~TestTabStatsTracker() override {} // Helper functions to update the number of tabs/windows. @@ -106,6 +81,20 @@ DISALLOW_COPY_AND_ASSIGN(TestTabStatsTracker); }; +class TestUmaStatsReportingDelegate + : public TestTabStatsTracker::UmaStatsReportingDelegate { + public: + TestUmaStatsReportingDelegate() {} + + protected: + // Skip the check that ensures that there's at least one visible window as + // there's no window in the context of these tests. + bool IsChromeBackgroundedWithoutWindows() override { return false; } + + private: + DISALLOW_COPY_AND_ASSIGN(TestUmaStatsReportingDelegate); +}; + class TabStatsTrackerTest : public testing::Test { public: using UmaStatsReportingDelegate = @@ -144,74 +133,23 @@ DISALLOW_COPY_AND_ASSIGN(TabStatsTrackerTest); }; +TestTabStatsTracker::TestTabStatsTracker(PrefService* pref_service) + : TabStatsTracker(pref_service), pref_service_(pref_service) { + // Stop the timer to ensure that the stats don't get reported (and reset) + // while running the tests. + EXPECT_TRUE(timer()->IsRunning()); + timer()->Stop(); + + reset_reporting_delegate(new TestUmaStatsReportingDelegate()); +} + // Comparator for base::Bucket values. bool CompareHistogramBucket(const base::Bucket& l, const base::Bucket& r) { return l.min < r.min; } -void EnsureTabStatsMatchExpectations(const TabsStats& expected, - const TabsStats& actual) { - EXPECT_EQ(expected.total_tab_count, actual.total_tab_count); - EXPECT_EQ(expected.total_tab_count_max, actual.total_tab_count_max); - EXPECT_EQ(expected.max_tab_per_window, actual.max_tab_per_window); - EXPECT_EQ(expected.window_count, actual.window_count); - EXPECT_EQ(expected.window_count_max, actual.window_count_max); -} - } // namespace -IN_PROC_BROWSER_TEST_F(TabStatsTrackerBrowserTest, - TabsAndWindowsAreCountedAccurately) { - // Assert that the |TabStatsTracker| instance is initialized during the - // creation of the main browser. - ASSERT_NE(static_cast<TabStatsTracker*>(nullptr), tab_stats_tracker_); - - TabsStats expected_stats = {}; - - // There should be only one window with one tab at startup. - expected_stats.total_tab_count = 1; - expected_stats.total_tab_count_max = 1; - expected_stats.max_tab_per_window = 1; - expected_stats.window_count = 1; - expected_stats.window_count_max = 1; - - EnsureTabStatsMatchExpectations(expected_stats, - tab_stats_tracker_->tab_stats()); - - // Add a tab and make sure that the counters get updated. - AddTabAtIndex(1, GURL("about:blank"), ui::PAGE_TRANSITION_TYPED); - ++expected_stats.total_tab_count; - ++expected_stats.total_tab_count_max; - ++expected_stats.max_tab_per_window; - EnsureTabStatsMatchExpectations(expected_stats, - tab_stats_tracker_->tab_stats()); - - browser()->tab_strip_model()->CloseWebContentsAt(1, 0); - --expected_stats.total_tab_count; - EnsureTabStatsMatchExpectations(expected_stats, - tab_stats_tracker_->tab_stats()); - - Browser* browser = CreateBrowser(ProfileManager::GetActiveUserProfile()); - ++expected_stats.total_tab_count; - ++expected_stats.window_count; - ++expected_stats.window_count_max; - EnsureTabStatsMatchExpectations(expected_stats, - tab_stats_tracker_->tab_stats()); - - AddTabAtIndexToBrowser(browser, 1, GURL("about:blank"), - ui::PAGE_TRANSITION_TYPED, true); - ++expected_stats.total_tab_count; - ++expected_stats.total_tab_count_max; - EnsureTabStatsMatchExpectations(expected_stats, - tab_stats_tracker_->tab_stats()); - - CloseBrowserSynchronously(browser); - expected_stats.total_tab_count = 1; - expected_stats.window_count = 1; - EnsureTabStatsMatchExpectations(expected_stats, - tab_stats_tracker_->tab_stats()); -} - TEST_F(TabStatsTrackerTest, OnResume) { // Makes sure that there's no sample initially. histogram_tester_.ExpectTotalCount(
diff --git a/chrome/browser/printing/printer_manager_dialog.h b/chrome/browser/printing/printer_manager_dialog.h index 6a1df0c..cc99921 100644 --- a/chrome/browser/printing/printer_manager_dialog.h +++ b/chrome/browser/printing/printer_manager_dialog.h
@@ -6,10 +6,16 @@ #define CHROME_BROWSER_PRINTING_PRINTER_MANAGER_DIALOG_H_ #include "base/macros.h" +#include "printing/features/features.h" + +#if !BUILDFLAG(ENABLE_PRINTING) +#error "Printing must be enabled" +#endif namespace printing { -// An abstraction of a printer manager dialog. This is used for print preview. +// An abstraction of a printer manager dialog. This is used for the printing +// sub-section of Settings. // This includes the OS-dependent UI to manage the network and local printers. class PrinterManagerDialog { public:
diff --git a/chrome/browser/resources/print_preview/compiled_resources2.gyp b/chrome/browser/resources/print_preview/compiled_resources2.gyp index 854ca2d0..c1a9334e 100644 --- a/chrome/browser/resources/print_preview/compiled_resources2.gyp +++ b/chrome/browser/resources/print_preview/compiled_resources2.gyp
@@ -35,5 +35,14 @@ ], 'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'], }, + { + 'target_name': 'native_layer', + 'dependencies': [ + 'data/compiled_resources2.gyp:destination', + 'data/compiled_resources2.gyp:measurement_system', + '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:cr', + ], + 'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'], + }, ], }
diff --git a/chrome/browser/resources/print_preview/data/compiled_resources2.gyp b/chrome/browser/resources/print_preview/data/compiled_resources2.gyp index d69be6d..bf9b2ef 100644 --- a/chrome/browser/resources/print_preview/data/compiled_resources2.gyp +++ b/chrome/browser/resources/print_preview/data/compiled_resources2.gyp
@@ -32,6 +32,13 @@ 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], }, { + 'target_name': 'measurement_system', + 'dependencies': [ + '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:cr', + ], + 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], + }, + { 'target_name': 'printable_area', 'dependencies': [ 'size',
diff --git a/chrome/browser/resources/print_preview/native_layer.html b/chrome/browser/resources/print_preview/native_layer.html new file mode 100644 index 0000000..5e71fec --- /dev/null +++ b/chrome/browser/resources/print_preview/native_layer.html
@@ -0,0 +1,3 @@ +<link rel="import" href="chrome://resources/html/cr.html"> + +<script src="native_layer.js"></script>
diff --git a/chrome/browser/resources/print_preview/native_layer.js b/chrome/browser/resources/print_preview/native_layer.js index e797402..d2227130 100644 --- a/chrome/browser/resources/print_preview/native_layer.js +++ b/chrome/browser/resources/print_preview/native_layer.js
@@ -190,199 +190,31 @@ } /** - * @param {!print_preview.Destination} destination Destination to print to. - * @param {!print_preview.ticket_items.Color} color Color ticket item. - * @return {number} Native layer color model. - * @private - */ - getNativeColorModel_(destination, color) { - // For non-local printers native color model is ignored anyway. - const option = destination.isLocal ? color.getSelectedOption() : null; - const nativeColorModel = parseInt(option ? option.vendor_id : null, 10); - if (isNaN(nativeColorModel)) { - return color.getValue() ? NativeLayer.ColorMode_.COLOR : - NativeLayer.ColorMode_.GRAY; - } - return nativeColorModel; - } - - /** * Requests that a preview be generated. The following Web UI events may * be triggered in response: * 'print-preset-options', * 'page-count-ready', * 'page-layout-ready', * 'page-preview-ready' - * @param {!print_preview.Destination} destination Destination to print to. - * @param {!print_preview.PrintTicketStore} printTicketStore Used to get the - * state of the print ticket. - * @param {!print_preview.DocumentInfo} documentInfo Document data model. - * @param {boolean} generateDraft Tell the renderer to re-render. - * @param {number} requestId ID of the preview request. + * @param {string} printTicket JSON print ticket for the request. + * @param {number} pageCount Page count for the preview request, or -1 if + * unknown (first request). * @return {!Promise<number>} Promise that resolves with the unique ID of * the preview UI when the preview has been generated. */ - getPreview( - destination, printTicketStore, documentInfo, generateDraft, requestId) { - assert( - printTicketStore.isTicketValidForPreview(), - 'Trying to generate preview when ticket is not valid'); - - const ticket = { - 'pageRange': printTicketStore.pageRange.getDocumentPageRanges(), - 'mediaSize': printTicketStore.mediaSize.getValue(), - 'landscape': printTicketStore.landscape.getValue(), - 'color': this.getNativeColorModel_(destination, printTicketStore.color), - 'headerFooterEnabled': printTicketStore.headerFooter.getValue(), - 'marginsType': printTicketStore.marginsType.getValue(), - 'isFirstRequest': requestId == 0, - 'requestID': requestId, - 'previewModifiable': documentInfo.isModifiable, - 'generateDraftData': generateDraft, - 'fitToPageEnabled': printTicketStore.fitToPage.getValue(), - 'scaleFactor': printTicketStore.scaling.getValueAsNumber(), - // NOTE: Even though the following fields don't directly relate to the - // preview, they still need to be included. - // e.g. printing::PrintSettingsFromJobSettings() still checks for them. - 'collate': true, - 'copies': 1, - 'deviceName': destination.id, - 'dpiHorizontal': 'horizontal_dpi' in printTicketStore.dpi.getValue() ? - printTicketStore.dpi.getValue().horizontal_dpi : - 0, - 'dpiVertical': 'vertical_dpi' in printTicketStore.dpi.getValue() ? - printTicketStore.dpi.getValue().vertical_dpi : - 0, - 'duplex': printTicketStore.duplex.getValue() ? - NativeLayer.DuplexMode.LONG_EDGE : - NativeLayer.DuplexMode.SIMPLEX, - 'printToPDF': destination.id == - print_preview.Destination.GooglePromotedId.SAVE_AS_PDF, - 'printWithCloudPrint': !destination.isLocal, - 'printWithPrivet': destination.isPrivet, - 'printWithExtension': destination.isExtension, - 'rasterizePDF': false, - 'shouldPrintBackgrounds': printTicketStore.cssBackground.getValue(), - 'shouldPrintSelectionOnly': printTicketStore.selectionOnly.getValue() - }; - - // Set 'cloudPrintID' only if the destination is not local. - if (destination && !destination.isLocal) { - ticket['cloudPrintID'] = destination.id; - } - - if (printTicketStore.marginsType.isCapabilityAvailable() && - printTicketStore.marginsType.getValue() == - print_preview.ticket_items.MarginsTypeValue.CUSTOM) { - const customMargins = printTicketStore.customMargins.getValue(); - const orientationEnum = - print_preview.ticket_items.CustomMarginsOrientation; - ticket['marginsCustom'] = { - 'marginTop': customMargins.get(orientationEnum.TOP), - 'marginRight': customMargins.get(orientationEnum.RIGHT), - 'marginBottom': customMargins.get(orientationEnum.BOTTOM), - 'marginLeft': customMargins.get(orientationEnum.LEFT) - }; - } - - return cr.sendWithPromise( - 'getPreview', JSON.stringify(ticket), - requestId > 0 ? documentInfo.pageCount : -1); + getPreview(printTicket, pageCount) { + return cr.sendWithPromise('getPreview', printTicket, pageCount); } /** * Requests that the document be printed. - * @param {!print_preview.Destination} destination Destination to print to. - * @param {!print_preview.PrintTicketStore} printTicketStore Used to get the - * state of the print ticket. - * @param {!print_preview.DocumentInfo} documentInfo Document data model. - * @param {boolean=} opt_isOpenPdfInPreview Whether to open the PDF in the - * system's preview application. - * @param {boolean=} opt_showSystemDialog Whether to open system dialog for - * advanced settings. + * @param {string} printTicket The serialized print ticket for the print + * job. * @return {!Promise} Promise that will resolve when the print request is * finished or rejected. */ - print( - destination, printTicketStore, documentInfo, opt_isOpenPdfInPreview, - opt_showSystemDialog) { - assert( - printTicketStore.isTicketValid(), - 'Trying to print when ticket is not valid'); - - assert( - !opt_showSystemDialog || (cr.isWindows && destination.isLocal), - 'Implemented for Windows only'); - - // Note: update - // chrome/browser/ui/webui/print_preview/print_preview_handler_unittest.cc - // with any changes to ticket creation. - const ticket = { - 'mediaSize': printTicketStore.mediaSize.getValue(), - 'pageCount': printTicketStore.pageRange.getPageNumberSet().size, - 'landscape': printTicketStore.landscape.getValue(), - 'color': this.getNativeColorModel_(destination, printTicketStore.color), - 'headerFooterEnabled': false, // Only used in print preview - 'marginsType': printTicketStore.marginsType.getValue(), - 'duplex': printTicketStore.duplex.getValue() ? - NativeLayer.DuplexMode.LONG_EDGE : - NativeLayer.DuplexMode.SIMPLEX, - 'copies': printTicketStore.copies.getValueAsNumber(), - 'collate': printTicketStore.collate.getValue(), - 'shouldPrintBackgrounds': printTicketStore.cssBackground.getValue(), - 'shouldPrintSelectionOnly': false, // Only used in print preview - 'previewModifiable': documentInfo.isModifiable, - 'printToPDF': destination.id == - print_preview.Destination.GooglePromotedId.SAVE_AS_PDF, - 'printWithCloudPrint': !destination.isLocal, - 'printWithPrivet': destination.isPrivet, - 'printWithExtension': destination.isExtension, - 'rasterizePDF': printTicketStore.rasterize.getValue(), - 'scaleFactor': printTicketStore.scaling.getValueAsNumber(), - 'dpiHorizontal': 'horizontal_dpi' in printTicketStore.dpi.getValue() ? - printTicketStore.dpi.getValue().horizontal_dpi : - 0, - 'dpiVertical': 'vertical_dpi' in printTicketStore.dpi.getValue() ? - printTicketStore.dpi.getValue().vertical_dpi : - 0, - 'deviceName': destination.id, - 'fitToPageEnabled': printTicketStore.fitToPage.getValue(), - 'pageWidth': documentInfo.pageSize.width, - 'pageHeight': documentInfo.pageSize.height, - 'showSystemDialog': opt_showSystemDialog - }; - - if (!destination.isLocal) { - // We can't set cloudPrintID if the destination is "Print with Cloud - // Print" because the native system will try to print to Google Cloud - // Print with this ID instead of opening a Google Cloud Print dialog. - ticket['cloudPrintID'] = destination.id; - } - - if (printTicketStore.marginsType.isCapabilityAvailable() && - printTicketStore.marginsType.isValueEqual( - print_preview.ticket_items.MarginsTypeValue.CUSTOM)) { - const customMargins = printTicketStore.customMargins.getValue(); - const orientationEnum = - print_preview.ticket_items.CustomMarginsOrientation; - ticket['marginsCustom'] = { - 'marginTop': customMargins.get(orientationEnum.TOP), - 'marginRight': customMargins.get(orientationEnum.RIGHT), - 'marginBottom': customMargins.get(orientationEnum.BOTTOM), - 'marginLeft': customMargins.get(orientationEnum.LEFT) - }; - } - - if (destination.isPrivet || destination.isExtension) { - ticket['ticket'] = printTicketStore.createPrintTicket(destination); - ticket['capabilities'] = JSON.stringify(destination.capabilities); - } - - if (opt_isOpenPdfInPreview) { - ticket['OpenPDFInPreview'] = true; - } - - return cr.sendWithPromise('print', JSON.stringify(ticket)); + print(printTicket) { + return cr.sendWithPromise('print', printTicket); } /** Requests that the current pending print request be cancelled. */ @@ -392,7 +224,7 @@ /** * Sends the app state to be saved in the sticky settings. - * @param {string} appStateStr JSON string of the app state to persist + * @param {string} appStateStr JSON string of the app state to persist. */ saveAppState(appStateStr) { chrome.send('saveAppState', [appStateStr]); @@ -480,19 +312,6 @@ let currentInstance = null; /** - * Constant values matching printing::DuplexMode enum. - * @enum {number} - */ - NativeLayer.DuplexMode = {SIMPLEX: 0, LONG_EDGE: 1, UNKNOWN_DUPLEX_MODE: -1}; - - /** - * Enumeration of color modes used by Chromium. - * @enum {number} - * @private - */ - NativeLayer.ColorMode_ = {GRAY: 1, COLOR: 2}; - - /** * Version of the serialized state of the print preview. * @type {number} * @const
diff --git a/chrome/browser/resources/print_preview/new/compiled_resources2.gyp b/chrome/browser/resources/print_preview/new/compiled_resources2.gyp index d8e8670..6b6454e 100644 --- a/chrome/browser/resources/print_preview/new/compiled_resources2.gyp +++ b/chrome/browser/resources/print_preview/new/compiled_resources2.gyp
@@ -126,6 +126,7 @@ 'target_name': 'model', 'dependencies': [ '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:cr', + '../compiled_resources2.gyp:native_layer', '../data/compiled_resources2.gyp:destination', '../data/compiled_resources2.gyp:document_info', ],
diff --git a/chrome/browser/resources/print_preview/new/model.html b/chrome/browser/resources/print_preview/new/model.html index 3c40ff26..b983e9d 100644 --- a/chrome/browser/resources/print_preview/new/model.html +++ b/chrome/browser/resources/print_preview/new/model.html
@@ -1,5 +1,6 @@ <link rel="import" href="chrome://resources/html/polymer.html"> +<link rel="import" href="../native_layer.html"> <link rel="import" href="../data/destination.html"> <link rel="import" href="../data/document_info.html">
diff --git a/chrome/browser/resources/print_preview/new/model.js b/chrome/browser/resources/print_preview/new/model.js index ee102c1..ba95eeb 100644 --- a/chrome/browser/resources/print_preview/new/model.js +++ b/chrome/browser/resources/print_preview/new/model.js
@@ -273,6 +273,23 @@ */ MONOCHROME_TYPES_: ['STANDARD_MONOCHROME', 'CUSTOM_MONOCHROME'], + /** @private {!print_preview.NativeLayer} */ + nativeLayer_: print_preview.NativeLayer.getInstance(), + + /** @override */ + attached: function() { + this.nativeLayer_.getInitialSettings().then( + this.onInitialSettingsSet_.bind(this)); + }, + + /** + * @param {!print_preview.NativeInitialSettings} settings + * @private + */ + onInitialSettingsSet_: function(settings) { + // Do nothing here for now. + }, + /** * Updates the availability of the settings sections. * @private
diff --git a/chrome/browser/resources/print_preview/preview_generator.js b/chrome/browser/resources/print_preview/preview_generator.js index 93c0c2f0..c0ff0a1 100644 --- a/chrome/browser/resources/print_preview/preview_generator.js +++ b/chrome/browser/resources/print_preview/preview_generator.js
@@ -189,13 +189,87 @@ this.generateDraft_ = this.documentInfo_.isModifiable; return { id: this.inFlightRequestId_, - request: this.nativeLayer_.getPreview( - this.destinationStore_.selectedDestination, this.printTicketStore_, - this.documentInfo_, this.generateDraft_, this.inFlightRequestId_), + request: this.getPreview_(), }; } /** + * @return {!Promise} Promise that resolves when the preview has been + * generated. + * @private + */ + getPreview_() { + const printTicketStore = this.printTicketStore_; + const destination = assert(this.destinationStore_.selectedDestination); + + assert( + printTicketStore.isTicketValidForPreview(), + 'Trying to generate preview when ticket is not valid'); + + const ticket = { + pageRange: printTicketStore.pageRange.getDocumentPageRanges(), + mediaSize: printTicketStore.mediaSize.getValue(), + landscape: printTicketStore.landscape.getValue(), + color: PreviewGenerator.getNativeColorModel( + destination, printTicketStore.color), + headerFooterEnabled: printTicketStore.headerFooter.getValue(), + marginsType: printTicketStore.marginsType.getValue(), + isFirstRequest: this.inFlightRequestId_ == 0, + requestID: this.inFlightRequestId_, + previewModifiable: this.documentInfo_.isModifiable, + generateDraftData: this.generateDraft_, + fitToPageEnabled: printTicketStore.fitToPage.getValue(), + scaleFactor: printTicketStore.scaling.getValueAsNumber(), + // NOTE: Even though the following fields dont directly relate to the + // preview, they still need to be included. + // e.g. printing::PrintSettingsFromJobSettings() still checks for them. + collate: true, + copies: 1, + deviceName: destination.id, + dpiHorizontal: 'horizontal_dpi' in printTicketStore.dpi.getValue() ? + printTicketStore.dpi.getValue().horizontal_dpi : + 0, + dpiVertical: 'vertical_dpi' in printTicketStore.dpi.getValue() ? + printTicketStore.dpi.getValue().vertical_dpi : + 0, + duplex: printTicketStore.duplex.getValue() ? + PreviewGenerator.DuplexMode.LONG_EDGE : + PreviewGenerator.DuplexMode.SIMPLEX, + printToPDF: destination.id == + print_preview.Destination.GooglePromotedId.SAVE_AS_PDF, + printWithCloudPrint: !destination.isLocal, + printWithPrivet: destination.isPrivet, + printWithExtension: destination.isExtension, + rasterizePDF: false, + shouldPrintBackgrounds: printTicketStore.cssBackground.getValue(), + shouldPrintSelectionOnly: printTicketStore.selectionOnly.getValue() + }; + + // Set 'cloudPrintID' only if the destination is not local. + if (destination && !destination.isLocal) { + ticket.cloudPrintID = destination.id; + } + + if (printTicketStore.marginsType.isCapabilityAvailable() && + printTicketStore.marginsType.getValue() == + print_preview.ticket_items.MarginsTypeValue.CUSTOM) { + const customMargins = printTicketStore.customMargins.getValue(); + const orientationEnum = + print_preview.ticket_items.CustomMarginsOrientation; + ticket.marginsCustom = { + marginTop: customMargins.get(orientationEnum.TOP), + marginRight: customMargins.get(orientationEnum.RIGHT), + marginBottom: customMargins.get(orientationEnum.BOTTOM), + marginLeft: customMargins.get(orientationEnum.LEFT) + }; + } + + const pageCount = + this.inFlightRequestId_ > 0 ? this.documentInfo_.pageCount : -1; + return this.nativeLayer_.getPreview(JSON.stringify(ticket), pageCount); + } + + /** * Dispatches a PAGE_READY event to signal that a page preview is ready. * @param {number} previewIndex Index of the page with respect to the pages * shown in the preview. E.g an index of 0 is the first displayed page, @@ -409,6 +483,35 @@ FAIL: 'print_preview.PreviewGenerator.FAIL' }; + /** + * Enumeration of color modes used by Chromium. + * @enum {number} + */ + PreviewGenerator.ColorMode = {GRAY: 1, COLOR: 2}; + + /** + * @param {!print_preview.Destination} destination Destination to print to. + * @param {!print_preview.ticket_items.Color} color Color ticket item. + * @return {number} Native color model. + */ + PreviewGenerator.getNativeColorModel = function(destination, color) { + // For non-local printers native color model is ignored anyway. + const option = destination.isLocal ? color.getSelectedOption() : null; + const nativeColorModel = parseInt(option ? option.vendor_id : null, 10); + if (isNaN(nativeColorModel)) { + return color.getValue() ? PreviewGenerator.ColorMode.COLOR : + PreviewGenerator.ColorMode.GRAY; + } + return nativeColorModel; + }; + + /** + * Constant values matching printing::DuplexMode enum. + * @enum {number} + */ + PreviewGenerator + .DuplexMode = {SIMPLEX: 0, LONG_EDGE: 1, UNKNOWN_DUPLEX_MODE: -1}; + // Export return {PreviewGenerator: PreviewGenerator}; });
diff --git a/chrome/browser/resources/print_preview/print_preview.js b/chrome/browser/resources/print_preview/print_preview.js index d806202..e7ba6397 100644 --- a/chrome/browser/resources/print_preview/print_preview.js +++ b/chrome/browser/resources/print_preview/print_preview.js
@@ -559,10 +559,7 @@ .PRINT_WITH_SETTINGS_COLLAPSED); } const destination = assert(this.destinationStore_.selectedDestination); - const whenPrintDone = this.nativeLayer_.print( - destination, this.printTicketStore_, this.documentInfo_, - this.uiState_ == PrintPreviewUiState_.OPENING_PDF_PREVIEW, - this.showSystemDialogBeforeNextPrint_); + const whenPrintDone = this.sendPrintRequest_(destination); if (this.uiState_ == PrintPreviewUiState_.OPENING_PDF_PREVIEW || (destination.isLocal && !destination.isPrivet && !destination.isExtension && @@ -601,6 +598,96 @@ }, /** + * @param {!print_preview.Destination} destination Destination to print to. + * @return {!Promise} Promise that resolves when print request is resolved + * or rejected. + * @private + */ + sendPrintRequest_: function(destination) { + const printTicketStore = this.printTicketStore_; + const documentInfo = this.documentInfo_; + assert( + printTicketStore.isTicketValid(), + 'Trying to print when ticket is not valid'); + + assert( + !this.showSystemDialogBeforeNextPrint_ || + (cr.isWindows && destination.isLocal), + 'Implemented for Windows only'); + + // Note: update + // chrome/browser/ui/webui/print_preview/print_preview_handler_unittest.cc + // with any changes to ticket creation. + const ticket = { + mediaSize: printTicketStore.mediaSize.getValue(), + pageCount: printTicketStore.pageRange.getPageNumberSet().size, + landscape: printTicketStore.landscape.getValue(), + color: print_preview.PreviewGenerator.getNativeColorModel( + destination, printTicketStore.color), + headerFooterEnabled: false, // Only used in print preview + marginsType: printTicketStore.marginsType.getValue(), + duplex: printTicketStore.duplex.getValue() ? + print_preview.PreviewGenerator.DuplexMode.LONG_EDGE : + print_preview.PreviewGenerator.DuplexMode.SIMPLEX, + copies: printTicketStore.copies.getValueAsNumber(), + collate: printTicketStore.collate.getValue(), + shouldPrintBackgrounds: printTicketStore.cssBackground.getValue(), + shouldPrintSelectionOnly: false, // Only used in print preview + previewModifiable: documentInfo.isModifiable, + printToPDF: destination.id == + print_preview.Destination.GooglePromotedId.SAVE_AS_PDF, + printWithCloudPrint: !destination.isLocal, + printWithPrivet: destination.isPrivet, + printWithExtension: destination.isExtension, + rasterizePDF: printTicketStore.rasterize.getValue(), + scaleFactor: printTicketStore.scaling.getValueAsNumber(), + dpiHorizontal: 'horizontal_dpi' in printTicketStore.dpi.getValue() ? + printTicketStore.dpi.getValue().horizontal_dpi : + 0, + dpiVertical: 'vertical_dpi' in printTicketStore.dpi.getValue() ? + printTicketStore.dpi.getValue().vertical_dpi : + 0, + deviceName: destination.id, + fitToPageEnabled: printTicketStore.fitToPage.getValue(), + pageWidth: documentInfo.pageSize.width, + pageHeight: documentInfo.pageSize.height, + showSystemDialog: this.showSystemDialogBeforeNextPrint_ + }; + + if (!destination.isLocal) { + // We can't set cloudPrintID if the destination is "Print with Cloud + // Print" because the native system will try to print to Google Cloud + // Print with this ID instead of opening a Google Cloud Print dialog. + ticket.cloudPrintID = destination.id; + } + + if (printTicketStore.marginsType.isCapabilityAvailable() && + printTicketStore.marginsType.isValueEqual( + print_preview.ticket_items.MarginsTypeValue.CUSTOM)) { + const customMargins = printTicketStore.customMargins.getValue(); + const orientationEnum = + print_preview.ticket_items.CustomMarginsOrientation; + ticket.marginsCustom = { + marginTop: customMargins.get(orientationEnum.TOP), + marginRight: customMargins.get(orientationEnum.RIGHT), + marginBottom: customMargins.get(orientationEnum.BOTTOM), + marginLeft: customMargins.get(orientationEnum.LEFT) + }; + } + + if (destination.isPrivet || destination.isExtension) { + ticket.ticket = printTicketStore.createPrintTicket(destination); + ticket.capabilities = JSON.stringify(destination.capabilities); + } + + if (this.uiState_ == PrintPreviewUiState_.OPENING_PDF_PREVIEW) { + ticket.OpenPDFInPreview = true; + } + + return this.nativeLayer_.print(JSON.stringify(ticket)); + }, + + /** * Closes the print preview. * @param {boolean} isCancel Whether this was called due to the user * closing the dialog without printing.
diff --git a/chrome/browser/resources/print_preview/print_preview_resources.grd b/chrome/browser/resources/print_preview/print_preview_resources.grd index 9066a7e..42d1a5b5c 100644 --- a/chrome/browser/resources/print_preview/print_preview_resources.grd +++ b/chrome/browser/resources/print_preview/print_preview_resources.grd
@@ -29,6 +29,12 @@ <structure name="IDR_PRINT_PREVIEW_NEW_MODEL_JS" file="new/model.js" type="chrome_html" /> + <structure name="IDR_PRINT_PREVIEW_NATIVE_LAYER_HTML" + file="native_layer.html" + type="chrome_html" /> + <structure name="IDR_PRINT_PREVIEW_NATIVE_LAYER_JS" + file="native_layer.js" + type="chrome_html" /> <structure name="IDR_PRINT_PREVIEW_DATA_DESTINATION_HTML" file="data/destination.html" type="chrome_html" />
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 25c6a70..c787664d 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -1556,12 +1556,6 @@ if (use_cras) { defines += [ "USE_CRAS" ] } - } else if (!is_android) { - # !is_chromeos && !is_android - sources += [ - "webui/settings/printing_handler.cc", - "webui/settings/printing_handler.h", - ] } if (is_win || is_mac || is_desktop_linux || is_chromeos) { @@ -3576,6 +3570,12 @@ "//components/printing/browser", "//printing", ] + if (!is_chromeos && !is_android) { + sources += [ + "webui/settings/printing_handler.cc", + "webui/settings/printing_handler.h", + ] + } if (use_cups) { configs += [ "//printing:cups" ] }
diff --git a/chrome/browser/ui/webui/media_router/media_router_ui_unittest.cc b/chrome/browser/ui/webui/media_router/media_router_ui_unittest.cc index 11b8c3b1..61937ce 100644 --- a/chrome/browser/ui/webui/media_router/media_router_ui_unittest.cc +++ b/chrome/browser/ui/webui/media_router/media_router_ui_unittest.cc
@@ -108,19 +108,16 @@ ChromeRenderViewHostTestHarness::SetUp(); EventPageRequestManagerFactory::GetInstance()->SetTestingFactory( profile(), &MockEventPageRequestManager::Create); - mock_router_ = static_cast<MockMediaRouter*>( - MediaRouterFactory::GetInstance()->SetTestingFactoryAndUse( - profile(), &MockMediaRouter::Create)); - EXPECT_CALL(*mock_router_, OnUserGesture()).Times(AnyNumber()); - EXPECT_CALL(*mock_router_, GetCurrentRoutes()) + EXPECT_CALL(mock_router_, OnUserGesture()).Times(AnyNumber()); + EXPECT_CALL(mock_router_, GetCurrentRoutes()) .Times(AnyNumber()) .WillRepeatedly(Return(std::vector<MediaRoute>())); } void TearDown() override { - EXPECT_CALL(*mock_router_, UnregisterMediaSinksObserver(_)) + EXPECT_CALL(mock_router_, UnregisterMediaSinksObserver(_)) .Times(AnyNumber()); - EXPECT_CALL(*mock_router_, UnregisterMediaRoutesObserver(_)) + EXPECT_CALL(mock_router_, UnregisterMediaRoutesObserver(_)) .Times(AnyNumber()); web_ui_contents_.reset(); start_presentation_context_.reset(); @@ -149,15 +146,15 @@ auto file_dialog = base::MakeUnique<MockMediaRouterFileDialog>(); mock_file_dialog_ = file_dialog.get(); - EXPECT_CALL(*mock_router_, RegisterMediaSinksObserver(_)) + EXPECT_CALL(mock_router_, RegisterMediaSinksObserver(_)) .WillRepeatedly(Invoke([this](MediaSinksObserver* observer) { this->media_sinks_observers_.push_back(observer); return true; })); - EXPECT_CALL(*mock_router_, RegisterMediaRoutesObserver(_)) + EXPECT_CALL(mock_router_, RegisterMediaRoutesObserver(_)) .Times(AnyNumber()); media_router_ui_->InitForTest( - mock_router_, web_contents(), message_handler_.get(), + &mock_router_, web_contents(), message_handler_.get(), std::move(start_presentation_context_), std::move(file_dialog)); message_handler_->SetWebUIForTest(&web_ui_); } @@ -174,13 +171,13 @@ // controller. Returns a reference to the mock controller. scoped_refptr<MockMediaRouteController> OpenUIDetailsView( const MediaRoute::Id& route_id) { - auto controller = - base::MakeRefCounted<MockMediaRouteController>(route_id, profile()); + auto controller = base::MakeRefCounted<MockMediaRouteController>( + route_id, profile(), &mock_router_); MediaSource media_source("mediaSource"); MediaRoute route(route_id, media_source, "sinkId", "", true, "", true); media_router_ui_->OnRoutesUpdated({route}, std::vector<MediaRoute::Id>()); - EXPECT_CALL(*mock_router_, GetRouteController(route_id)) + EXPECT_CALL(mock_router_, GetRouteController(route_id)) .WillOnce(Return(controller)); media_router_ui_->OnMediaControllerUIAvailable(route_id); @@ -188,8 +185,8 @@ } protected: + MockMediaRouter mock_router_; content::PresentationRequest presentation_request_; - MockMediaRouter* mock_router_ = nullptr; content::TestWebUI web_ui_; std::unique_ptr<WebContents> web_ui_contents_; std::unique_ptr<StartPresentationContext> start_presentation_context_; @@ -203,7 +200,7 @@ TEST_F(MediaRouterUITest, RouteCreationTimeoutForTab) { CreateMediaRouterUI(profile()); std::vector<MediaRouteResponseCallback> callbacks; - EXPECT_CALL(*mock_router_, + EXPECT_CALL(mock_router_, CreateRouteInternal(_, _, _, _, _, base::TimeDelta::FromSeconds(60), false)) .WillOnce(SaveArgWithMove<4>(&callbacks)); @@ -222,7 +219,7 @@ TEST_F(MediaRouterUITest, RouteCreationTimeoutForDesktop) { CreateMediaRouterUI(profile()); std::vector<MediaRouteResponseCallback> callbacks; - EXPECT_CALL(*mock_router_, + EXPECT_CALL(mock_router_, CreateRouteInternal(_, _, _, _, _, base::TimeDelta::FromSeconds(120), false)) .WillOnce(SaveArgWithMove<4>(&callbacks)); @@ -245,7 +242,7 @@ url::Origin::Create(GURL("https://frameurl.fakeurl"))); media_router_ui_->OnDefaultPresentationChanged(presentation_request); std::vector<MediaRouteResponseCallback> callbacks; - EXPECT_CALL(*mock_router_, + EXPECT_CALL(mock_router_, CreateRouteInternal(_, _, _, _, _, base::TimeDelta::FromSeconds(20), false)) .WillOnce(SaveArgWithMove<4>(&callbacks)); @@ -278,7 +275,7 @@ // Expect that the media_router_ will make a call to the mock_router // then we will want to check that it made the call with. - EXPECT_CALL(*mock_router_, CreateRouteInternal(_, _, _, _, _, _, _)) + EXPECT_CALL(mock_router_, CreateRouteInternal(_, _, _, _, _, _, _)) .WillOnce(SaveArgWithMove<3>(&location_file_opened)); media_router_ui_->CreateRoute(CreateSinkCompatibleWithAllSources().id(), @@ -291,7 +288,7 @@ TEST_F(MediaRouterUITest, RouteCreationParametersCantBeCreated) { CreateMediaRouterUI(profile()); MediaSinkSearchResponseCallback sink_callback; - EXPECT_CALL(*mock_router_, SearchSinksInternal(_, _, _, _, _)) + EXPECT_CALL(mock_router_, SearchSinksInternal(_, _, _, _, _)) .WillOnce(SaveArgWithMove<4>(&sink_callback)); // Use PRESENTATION mode without setting a PresentationRequest. @@ -307,7 +304,7 @@ CreateMediaRouterUI(profile()->GetOffTheRecordProfile()); media_router_ui_->OnDefaultPresentationChanged(presentation_request_); - EXPECT_CALL(*mock_router_, + EXPECT_CALL(mock_router_, CreateRouteInternal(_, _, _, _, _, base::TimeDelta::FromSeconds(20), true)); media_router_ui_->CreateRoute(CreateSinkCompatibleWithAllSources().id(), @@ -434,7 +431,7 @@ MediaSource media_source_3(MediaSourceForDesktop()); std::unique_ptr<MediaRouterUI::UIMediaRoutesObserver> observer( new MediaRouterUI::UIMediaRoutesObserver( - mock_router_, MediaSource::Id(), + &mock_router_, MediaSource::Id(), base::Bind(&MediaRouterUI::OnRoutesUpdated, base::Unretained(media_router_ui_.get())))); @@ -471,7 +468,7 @@ EXPECT_NE(end(current_cast_modes), cast_mode_entry); EXPECT_EQ(MediaCastMode::DESKTOP_MIRROR, cast_mode_entry->second); - EXPECT_CALL(*mock_router_, UnregisterMediaRoutesObserver(_)).Times(1); + EXPECT_CALL(mock_router_, UnregisterMediaRoutesObserver(_)).Times(1); observer.reset(); } @@ -482,7 +479,7 @@ MediaSource media_source_3(MediaSourceForDesktop()); std::unique_ptr<MediaRouterUI::UIMediaRoutesObserver> observer( new MediaRouterUI::UIMediaRoutesObserver( - mock_router_, MediaSource::Id(), + &mock_router_, MediaSource::Id(), base::Bind(&MediaRouterUI::OnRoutesUpdated, base::Unretained(media_router_ui_.get())))); @@ -519,7 +516,7 @@ EXPECT_NE(end(current_cast_modes), cast_mode_entry); EXPECT_EQ(MediaCastMode::DESKTOP_MIRROR, cast_mode_entry->second); - EXPECT_CALL(*mock_router_, UnregisterMediaRoutesObserver(_)).Times(1); + EXPECT_CALL(mock_router_, UnregisterMediaRoutesObserver(_)).Times(1); observer.reset(); } @@ -699,10 +696,10 @@ // When the route details view is closed, the route controller observer should // be destroyed, also triggering the destruction of the controller. - EXPECT_CALL(*mock_router_, DetachRouteController(route_id, _)); + EXPECT_CALL(mock_router_, DetachRouteController(route_id, _)); media_router_ui_->OnMediaControllerUIClosed(); - EXPECT_TRUE(Mock::VerifyAndClearExpectations(mock_router_)); + EXPECT_TRUE(Mock::VerifyAndClearExpectations(&mock_router_)); } TEST_F(MediaRouterUITest, SendMediaStatusUpdate) { @@ -727,8 +724,8 @@ MediaStatus status; status.title = "test title"; std::string route_id = "routeId"; - auto controller = - base::MakeRefCounted<MockMediaRouteController>(route_id, profile()); + auto controller = base::MakeRefCounted<MockMediaRouteController>( + route_id, profile(), &mock_router_); controller->OnMediaStatusUpdated(status); CreateMediaRouterUI(profile()); @@ -738,7 +735,7 @@ // If the controller has already received a media status update, MediaRouterUI // should be notified with it when it starts observing the controller. - EXPECT_CALL(*mock_router_, GetRouteController(route_id)) + EXPECT_CALL(mock_router_, GetRouteController(route_id)) .WillOnce(Return(controller)); EXPECT_CALL(*message_handler_, UpdateMediaRouteStatus(status)); media_router_ui_->OnMediaControllerUIAvailable(route_id); @@ -771,12 +768,12 @@ message_handler_ = base::MakeUnique<MockMediaRouterWebUIMessageHandler>( media_router_ui_.get()); message_handler_->SetWebUIForTest(&web_ui_); - EXPECT_CALL(*mock_router_, RegisterMediaSinksObserver(_)) + EXPECT_CALL(mock_router_, RegisterMediaSinksObserver(_)) .WillRepeatedly(Invoke([this](MediaSinksObserver* observer) { this->media_sinks_observers_.push_back(observer); return true; })); - EXPECT_CALL(*mock_router_, RegisterMediaRoutesObserver(_)).Times(AnyNumber()); + EXPECT_CALL(mock_router_, RegisterMediaRoutesObserver(_)).Times(AnyNumber()); // For some reason we push two sets of cast modes to the dialog, even when // initializing the dialog with a presentation request. The WebUI can handle // the forced mode that is not in the initial cast mode set, but is this a @@ -795,7 +792,7 @@ base::Optional<MediaCastMode>(MediaCastMode::PRESENTATION))); media_router_ui_->UIInitialized(); media_router_ui_->InitForTest( - mock_router_, web_contents(), message_handler_.get(), + &mock_router_, web_contents(), message_handler_.get(), std::move(start_presentation_context_), nullptr); // |media_router_ui_| takes ownership of |request_callbacks|. media_router_ui_.reset();
diff --git a/chrome/browser/ui/webui/media_router/media_router_webui_message_handler_unittest.cc b/chrome/browser/ui/webui/media_router/media_router_webui_message_handler_unittest.cc index 9a541e8c..6c726603 100644 --- a/chrome/browser/ui/webui/media_router/media_router_webui_message_handler_unittest.cc +++ b/chrome/browser/ui/webui/media_router/media_router_webui_message_handler_unittest.cc
@@ -207,8 +207,11 @@ return dict_value; } + MockMediaRouter* router() { return &router_; } + protected: std::unique_ptr<content::TestWebUI> web_ui_; + MockMediaRouter router_; std::unique_ptr<MockMediaRouterUI> mock_media_router_ui_; std::unique_ptr<TestMediaRouterWebUIMessageHandler> handler_; const std::string provider_extension_id_; @@ -619,8 +622,8 @@ } TEST_F(MediaRouterWebUIMessageHandlerTest, OnMediaCommandsReceived) { - auto controller = - base::MakeRefCounted<MockMediaRouteController>("routeId", profile()); + auto controller = base::MakeRefCounted<MockMediaRouteController>( + "routeId", profile(), router()); EXPECT_CALL(*mock_media_router_ui_, GetMediaRouteController()) .WillRepeatedly(Return(controller.get())); MediaStatus status; @@ -657,8 +660,8 @@ } TEST_F(MediaRouterWebUIMessageHandlerTest, OnSetMediaRemotingEnabled) { - auto controller = - base::MakeRefCounted<MirroringMediaRouteController>("routeId", profile()); + auto controller = base::MakeRefCounted<MirroringMediaRouteController>( + "routeId", profile(), router()); EXPECT_CALL(*mock_media_router_ui_, GetMediaRouteController()) .WillRepeatedly(Return(controller.get())); @@ -669,8 +672,8 @@ } TEST_F(MediaRouterWebUIMessageHandlerTest, OnInvalidMediaCommandsReceived) { - auto controller = - base::MakeRefCounted<MockMediaRouteController>("routeId", profile()); + auto controller = base::MakeRefCounted<MockMediaRouteController>( + "routeId", profile(), router()); EXPECT_CALL(*mock_media_router_ui_, GetMediaRouteController()) .WillRepeatedly(Return(controller.get()));
diff --git a/chrome/browser/ui/webui/settings/md_settings_ui.cc b/chrome/browser/ui/webui/settings/md_settings_ui.cc index 6c23035..31915a45 100644 --- a/chrome/browser/ui/webui/settings/md_settings_ui.cc +++ b/chrome/browser/ui/webui/settings/md_settings_ui.cc
@@ -9,6 +9,7 @@ #include <memory> #include <string> #include <utility> +#include <vector> #include "base/memory/ptr_util.h" #include "base/metrics/histogram_macros.h" @@ -46,6 +47,7 @@ #include "content/public/browser/web_contents.h" #include "content/public/browser/web_ui.h" #include "content/public/browser/web_ui_data_source.h" +#include "printing/features/features.h" #if defined(OS_WIN) #include "chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_win.h" @@ -84,7 +86,6 @@ #include "chromeos/chromeos_switches.h" #include "components/arc/arc_util.h" #else // !defined(OS_CHROMEOS) -#include "chrome/browser/ui/webui/settings/printing_handler.h" #include "chrome/browser/ui/webui/settings/settings_default_browser_handler.h" #include "chrome/browser/ui/webui/settings/settings_manage_profile_handler.h" #include "chrome/browser/ui/webui/settings/system_handler.h" @@ -96,6 +97,10 @@ #include "chrome/browser/ui/webui/settings/native_certificates_handler.h" #endif // defined(USE_NSS_CERTS) +#if BUILDFLAG(ENABLE_PRINTING) && !defined(OS_CHROMEOS) +#include "chrome/browser/ui/webui/settings/printing_handler.h" +#endif + #if defined(SAFE_BROWSING_DB_LOCAL) #include "chrome/browser/safe_browsing/chrome_password_protection_service.h" #include "chrome/browser/ui/webui/settings/change_password_handler.h" @@ -186,6 +191,9 @@ AddSettingsPageUIHandler(base::MakeUnique<DefaultBrowserHandler>(web_ui)); AddSettingsPageUIHandler(base::MakeUnique<ManageProfileHandler>(profile)); AddSettingsPageUIHandler(base::MakeUnique<SystemHandler>()); +#endif + +#if BUILDFLAG(ENABLE_PRINTING) && !defined(OS_CHROMEOS) AddSettingsPageUIHandler(base::MakeUnique<PrintingHandler>()); #endif
diff --git a/chrome/browser/ui/webui/settings/printing_handler.h b/chrome/browser/ui/webui/settings/printing_handler.h index b233575e..5759261 100644 --- a/chrome/browser/ui/webui/settings/printing_handler.h +++ b/chrome/browser/ui/webui/settings/printing_handler.h
@@ -6,7 +6,17 @@ #define CHROME_BROWSER_UI_WEBUI_SETTINGS_PRINTING_HANDLER_H_ #include "base/macros.h" +#include "build/build_config.h" #include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h" +#include "printing/features/features.h" + +#if defined(OS_CHROMEOS) +#error "Not for use on ChromeOS" +#endif + +#if !BUILDFLAG(ENABLE_PRINTING) +#error "Printing must be enabled" +#endif namespace settings {
diff --git a/chrome/common/extensions/docs/examples/api/default_command_override/background.js b/chrome/common/extensions/docs/examples/api/default_command_override/background.js new file mode 100644 index 0000000..5d31360 --- /dev/null +++ b/chrome/common/extensions/docs/examples/api/default_command_override/background.js
@@ -0,0 +1,17 @@ +// 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. +chrome.commands.onCommand.addListener(function(command) { + chrome.tabs.query({currentWindow: true}, function(tabs) { + // Sort tabs according to their index in the window. + tabs.sort((a, b) => { return a.index < b.index; }); + let activeIndex = tabs.findIndex((tab) => { return tab.active; }); + let lastTab = tabs.length - 1; + let newIndex = -1; + if (command === 'flip-tabs-forward') + newIndex = activeIndex === 0 ? lastTab : activeIndex - 1; + else // 'flip-tabs-backwards' + newIndex = activeIndex === lastTab ? 0 : activeIndex + 1; + chrome.tabs.update(tabs[newIndex].id, {active: true, highlighted: true}); + }); +});
diff --git a/chrome/common/extensions/docs/examples/api/default_command_override/images/tabFlipper128.png b/chrome/common/extensions/docs/examples/api/default_command_override/images/tabFlipper128.png new file mode 100644 index 0000000..1d1dcb8 --- /dev/null +++ b/chrome/common/extensions/docs/examples/api/default_command_override/images/tabFlipper128.png Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/default_command_override/images/tabFlipper16.png b/chrome/common/extensions/docs/examples/api/default_command_override/images/tabFlipper16.png new file mode 100644 index 0000000..695f64e --- /dev/null +++ b/chrome/common/extensions/docs/examples/api/default_command_override/images/tabFlipper16.png Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/default_command_override/images/tabFlipper32.png b/chrome/common/extensions/docs/examples/api/default_command_override/images/tabFlipper32.png new file mode 100644 index 0000000..67ef0d3 --- /dev/null +++ b/chrome/common/extensions/docs/examples/api/default_command_override/images/tabFlipper32.png Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/default_command_override/images/tabFlipper48.png b/chrome/common/extensions/docs/examples/api/default_command_override/images/tabFlipper48.png new file mode 100644 index 0000000..4bf7680 --- /dev/null +++ b/chrome/common/extensions/docs/examples/api/default_command_override/images/tabFlipper48.png Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/default_command_override/manifest.json b/chrome/common/extensions/docs/examples/api/default_command_override/manifest.json new file mode 100644 index 0000000..803f2b9c --- /dev/null +++ b/chrome/common/extensions/docs/examples/api/default_command_override/manifest.json
@@ -0,0 +1,36 @@ +{ + "name": "Tab Flipper", + "description": "Press Ctrl+Shift+Right or Ctrl+Shift+Left (Command+Shift+Right or Command+Shift+Left on a Mac) to flip through window tabs", + "version": "1.0", + "manifest_version": 2, + "background": { + "scripts": ["background.js"], + "persistent": false + }, + "browser_action": { + "default_icon": "images/tabFlipper16.png", + "default_title": "Press Ctrl(Win)/Command(Mac)+Shift+ Left or Right to Flip Tabs" + }, + "commands": { + "flip-tabs-forward": { + "suggested_key": { + "default": "Ctrl+Shift+Right", + "mac": "Command+Shift+Right" + }, + "description": "Flip tabs forward" + }, + "flip-tabs-backwards": { + "suggested_key": { + "default": "Ctrl+Shift+Left", + "mac": "Command+Shift+Left" + }, + "description": "Flip tabs backwards" + } + }, + "icons": { + "16": "images/tabFlipper16.png", + "32": "images/tabFlipper32.png", + "48": "images/tabFlipper48.png", + "128": "images/tabFlipper128.png" + } +}
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 187aa88..6d71244 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -568,8 +568,7 @@ "../browser/metrics/process_memory_metrics_emitter_browsertest.cc", "../browser/metrics/startup_metrics_browsertest.cc", "../browser/metrics/tab_reactivation_tracker_browsertest.cc", - "../browser/metrics/tab_stats_data_store_unittests.cc", - "../browser/metrics/tab_stats_tracker_unittests.cc", + "../browser/metrics/tab_stats_tracker_browsertest.cc", "../browser/metrics/ukm_browsertest.cc", "../browser/net/chrome_mojo_proxy_resolver_factory_browsertest.cc", "../browser/net/chrome_network_delegate_browsertest.cc", @@ -2743,6 +2742,8 @@ "../browser/media_galleries/win/mtp_device_delegate_impl_win_unittest.cc", "../browser/media_galleries/win/mtp_device_object_enumerator_unittest.cc", "../browser/memory/swap_thrashing_monitor_delegate_win_unittest.cc", + "../browser/metrics/tab_stats_data_store_unittests.cc", + "../browser/metrics/tab_stats_tracker_unittests.cc", "../browser/page_load_metrics/observers/session_restore_page_load_metrics_observer_unittest.cc", "../browser/resource_coordinator/background_tab_navigation_throttle_unittest.cc", "../browser/resource_coordinator/lifecycle_unit_unittest.cc",
diff --git a/chrome/test/data/webui/print_preview/native_layer_stub.js b/chrome/test/data/webui/print_preview/native_layer_stub.js index ba51133..72044e77 100644 --- a/chrome/test/data/webui/print_preview/native_layer_stub.js +++ b/chrome/test/data/webui/print_preview/native_layer_stub.js
@@ -73,22 +73,20 @@ } /** @override */ - getPreview( - destination, printTicketStore, documentInfo, generateDraft, requestId) { + getPreview(printTicket, pageCount) { this.methodCalled('getPreview', { - destination: destination, - printTicketStore: printTicketStore, - documentInfo: documentInfo, - generateDraft: generateDraft, - requestId: requestId, + printTicket: printTicket, + pageCount: pageCount }); - if (destination.id == this.badPrinterId_) { + const printTicketParsed = JSON.parse(printTicket); + if (printTicketParsed.deviceName == this.badPrinterId_) { let rejectString = print_preview.PreviewArea.EventType.SETTINGS_INVALID; rejectString = rejectString.substring( rejectString.lastIndexOf('.') + 1, rejectString.length); return Promise.reject(rejectString); } - const pageRanges = printTicketStore.pageRange.getDocumentPageRanges(); + const pageRanges = printTicketParsed.pageRange; + const requestId = printTicketParsed.requestID; if (pageRanges.length == 0) { // assume full length document, 1 page. cr.webUIListenerCallback('page-count-ready', 1, requestId, 100); cr.webUIListenerCallback('page-preview-ready', 0, 0, requestId); @@ -122,20 +120,8 @@ } /** @override */ - print( - destination, - printTicketStore, - documentInfo, - opt_isOpenPdfInPreview, - opt_showSystemDialog - ) { - this.methodCalled('print', { - destination: destination, - printTicketStore: printTicketStore, - documentInfo: documentInfo, - openPdfInPreview: opt_isOpenPdfInPreview || false, - showSystemDialog: opt_showSystemDialog || false, - }); + print(printTicket) { + this.methodCalled('print', printTicket); return Promise.resolve(); }
diff --git a/chrome/test/data/webui/print_preview/print_preview_tests.js b/chrome/test/data/webui/print_preview/print_preview_tests.js index a01a34b..8fe10e294 100644 --- a/chrome/test/data/webui/print_preview/print_preview_tests.js +++ b/chrome/test/data/webui/print_preview/print_preview_tests.js
@@ -644,24 +644,22 @@ 'ID1', printPreview.destinationStore_.selectedDestination.id); // Validate the parameters for getPreview match the app state. - expectEquals('CUSTOM_SQUARE', - args[1].printTicketStore.mediaSize.getValue().name); - expectEquals('90', args[1].printTicketStore.scaling.getValue()); - expectEquals( - 100, args[1].printTicketStore.dpi.getValue().horizontal_dpi); - expectTrue(args[1].printTicketStore.headerFooter.getValue()); - expectTrue(args[1].printTicketStore.cssBackground.getValue()); - expectTrue(args[1].printTicketStore.fitToPage.getValue()); - expectTrue(args[1].printTicketStore.collate.getValue()); - expectTrue(args[1].printTicketStore.duplex.getValue()); - expectTrue(args[1].printTicketStore.landscape.getValue()); - expectTrue(args[1].printTicketStore.color.getValue()); + const ticket = JSON.parse(args[1].printTicket); + expectEquals('CUSTOM_SQUARE', ticket.mediaSize.name); + expectEquals(90, ticket.scaleFactor); + expectEquals(100, ticket.dpiHorizontal); + expectTrue(ticket.headerFooterEnabled); + expectTrue(ticket.shouldPrintBackgrounds); + expectTrue(ticket.fitToPageEnabled); + expectTrue(ticket.collate); + expectEquals(ticket.duplex, + print_preview.PreviewGenerator.DuplexMode.LONG_EDGE); + expectTrue(ticket.landscape); + expectEquals(ticket.color, + print_preview.PreviewGenerator.ColorMode.COLOR); expectEquals(print_preview.ticket_items.MarginsTypeValue.CUSTOM, - args[1].printTicketStore.marginsType.getValue()); - expectEquals( - 74, - args[1].printTicketStore.customMargins.getValue().get( - print_preview.ticket_items.CustomMarginsOrientation.TOP)); + ticket.marginsType); + expectEquals(74, ticket.marginsCustom.marginTop); // Change scaling (a persisted ticket item value) expandMoreSettings(); @@ -842,8 +840,9 @@ const fitToPageContainer = scalingSettings.querySelector('#fit-to-page-container'); checkElementDisplayed(fitToPageContainer, true); - expectTrue(args[1].printTicketStore.fitToPage.getValue()); - expectEquals('100', args[1].printTicketStore.scaling.getValue()); + const ticket = JSON.parse(args[1].printTicket); + expectTrue(ticket.fitToPageEnabled); + expectEquals(100, ticket.scaleFactor); expectTrue(fitToPageContainer.querySelector('.checkbox').checked); expandMoreSettings(); checkSectionVisible($('media-size-settings'), true); @@ -863,10 +862,12 @@ scalingInput.dispatchEvent(enterEvent); // Wait for the preview to refresh and verify print ticket and - // display. + // display. There will be 2 preview requests. Since we only catch + // the first one, only verify fit to page in print ticket. return nativeLayer.whenCalled('getPreview').then(function(args) { - expectFalse(args.printTicketStore.fitToPage.getValue()); - expectEquals('105', args.printTicketStore.scaling.getValue()); + console.log('args.printticket ' + args.printTicket); + const updatedTicket = JSON.parse(args.printTicket); + expectFalse(updatedTicket.fitToPageEnabled); expectFalse(fitToPageContainer.querySelector('.checkbox').checked); return whenAnimationDone('more-settings'); }); @@ -1256,8 +1257,9 @@ setupSettingsAndDestinationsWithCapabilities(), nativeLayer.whenCalled('getPreview'), ]).then(function(args) { - expectEquals(0, args[1].requestId); - expectEquals('FooDevice', args[1].destination.id); + const ticket = JSON.parse(args[1].printTicket); + expectEquals(0, ticket.requestID); + expectEquals('FooDevice', ticket.deviceName); nativeLayer.reset(); // Setup capabilities for BarDevice. @@ -1275,8 +1277,9 @@ printPreview.destinationStore_.selectDestination(barDestination); return waitForPrinterToUpdatePreview(); }).then(function(args) { - expectEquals(1, args[1].requestId); - expectEquals('BarDevice', args[1].destination.id); + const ticket = JSON.parse(args[1].printTicket); + expectEquals(1, ticket.requestID); + expectEquals('BarDevice', ticket.deviceName); }); }); @@ -1434,8 +1437,9 @@ expectEquals('ID1', id); return nativeLayer.whenCalled('getPreview'); }).then(function(previewArgs) { - expectEquals(0, previewArgs.requestId); - expectEquals('ID1', previewArgs.destination.id); + const ticket = JSON.parse(previewArgs.printTicket); + expectEquals(0, ticket.requestID); + expectEquals('ID1', ticket.deviceName); }); }); @@ -1489,30 +1493,22 @@ return nativeLayer.whenCalled('print'); }).then( /** - * @param {{destination: !print_preview.Destination, - * printTicketStore: !print_preview.PrintTicketStore, - * cloudPrintInterface: print_preview - * .CloudPrintInterface, - * documentInfo: print_preview.DocumentInfo, - * openPdfInPreview: boolean, - * showSystemDialog: boolean}} args - * The arguments that print() was called with. + * @param {string} printTicket The print ticket print() was called + * for. */ - function(args) { + function(printTicket) { // Sanity check some printing argument values. - const printTicketStore = args.printTicketStore; - expectEquals(barDevice.printer.deviceName, args.destination.id); + const ticket = JSON.parse(printTicket); + expectEquals(barDevice.printer.deviceName, ticket.deviceName); expectEquals( getDefaultOrientation(barDevice) == 'LANDSCAPE', - printTicketStore.landscape.getValue()); - expectEquals(1, printTicketStore.copies.getValueAsNumber()); + ticket.landscape); + expectEquals(1, ticket.copies); const mediaDefault = getDefaultMediaSize(barDevice); expectEquals( - mediaDefault.width_microns, - printTicketStore.mediaSize.getValue().width_microns); + mediaDefault.width_microns, ticket.mediaSize.width_microns); expectEquals( - mediaDefault.height_microns, - printTicketStore.mediaSize.getValue().height_microns); + mediaDefault.height_microns, ticket.mediaSize.height_microns); return nativeLayer.whenCalled('hidePreview'); }); }); @@ -1526,16 +1522,18 @@ ]).then(function(args) { // The first request should generate draft because there was no // previous print preview draft. - expectTrue(args[1].generateDraft); - expectEquals(0, args[1].requestId); + const ticket = JSON.parse(args[1].printTicket); + expectTrue(ticket.generateDraft); + expectEquals(0, ticket.requestID); nativeLayer.resetResolver('getPreview'); // Change the page range - no new draft needed. printPreview.printTicketStore_.pageRange.updateValue('2'); return nativeLayer.whenCalled('getPreview'); }).then(function(args) { - expectFalse(args.generateDraft); - expectEquals(1, args.requestId); + const ticket = JSON.parse(args.printTicket); + expectFalse(ticket.generateDraft); + expectEquals(1, ticket.requestID); nativeLayer.resetResolver('getPreview'); // Change the margin type - need to regenerate again. @@ -1543,8 +1541,9 @@ print_preview.ticket_items.MarginsTypeValue.NO_MARGINS); return nativeLayer.whenCalled('getPreview'); }).then(function(args) { - expectTrue(args.generateDraft); - expectEquals(2, args.requestId); + const ticket = JSON.parse(args.printTicket); + expectTrue(ticket.generateDraft); + expectEquals(2, ticket.requestID); }); }); @@ -1604,17 +1603,11 @@ return nativeLayer.whenCalled('print'); }).then( /** - * @param {{destination: !print_preview.Destination, - * printTicketStore: !print_preview.PrintTicketStore, - * cloudPrintInterface: print_preview - * .CloudPrintInterface, - * documentInfo: print_preview.DocumentInfo, - * openPdfInPreview: boolean - * showSystemDialog: boolean}} args - * The arguments that print() was called with. + * @param {string} printTicket The print ticket print() was + * called for. */ - function(args) { - expectTrue(args.openPdfInPreview); + function(printTicket) { + expectTrue(JSON.parse(printTicket).OpenPDFInPreview); return nativeLayer.whenCalled('hidePreview'); }); }); @@ -1672,17 +1665,11 @@ return nativeLayer.whenCalled('print'); }).then( /** - * @param {{destination: !print_preview.Destination, - * printTicketStore: !print_preview.PrintTicketStore, - * cloudPrintInterface: print_preview - * .CloudPrintInterface, - * documentInfo: print_preview.DocumentInfo, - * openPdfInPreview: boolean - * showSystemDialog: boolean}} args - * The arguments that print() was called with. + * @param {string} printTicket The print ticket print() was + * called for. */ - function(args) { - expectTrue(args.showSystemDialog); + function(printTicket) { + expectTrue(JSON.parse(printTicket).showSystemDialog); return nativeLayer.whenCalled('hidePreview'); }); });
diff --git a/chromeos/printing/printer_translator.cc b/chromeos/printing/printer_translator.cc index d361d6b..14b6ac42 100644 --- a/chromeos/printing/printer_translator.cc +++ b/chromeos/printing/printer_translator.cc
@@ -30,6 +30,7 @@ const char kUri[] = "uri"; const char kUUID[] = "uuid"; const char kPpdResource[] = "ppd_resource"; +const char kGuid[] = "guid"; // Populates the |printer| object with corresponding fields from |value|. // Returns false if |value| is missing a required field. @@ -84,7 +85,8 @@ std::unique_ptr<Printer> RecommendedPrinterToPrinter( const base::DictionaryValue& pref) { std::string id; - if (!pref.GetString(kPrinterId, &id)) { + // Printer id comes from the id or guid field depending on the source. + if (!pref.GetString(kPrinterId, &id) && !pref.GetString(kGuid, &id)) { LOG(WARNING) << "Record id required"; return nullptr; }
diff --git a/chromeos/printing/printer_translator_unittest.cc b/chromeos/printing/printer_translator_unittest.cc index ce265586..dc152e82 100644 --- a/chromeos/printing/printer_translator_unittest.cc +++ b/chromeos/printing/printer_translator_unittest.cc
@@ -25,6 +25,8 @@ const char kModel[] = "Inktastic Laser Magic"; const char kMakeAndModel[] = "Chrome Inktastic Laser Magic"; +const char kGUID[] = "{4d8faf22-303f-46c6-ab30-352d47d6a8b9}"; + // PpdReference test data const char kEffectiveMakeAndModel[] = "PrintBlaster LazerInker 2000"; @@ -148,4 +150,17 @@ EXPECT_EQ(kMake, printer->make_and_model()); } +TEST(PrinterTranslatorTest, BulkPrinterJson) { + base::DictionaryValue preference; + preference.SetString("guid", kGUID); + preference.SetString("display_name", kName); + preference.SetString("uri", kUri); + preference.SetString("ppd_resource.effective_model", kEffectiveMakeAndModel); + + std::unique_ptr<Printer> printer = RecommendedPrinterToPrinter(preference); + EXPECT_TRUE(printer); + + EXPECT_EQ(kGUID, printer->id()); +} + } // namespace chromeos
diff --git a/components/favicon/ios/web_favicon_driver.h b/components/favicon/ios/web_favicon_driver.h index a387ab1..482a954 100644 --- a/components/favicon/ios/web_favicon_driver.h +++ b/components/favicon/ios/web_favicon_driver.h
@@ -60,8 +60,6 @@ history::HistoryService* history_service); // web::WebStateObserver implementation. - void DidStartNavigation(web::WebState* web_state, - web::NavigationContext* navigation_context) override; void DidFinishNavigation(web::WebState* web_state, web::NavigationContext* navigation_context) override; void FaviconUrlUpdated( @@ -76,9 +74,6 @@ // Image Fetcher used to fetch favicon. image_fetcher::IOSImageDataFetcherWrapper image_fetcher_; - // Caches the favicon URLs candidates for same-document navigations. - std::vector<favicon::FaviconURL> candidates_; - // The WebState this instance is observing. Will be null after // WebStateDestroyed has been called. web::WebState* web_state_ = nullptr;
diff --git a/components/favicon/ios/web_favicon_driver.mm b/components/favicon/ios/web_favicon_driver.mm index c00b18a..64537f56 100644 --- a/components/favicon/ios/web_favicon_driver.mm +++ b/components/favicon/ios/web_favicon_driver.mm
@@ -117,13 +117,10 @@ // On iOS, the active URL can change between calls to FetchFavicon(). For // instance, FetchFavicon() is not synchronously called when the active URL // changes as a result of CRWSessionController::goToEntry(). - if (GetActiveURL() != page_url && !page_url.is_empty()) { - return; - } - web::NavigationItem* item = web_state_->GetNavigationManager()->GetVisibleItem(); - DCHECK(item); + if (!item || item->GetURL() != page_url) + return; web::FaviconStatus& favicon_status = item->GetFavicon(); favicon_status.valid = true; @@ -168,32 +165,11 @@ DCHECK(!web_state_); } -void WebFaviconDriver::DidStartNavigation( - web::WebState* web_state, - web::NavigationContext* navigation_context) { - DCHECK_EQ(web_state_, web_state); - SetFaviconOutOfDateForPage(navigation_context->GetUrl(), - /*force_reload=*/false); -} - void WebFaviconDriver::DidFinishNavigation( web::WebState* web_state, web::NavigationContext* navigation_context) { - DCHECK_EQ(web_state_, web_state); - if (navigation_context->GetError()) - return; - - // Fetch the favicon for the new URL. - FetchFavicon(navigation_context->GetUrl(), + FetchFavicon(web_state->GetLastCommittedURL(), navigation_context->IsSameDocument()); - - if (navigation_context->IsSameDocument()) { - if (!candidates_.empty()) { - FaviconUrlUpdatedInternal(candidates_); - } - } else { - candidates_.clear(); - } } void WebFaviconDriver::FaviconUrlUpdated( @@ -201,8 +177,8 @@ const std::vector<web::FaviconURL>& candidates) { DCHECK_EQ(web_state_, web_state); DCHECK(!candidates.empty()); - candidates_ = FaviconURLsFromWebFaviconURLs(candidates); - FaviconUrlUpdatedInternal(candidates_); + OnUpdateCandidates(GetActiveURL(), FaviconURLsFromWebFaviconURLs(candidates), + GURL()); } void WebFaviconDriver::WebStateDestroyed(web::WebState* web_state) { @@ -211,9 +187,4 @@ web_state_ = nullptr; } -void WebFaviconDriver::FaviconUrlUpdatedInternal( - const std::vector<favicon::FaviconURL>& candidates) { - OnUpdateCandidates(GetActiveURL(), candidates, GURL()); -} - } // namespace favicon
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index 1f08638c..5e7a35a 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn
@@ -1562,6 +1562,8 @@ "shared_worker/worker_storage_partition.h", "site_instance_impl.cc", "site_instance_impl.h", + "site_isolation_policy.cc", + "site_isolation_policy.h", "speech/speech_recognition_dispatcher_host.cc", "speech/speech_recognition_dispatcher_host.h", "speech/speech_recognition_manager_impl.cc",
diff --git a/content/browser/browser_main_loop.cc b/content/browser/browser_main_loop.cc index 2ed9c26..e9bee04d 100644 --- a/content/browser/browser_main_loop.cc +++ b/content/browser/browser_main_loop.cc
@@ -84,6 +84,7 @@ #include "content/browser/renderer_host/media/media_stream_manager.h" #include "content/browser/renderer_host/render_process_host_impl.h" #include "content/browser/service_manager/service_manager_context.h" +#include "content/browser/site_isolation_policy.h" #include "content/browser/speech/speech_recognition_manager_impl.h" #include "content/browser/startup_task_runner.h" #include "content/browser/tracing/background_tracing_manager_impl.h" @@ -93,7 +94,6 @@ #include "content/browser/webui/url_data_manager.h" #include "content/common/content_switches_internal.h" #include "content/common/service_manager/service_manager_connection_impl.h" -#include "content/common/site_isolation_policy.h" #include "content/common/task_scheduler.h" #include "content/public/browser/browser_main_parts.h" #include "content/public/browser/content_browser_client.h" @@ -913,8 +913,6 @@ ChildProcessSecurityPolicyImpl* policy = ChildProcessSecurityPolicyImpl::GetInstance(); policy->AddIsolatedOrigins(SiteIsolationPolicy::GetIsolatedOrigins()); - policy->AddIsolatedOrigins( - GetContentClient()->browser()->GetOriginsRequiringDedicatedProcess()); return result_code_; }
diff --git a/content/browser/browser_plugin/browser_plugin_guest.cc b/content/browser/browser_plugin/browser_plugin_guest.cc index bc1151fc..fc152cf 100644 --- a/content/browser/browser_plugin/browser_plugin_guest.cc +++ b/content/browser/browser_plugin/browser_plugin_guest.cc
@@ -41,7 +41,6 @@ #include "content/common/drag_messages.h" #include "content/common/input/ime_text_span_conversions.h" #include "content/common/input_messages.h" -#include "content/common/site_isolation_policy.h" #include "content/common/text_input_state.h" #include "content/common/view_messages.h" #include "content/public/browser/browser_context.h"
diff --git a/content/browser/browser_side_navigation_browsertest.cc b/content/browser/browser_side_navigation_browsertest.cc index 4a3e30e..c0125365 100644 --- a/content/browser/browser_side_navigation_browsertest.cc +++ b/content/browser/browser_side_navigation_browsertest.cc
@@ -13,7 +13,6 @@ #include "content/browser/frame_host/navigation_request.h" #include "content/browser/web_contents/web_contents_impl.h" #include "content/common/frame_messages.h" -#include "content/common/site_isolation_policy.h" #include "content/public/browser/navigation_controller.h" #include "content/public/browser/notification_types.h" #include "content/public/browser/web_contents.h"
diff --git a/content/browser/browsing_instance.cc b/content/browser/browsing_instance.cc index 33f0ebc..c7ed216 100644 --- a/content/browser/browsing_instance.cc +++ b/content/browser/browsing_instance.cc
@@ -7,7 +7,7 @@ #include "base/command_line.h" #include "base/logging.h" #include "content/browser/site_instance_impl.h" -#include "content/common/site_isolation_policy.h" +#include "content/browser/site_isolation_policy.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/content_browser_client.h" #include "content/public/common/content_switches.h"
diff --git a/content/browser/child_process_security_policy_impl.cc b/content/browser/child_process_security_policy_impl.cc index 2356dbb2..2fbe6d58 100644 --- a/content/browser/child_process_security_policy_impl.cc +++ b/content/browser/child_process_security_policy_impl.cc
@@ -20,7 +20,7 @@ #include "build/build_config.h" #include "content/browser/isolated_origin_util.h" #include "content/browser/site_instance_impl.h" -#include "content/common/site_isolation_policy.h" +#include "content/browser/site_isolation_policy.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/child_process_data.h"
diff --git a/content/browser/devtools/shared_worker_devtools_agent_host.cc b/content/browser/devtools/shared_worker_devtools_agent_host.cc index 4e32657..91fd27e5 100644 --- a/content/browser/devtools/shared_worker_devtools_agent_host.cc +++ b/content/browser/devtools/shared_worker_devtools_agent_host.cc
@@ -4,31 +4,48 @@ #include "content/browser/devtools/shared_worker_devtools_agent_host.h" +#include "content/browser/devtools/devtools_session.h" +#include "content/browser/devtools/protocol/inspector_handler.h" +#include "content/browser/devtools/protocol/network_handler.h" +#include "content/browser/devtools/protocol/protocol.h" +#include "content/browser/devtools/protocol/schema_handler.h" #include "content/browser/devtools/shared_worker_devtools_manager.h" +#include "content/browser/shared_worker/shared_worker_host.h" #include "content/browser/shared_worker/shared_worker_instance.h" #include "content/browser/shared_worker/shared_worker_service_impl.h" #include "content/public/browser/browser_thread.h" +#include "content/public/browser/render_process_host.h" namespace content { SharedWorkerDevToolsAgentHost::SharedWorkerDevToolsAgentHost( - WorkerId worker_id, - const SharedWorkerInstance& shared_worker) - : WorkerDevToolsAgentHost(shared_worker.devtools_worker_token(), worker_id), - shared_worker_(new SharedWorkerInstance(shared_worker)) { + SharedWorkerHost* worker_host) + : DevToolsAgentHostImpl( + worker_host->instance()->devtools_worker_token().ToString()), + worker_host_(worker_host), + instance_(new SharedWorkerInstance(*worker_host->instance())) { NotifyCreated(); } +SharedWorkerDevToolsAgentHost::~SharedWorkerDevToolsAgentHost() { + SharedWorkerDevToolsManager::GetInstance()->AgentHostDestroyed(this); +} + +BrowserContext* SharedWorkerDevToolsAgentHost::GetBrowserContext() { + RenderProcessHost* rph = GetProcess(); + return rph ? rph->GetBrowserContext() : nullptr; +} + std::string SharedWorkerDevToolsAgentHost::GetType() { return kTypeSharedWorker; } std::string SharedWorkerDevToolsAgentHost::GetTitle() { - return shared_worker_->name(); + return instance_->name(); } GURL SharedWorkerDevToolsAgentHost::GetURL() { - return shared_worker_->url(); + return instance_->url(); } bool SharedWorkerDevToolsAgentHost::Activate() { @@ -39,19 +56,128 @@ } bool SharedWorkerDevToolsAgentHost::Close() { - static_cast<SharedWorkerServiceImpl*>(SharedWorkerService::GetInstance()) - ->TerminateWorkerById(worker_id().first, worker_id().second); + if (worker_host_) + worker_host_->TerminateWorker(); return true; } -bool SharedWorkerDevToolsAgentHost::Matches( - const SharedWorkerInstance& other) { - return shared_worker_->Matches(other); +void SharedWorkerDevToolsAgentHost::AttachSession(DevToolsSession* session) { + if (RenderProcessHost* host = GetProcess()) { + if (sessions().size() == 1) + host->AddRoute(worker_host_->route_id(), this); + session->SetRenderer(host, nullptr); + if (!waiting_ready_for_reattach_) { + host->Send(new DevToolsAgentMsg_Attach(worker_host_->route_id(), + session->session_id())); + } + } + session->SetFallThroughForNotFound(true); + session->AddHandler(std::make_unique<protocol::InspectorHandler>()); + session->AddHandler(std::make_unique<protocol::NetworkHandler>(GetId())); + session->AddHandler(std::make_unique<protocol::SchemaHandler>()); } -SharedWorkerDevToolsAgentHost::~SharedWorkerDevToolsAgentHost() { - SharedWorkerDevToolsManager::GetInstance()->RemoveInspectedWorkerData( - worker_id()); +void SharedWorkerDevToolsAgentHost::DetachSession(int session_id) { + if (RenderProcessHost* host = GetProcess()) { + host->Send( + new DevToolsAgentMsg_Detach(worker_host_->route_id(), session_id)); + if (!sessions().size()) + host->RemoveRoute(worker_host_->route_id()); + } +} + +bool SharedWorkerDevToolsAgentHost::DispatchProtocolMessage( + DevToolsSession* session, + const std::string& message) { + int call_id = 0; + std::string method; + if (session->Dispatch(message, &call_id, &method) != + protocol::Response::kFallThrough) { + return true; + } + + if (RenderProcessHost* host = GetProcess()) { + host->Send(new DevToolsAgentMsg_DispatchOnInspectorBackend( + worker_host_->route_id(), session->session_id(), call_id, method, + message)); + session->waiting_messages()[call_id] = {method, message}; + } + return true; +} + +bool SharedWorkerDevToolsAgentHost::OnMessageReceived(const IPC::Message& msg) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + bool handled = true; + IPC_BEGIN_MESSAGE_MAP(SharedWorkerDevToolsAgentHost, msg) + IPC_MESSAGE_HANDLER(DevToolsClientMsg_DispatchOnInspectorFrontend, + OnDispatchOnInspectorFrontend) + IPC_MESSAGE_UNHANDLED(handled = false) + IPC_END_MESSAGE_MAP() + return handled; +} + +bool SharedWorkerDevToolsAgentHost::Matches(SharedWorkerHost* worker_host) { + return instance_->Matches(*worker_host->instance()); +} + +void SharedWorkerDevToolsAgentHost::WorkerReadyForInspection() { + DCHECK(worker_host_); + if (!waiting_ready_for_reattach_) + return; + waiting_ready_for_reattach_ = false; + if (RenderProcessHost* host = GetProcess()) { + for (DevToolsSession* session : sessions()) { + host->Send(new DevToolsAgentMsg_Reattach(worker_host_->route_id(), + session->session_id(), + session->state_cookie())); + for (const auto& pair : session->waiting_messages()) { + int call_id = pair.first; + const DevToolsSession::Message& message = pair.second; + host->Send(new DevToolsAgentMsg_DispatchOnInspectorBackend( + worker_host_->route_id(), session->session_id(), call_id, + message.method, message.message)); + } + } + } +} + +bool SharedWorkerDevToolsAgentHost::WorkerRestarted( + SharedWorkerHost* worker_host) { + DCHECK(!worker_host_); + worker_host_ = worker_host; + if (RenderProcessHost* host = GetProcess()) { + if (sessions().size()) + host->AddRoute(worker_host_->route_id(), this); + for (DevToolsSession* session : sessions()) + session->SetRenderer(host, nullptr); + } + waiting_ready_for_reattach_ = IsAttached(); + return waiting_ready_for_reattach_; +} + +void SharedWorkerDevToolsAgentHost::WorkerDestroyed() { + DCHECK(worker_host_); + for (auto* inspector : protocol::InspectorHandler::ForAgentHost(this)) + inspector->TargetCrashed(); + for (DevToolsSession* session : sessions()) + session->SetRenderer(nullptr, nullptr); + if (sessions().size()) { + if (RenderProcessHost* host = GetProcess()) + host->RemoveRoute(worker_host_->route_id()); + } + worker_host_ = nullptr; +} + +RenderProcessHost* SharedWorkerDevToolsAgentHost::GetProcess() { + return worker_host_ ? RenderProcessHost::FromID(worker_host_->process_id()) + : nullptr; +} + +void SharedWorkerDevToolsAgentHost::OnDispatchOnInspectorFrontend( + const DevToolsMessageChunk& message) { + DevToolsSession* session = SessionById(message.session_id); + if (session) + session->ReceiveMessageChunk(message); } } // namespace content
diff --git a/content/browser/devtools/shared_worker_devtools_agent_host.h b/content/browser/devtools/shared_worker_devtools_agent_host.h index 1566798..c445bc9 100644 --- a/content/browser/devtools/shared_worker_devtools_agent_host.h +++ b/content/browser/devtools/shared_worker_devtools_agent_host.h
@@ -6,20 +6,24 @@ #define CONTENT_BROWSER_DEVTOOLS_SHARED_WORKER_DEVTOOLS_AGENT_HOST_H_ #include "base/macros.h" -#include "content/browser/devtools/worker_devtools_agent_host.h" +#include "content/browser/devtools/devtools_agent_host_impl.h" +#include "ipc/ipc_listener.h" namespace content { class SharedWorkerInstance; +class SharedWorkerHost; +class RenderProcessHost; -class SharedWorkerDevToolsAgentHost : public WorkerDevToolsAgentHost { +class SharedWorkerDevToolsAgentHost : public DevToolsAgentHostImpl, + public IPC::Listener { public: using List = std::vector<scoped_refptr<SharedWorkerDevToolsAgentHost>>; - SharedWorkerDevToolsAgentHost(WorkerId worker_id, - const SharedWorkerInstance& shared_worker); + explicit SharedWorkerDevToolsAgentHost(SharedWorkerHost* worker_host); // DevToolsAgentHost override. + BrowserContext* GetBrowserContext() override; std::string GetType() override; std::string GetTitle() override; GURL GetURL() override; @@ -27,13 +31,31 @@ void Reload() override; bool Close() override; - bool Matches(const SharedWorkerInstance& other); + // DevToolsAgentHostImpl overrides. + void AttachSession(DevToolsSession* session) override; + void DetachSession(int session_id) override; + bool DispatchProtocolMessage(DevToolsSession* session, + const std::string& message) override; + + // IPC::Listener implementation. + bool OnMessageReceived(const IPC::Message& msg) override; + + bool Matches(SharedWorkerHost* worker_host); + void WorkerReadyForInspection(); + // Returns whether the worker should be paused for reattach. + bool WorkerRestarted(SharedWorkerHost* worker_host); + void WorkerDestroyed(); private: friend class SharedWorkerDevToolsManagerTest; ~SharedWorkerDevToolsAgentHost() override; - std::unique_ptr<SharedWorkerInstance> shared_worker_; + RenderProcessHost* GetProcess(); + void OnDispatchOnInspectorFrontend(const DevToolsMessageChunk& message); + + SharedWorkerHost* worker_host_; + std::unique_ptr<SharedWorkerInstance> instance_; + bool waiting_ready_for_reattach_ = false; DISALLOW_COPY_AND_ASSIGN(SharedWorkerDevToolsAgentHost); };
diff --git a/content/browser/devtools/shared_worker_devtools_manager.cc b/content/browser/devtools/shared_worker_devtools_manager.cc index 9903398..1ba4e39 100644 --- a/content/browser/devtools/shared_worker_devtools_manager.cc +++ b/content/browser/devtools/shared_worker_devtools_manager.cc
@@ -5,7 +5,7 @@ #include "content/browser/devtools/shared_worker_devtools_manager.h" #include "content/browser/devtools/shared_worker_devtools_agent_host.h" -#include "content/browser/shared_worker/shared_worker_instance.h" +#include "content/browser/shared_worker/shared_worker_host.h" #include "content/public/browser/browser_thread.h" namespace content { @@ -18,80 +18,61 @@ void SharedWorkerDevToolsManager::AddAllAgentHosts( SharedWorkerDevToolsAgentHost::List* result) { - for (auto& worker : workers_) { - if (!worker.second->IsTerminated()) - result->push_back(worker.second); - } + for (auto& it : live_hosts_) + result->push_back(it.second.get()); } -bool SharedWorkerDevToolsManager::WorkerCreated( - int worker_process_id, - int worker_route_id, - const SharedWorkerInstance& instance) { +bool SharedWorkerDevToolsManager::WorkerCreated(SharedWorkerHost* worker_host) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - const WorkerId id(worker_process_id, worker_route_id); - AgentHostMap::iterator it = - FindExistingWorkerAgentHost(instance); - if (it == workers_.end()) { - workers_[id] = new SharedWorkerDevToolsAgentHost(id, instance); + DCHECK(live_hosts_.find(worker_host) == live_hosts_.end()); + + auto it = + std::find_if(terminated_hosts_.begin(), terminated_hosts_.end(), + [&worker_host](SharedWorkerDevToolsAgentHost* agent_host) { + return agent_host->Matches(worker_host); + }); + if (it == terminated_hosts_.end()) { + live_hosts_[worker_host] = new SharedWorkerDevToolsAgentHost(worker_host); return false; } - // Worker restarted. - SharedWorkerDevToolsAgentHost* agent_host = it->second; - agent_host->WorkerRestarted(id); - workers_.erase(it); - workers_[id] = agent_host; - return agent_host->IsAttached(); + SharedWorkerDevToolsAgentHost* agent_host = *it; + terminated_hosts_.erase(it); + live_hosts_[worker_host] = agent_host; + return agent_host->WorkerRestarted(worker_host); } void SharedWorkerDevToolsManager::WorkerReadyForInspection( - int worker_process_id, - int worker_route_id) { + SharedWorkerHost* worker_host) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - const WorkerId id(worker_process_id, worker_route_id); - AgentHostMap::iterator it = workers_.find(id); - if (it == workers_.end() || it->second->IsTerminated()) - return; - it->second->WorkerReadyForInspection(); + live_hosts_[worker_host]->WorkerReadyForInspection(); } void SharedWorkerDevToolsManager::WorkerDestroyed( - int worker_process_id, - int worker_route_id) { + SharedWorkerHost* worker_host) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - const WorkerId id(worker_process_id, worker_route_id); - AgentHostMap::iterator it = workers_.find(id); - if (it == workers_.end() || it->second->IsTerminated()) - return; - scoped_refptr<SharedWorkerDevToolsAgentHost> agent_host(it->second); + scoped_refptr<SharedWorkerDevToolsAgentHost> agent_host = + live_hosts_[worker_host]; + live_hosts_.erase(worker_host); + terminated_hosts_.insert(agent_host.get()); agent_host->WorkerDestroyed(); } -void SharedWorkerDevToolsManager::RemoveInspectedWorkerData(WorkerId id) { +void SharedWorkerDevToolsManager::AgentHostDestroyed( + SharedWorkerDevToolsAgentHost* agent_host) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - workers_.erase(id); + auto it = terminated_hosts_.find(agent_host); + // Might be missing during shutdown due to different + // destruction order of this manager, shared workers + // and their agent hosts. + if (it != terminated_hosts_.end()) + terminated_hosts_.erase(it); } + SharedWorkerDevToolsManager::SharedWorkerDevToolsManager() { } SharedWorkerDevToolsManager::~SharedWorkerDevToolsManager() { } -SharedWorkerDevToolsManager::AgentHostMap::iterator -SharedWorkerDevToolsManager::FindExistingWorkerAgentHost( - const SharedWorkerInstance& instance) { - AgentHostMap::iterator it = workers_.begin(); - for (; it != workers_.end(); ++it) { - if (it->second->Matches(instance)) - break; - } - return it; -} - -void SharedWorkerDevToolsManager::ResetForTesting() { - workers_.clear(); -} - - } // namespace content
diff --git a/content/browser/devtools/shared_worker_devtools_manager.h b/content/browser/devtools/shared_worker_devtools_manager.h index c7f4f7c..551d2ef 100644 --- a/content/browser/devtools/shared_worker_devtools_manager.h +++ b/content/browser/devtools/shared_worker_devtools_manager.h
@@ -7,6 +7,7 @@ #include <map> +#include "base/containers/flat_set.h" #include "base/gtest_prod_util.h" #include "base/macros.h" #include "base/memory/singleton.h" @@ -15,14 +16,12 @@ namespace content { class SharedWorkerDevToolsAgentHost; -class SharedWorkerInstance; +class SharedWorkerHost; // Manages WorkerDevToolsAgentHost's for Shared Workers. // This class lives on UI thread. class CONTENT_EXPORT SharedWorkerDevToolsManager { public: - using WorkerId = std::pair<int, int>; - // Returns the SharedWorkerDevToolsManager singleton. static SharedWorkerDevToolsManager* GetInstance(); @@ -31,12 +30,9 @@ // Returns true when the worker must be paused on start because a DevTool // window for the same former SharedWorkerInstance is still opened. - bool WorkerCreated(int worker_process_id, - int worker_route_id, - const SharedWorkerInstance& instance); - void WorkerReadyForInspection(int worker_process_id, int worker_route_id); - void WorkerDestroyed(int worker_process_id, int worker_route_id); - void RemoveInspectedWorkerData(WorkerId id); + bool WorkerCreated(SharedWorkerHost* worker_host); + void WorkerReadyForInspection(SharedWorkerHost* worker_host); + void WorkerDestroyed(SharedWorkerHost* worker_host); private: friend struct base::DefaultSingletonTraits<SharedWorkerDevToolsManager>; @@ -45,18 +41,17 @@ FRIEND_TEST_ALL_PREFIXES(SharedWorkerDevToolsManagerTest, BasicTest); FRIEND_TEST_ALL_PREFIXES(SharedWorkerDevToolsManagerTest, AttachTest); - using AgentHostMap = std::map<WorkerId, SharedWorkerDevToolsAgentHost*>; - SharedWorkerDevToolsManager(); ~SharedWorkerDevToolsManager(); + void AgentHostDestroyed(SharedWorkerDevToolsAgentHost* agent_host); - AgentHostMap::iterator FindExistingWorkerAgentHost( - const SharedWorkerInstance& instance); + // We retatin agent hosts as long as the shared worker is alive. + std::map<SharedWorkerHost*, scoped_refptr<SharedWorkerDevToolsAgentHost>> + live_hosts_; + // Clients may retain agent host for the terminated shared worker, + // and we reconnect them when shared worker is restarted. + base::flat_set<SharedWorkerDevToolsAgentHost*> terminated_hosts_; - // Resets to its initial state as if newly created. - void ResetForTesting(); - - AgentHostMap workers_; DISALLOW_COPY_AND_ASSIGN(SharedWorkerDevToolsManager); };
diff --git a/content/browser/devtools/shared_worker_devtools_manager_unittest.cc b/content/browser/devtools/shared_worker_devtools_manager_unittest.cc deleted file mode 100644 index 66c5747..0000000 --- a/content/browser/devtools/shared_worker_devtools_manager_unittest.cc +++ /dev/null
@@ -1,349 +0,0 @@ -// Copyright 2014 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 "content/browser/devtools/shared_worker_devtools_manager.h" - -#include <stddef.h> - -#include <memory> - -#include "base/macros.h" -#include "base/run_loop.h" -#include "content/browser/browser_thread_impl.h" -#include "content/browser/devtools/devtools_agent_host_impl.h" -#include "content/browser/devtools/shared_worker_devtools_agent_host.h" -#include "content/browser/devtools/worker_devtools_agent_host.h" -#include "content/browser/shared_worker/shared_worker_instance.h" -#include "content/browser/shared_worker/worker_storage_partition.h" -#include "content/public/browser/browser_context.h" -#include "content/public/browser/storage_partition.h" -#include "content/public/test/test_browser_context.h" -#include "content/public/test/test_browser_thread_bundle.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace content { -namespace { - -class TestDevToolsClientHost : public DevToolsAgentHostClient { - public: - TestDevToolsClientHost() {} - ~TestDevToolsClientHost() override {} - void DispatchProtocolMessage(DevToolsAgentHost* agent_host, - const std::string& message) override {} - void AgentHostClosed(DevToolsAgentHost* agent_host) override {} - - void InspectAgentHost(DevToolsAgentHost* agent_host) { - if (agent_host_.get()) - agent_host_->DetachClient(this); - agent_host_ = agent_host; - if (agent_host_.get()) - agent_host_->AttachClient(this); - } - private: - scoped_refptr<DevToolsAgentHost> agent_host_; - DISALLOW_COPY_AND_ASSIGN(TestDevToolsClientHost); -}; -} // namespace - -class SharedWorkerDevToolsManagerTest : public testing::Test { - public: - typedef SharedWorkerDevToolsAgentHost::WorkerState WorkerState; - - SharedWorkerDevToolsManagerTest() - : browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP), - browser_context_(new TestBrowserContext()), - partition_(new WorkerStoragePartition( - BrowserContext::GetDefaultStoragePartition(browser_context_.get()) - ->GetURLRequestContext(), - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr)), - partition_id_(*partition_.get()) {} - - protected: - void SetUp() override { - manager_ = SharedWorkerDevToolsManager::GetInstance(); - } - void TearDown() override { - SharedWorkerDevToolsManager::GetInstance()->ResetForTesting(); - } - - void CheckWorkerState(int worker_process_id, - int worker_route_id, - WorkerState state) { - SharedWorkerDevToolsAgentHost* host = - GetDevToolsAgentHostForWorker(worker_process_id, worker_route_id); - EXPECT_TRUE(!!host); - EXPECT_EQ(state, host->state_); - } - - void CheckWorkerNotExist(int worker_process_id, int worker_route_id) { - EXPECT_TRUE( - !GetDevToolsAgentHostForWorker(worker_process_id, worker_route_id)); - } - - void CheckWorkerCount(size_t size) { - EXPECT_EQ(size, manager_->workers_.size()); - } - - SharedWorkerDevToolsAgentHost* GetDevToolsAgentHostForWorker( - int worker_process_id, - int worker_route_id) { - const SharedWorkerDevToolsManager::WorkerId id(worker_process_id, - worker_route_id); - auto it = manager_->workers_.find(id); - return it == manager_->workers_.end() ? nullptr : it->second; - } - - TestBrowserThreadBundle browser_thread_bundle_; - std::unique_ptr<TestBrowserContext> browser_context_; - std::unique_ptr<WorkerStoragePartition> partition_; - const WorkerStoragePartitionId partition_id_; - SharedWorkerDevToolsManager* manager_; -}; - -TEST_F(SharedWorkerDevToolsManagerTest, BasicTest) { - scoped_refptr<DevToolsAgentHostImpl> agent_host; - - SharedWorkerInstance instance1( - GURL("http://example.com/w.js"), std::string(), - url::Origin::Create(GURL("http://example.com/")), std::string(), - blink::kWebContentSecurityPolicyTypeReport, blink::kWebAddressSpacePublic, - browser_context_->GetResourceContext(), partition_id_, - blink::mojom::SharedWorkerCreationContextType::kNonsecure, - base::UnguessableToken::Create()); - - agent_host = GetDevToolsAgentHostForWorker(1, 1); - EXPECT_FALSE(agent_host.get()); - - // Created -> Started -> Destroyed - CheckWorkerNotExist(1, 1); - manager_->WorkerCreated(1, 1, instance1); - CheckWorkerState(1, 1, WorkerState::WORKER_UNINSPECTED); - manager_->WorkerReadyForInspection(1, 1); - CheckWorkerState(1, 1, WorkerState::WORKER_UNINSPECTED); - manager_->WorkerDestroyed(1, 1); - CheckWorkerNotExist(1, 1); - - // Created -> GetDevToolsAgentHost -> Started -> Destroyed - CheckWorkerNotExist(1, 2); - manager_->WorkerCreated(1, 2, instance1); - CheckWorkerState(1, 2, WorkerState::WORKER_UNINSPECTED); - agent_host = GetDevToolsAgentHostForWorker(1, 2); - EXPECT_TRUE(agent_host.get()); - CheckWorkerState(1, 2, WorkerState::WORKER_UNINSPECTED); - EXPECT_EQ(agent_host.get(), GetDevToolsAgentHostForWorker(1, 2)); - manager_->WorkerReadyForInspection(1, 2); - CheckWorkerState(1, 2, WorkerState::WORKER_UNINSPECTED); - manager_->WorkerDestroyed(1, 2); - CheckWorkerState(1, 2, WorkerState::WORKER_TERMINATED); - agent_host = nullptr; - CheckWorkerNotExist(1, 2); - - // Created -> Started -> GetDevToolsAgentHost -> Destroyed - CheckWorkerNotExist(1, 3); - manager_->WorkerCreated(1, 3, instance1); - CheckWorkerState(1, 3, WorkerState::WORKER_UNINSPECTED); - manager_->WorkerReadyForInspection(1, 3); - CheckWorkerState(1, 3, WorkerState::WORKER_UNINSPECTED); - agent_host = GetDevToolsAgentHostForWorker(1, 3); - EXPECT_TRUE(agent_host.get()); - CheckWorkerState(1, 3, WorkerState::WORKER_UNINSPECTED); - manager_->WorkerDestroyed(1, 3); - CheckWorkerState(1, 3, WorkerState::WORKER_TERMINATED); - agent_host = nullptr; - CheckWorkerNotExist(1, 3); - - // Created -> Destroyed - CheckWorkerNotExist(1, 4); - manager_->WorkerCreated(1, 4, instance1); - CheckWorkerState(1, 4, WorkerState::WORKER_UNINSPECTED); - manager_->WorkerDestroyed(1, 4); - CheckWorkerNotExist(1, 4); - - // Created -> GetDevToolsAgentHost -> Destroyed - CheckWorkerNotExist(1, 5); - manager_->WorkerCreated(1, 5, instance1); - CheckWorkerState(1, 5, WorkerState::WORKER_UNINSPECTED); - agent_host = GetDevToolsAgentHostForWorker(1, 5); - EXPECT_TRUE(agent_host.get()); - CheckWorkerState(1, 5, WorkerState::WORKER_UNINSPECTED); - manager_->WorkerDestroyed(1, 5); - CheckWorkerState(1, 5, WorkerState::WORKER_TERMINATED); - agent_host = nullptr; - CheckWorkerNotExist(1, 5); - - // Created -> GetDevToolsAgentHost -> Free agent_host -> Destroyed - CheckWorkerNotExist(1, 6); - manager_->WorkerCreated(1, 6, instance1); - CheckWorkerState(1, 6, WorkerState::WORKER_UNINSPECTED); - agent_host = GetDevToolsAgentHostForWorker(1, 6); - EXPECT_TRUE(agent_host.get()); - CheckWorkerState(1, 6, WorkerState::WORKER_UNINSPECTED); - agent_host = nullptr; - manager_->WorkerDestroyed(1, 6); - CheckWorkerNotExist(1, 6); -} - -TEST_F(SharedWorkerDevToolsManagerTest, AttachTest) { - scoped_refptr<DevToolsAgentHostImpl> agent_host1; - scoped_refptr<DevToolsAgentHostImpl> agent_host2; - - SharedWorkerInstance instance1( - GURL("http://example.com/w1.js"), std::string(), - url::Origin::Create(GURL("http://example.com/")), std::string(), - blink::kWebContentSecurityPolicyTypeReport, blink::kWebAddressSpacePublic, - browser_context_->GetResourceContext(), partition_id_, - blink::mojom::SharedWorkerCreationContextType::kNonsecure, - base::UnguessableToken::Create()); - SharedWorkerInstance instance2( - GURL("http://example.com/w2.js"), std::string(), - url::Origin::Create(GURL("http://example.com/")), std::string(), - blink::kWebContentSecurityPolicyTypeReport, blink::kWebAddressSpacePublic, - browser_context_->GetResourceContext(), partition_id_, - blink::mojom::SharedWorkerCreationContextType::kNonsecure, - base::UnguessableToken::Create()); - - // Created -> GetDevToolsAgentHost -> Register -> Started -> Destroyed - std::unique_ptr<TestDevToolsClientHost> client_host1( - new TestDevToolsClientHost()); - CheckWorkerNotExist(2, 1); - manager_->WorkerCreated(2, 1, instance1); - CheckWorkerState(2, 1, WorkerState::WORKER_UNINSPECTED); - agent_host1 = GetDevToolsAgentHostForWorker(2, 1); - EXPECT_TRUE(agent_host1.get()); - CheckWorkerState(2, 1, WorkerState::WORKER_UNINSPECTED); - EXPECT_EQ(agent_host1.get(), GetDevToolsAgentHostForWorker(2, 1)); - client_host1->InspectAgentHost(agent_host1.get()); - CheckWorkerState(2, 1, WorkerState::WORKER_INSPECTED); - manager_->WorkerReadyForInspection(2, 1); - CheckWorkerState(2, 1, WorkerState::WORKER_INSPECTED); - manager_->WorkerDestroyed(2, 1); - CheckWorkerState(2, 1, WorkerState::WORKER_TERMINATED); - EXPECT_EQ(agent_host1.get(), GetDevToolsAgentHostForWorker(2, 1)); - - // Created -> Started -> GetDevToolsAgentHost -> Register -> Destroyed - std::unique_ptr<TestDevToolsClientHost> client_host2( - new TestDevToolsClientHost()); - manager_->WorkerCreated(2, 2, instance2); - CheckWorkerState(2, 2, WorkerState::WORKER_UNINSPECTED); - manager_->WorkerReadyForInspection(2, 2); - CheckWorkerState(2, 2, WorkerState::WORKER_UNINSPECTED); - agent_host2 = GetDevToolsAgentHostForWorker(2, 2); - EXPECT_TRUE(agent_host2.get()); - EXPECT_NE(agent_host1.get(), agent_host2.get()); - EXPECT_EQ(agent_host2.get(), GetDevToolsAgentHostForWorker(2, 2)); - CheckWorkerState(2, 2, WorkerState::WORKER_UNINSPECTED); - client_host2->InspectAgentHost(agent_host2.get()); - CheckWorkerState(2, 2, WorkerState::WORKER_INSPECTED); - manager_->WorkerDestroyed(2, 2); - CheckWorkerState(2, 2, WorkerState::WORKER_TERMINATED); - EXPECT_EQ(agent_host2.get(), GetDevToolsAgentHostForWorker(2, 2)); - - // Re-created -> Started -> ClientHostClosing -> Destroyed - CheckWorkerState(2, 1, WorkerState::WORKER_TERMINATED); - manager_->WorkerCreated(2, 3, instance1); - CheckWorkerNotExist(2, 1); - CheckWorkerState(2, 3, WorkerState::WORKER_PAUSED_FOR_REATTACH); - EXPECT_EQ(agent_host1.get(), GetDevToolsAgentHostForWorker(2, 3)); - manager_->WorkerReadyForInspection(2, 3); - CheckWorkerState(2, 3, WorkerState::WORKER_INSPECTED); - client_host1->InspectAgentHost(nullptr); - manager_->WorkerDestroyed(2, 3); - CheckWorkerState(2, 3, WorkerState::WORKER_TERMINATED); - agent_host1 = nullptr; - CheckWorkerNotExist(2, 3); - - // Re-created -> Destroyed - CheckWorkerState(2, 2, WorkerState::WORKER_TERMINATED); - manager_->WorkerCreated(2, 4, instance2); - CheckWorkerNotExist(2, 2); - CheckWorkerState(2, 4, WorkerState::WORKER_PAUSED_FOR_REATTACH); - EXPECT_EQ(agent_host2.get(), GetDevToolsAgentHostForWorker(2, 4)); - manager_->WorkerDestroyed(2, 4); - CheckWorkerNotExist(2, 2); - CheckWorkerState(2, 4, WorkerState::WORKER_TERMINATED); - - // Re-created -> ClientHostClosing -> Destroyed - manager_->WorkerCreated(2, 5, instance2); - CheckWorkerNotExist(2, 2); - CheckWorkerState(2, 5, WorkerState::WORKER_PAUSED_FOR_REATTACH); - EXPECT_EQ(agent_host2.get(), GetDevToolsAgentHostForWorker(2, 5)); - client_host2->InspectAgentHost(nullptr); - CheckWorkerCount(1); - agent_host2 = nullptr; - CheckWorkerCount(1); - manager_->WorkerDestroyed(2, 5); - CheckWorkerCount(0); -} - -TEST_F(SharedWorkerDevToolsManagerTest, ReattachTest) { - SharedWorkerInstance instance( - GURL("http://example.com/w3.js"), std::string(), - url::Origin::Create(GURL("http://example.com/")), std::string(), - blink::kWebContentSecurityPolicyTypeReport, blink::kWebAddressSpacePublic, - browser_context_->GetResourceContext(), partition_id_, - blink::mojom::SharedWorkerCreationContextType::kNonsecure, - base::UnguessableToken::Create()); - std::unique_ptr<TestDevToolsClientHost> client_host( - new TestDevToolsClientHost()); - // Created -> GetDevToolsAgentHost -> Register -> Destroyed - manager_->WorkerCreated(3, 1, instance); - CheckWorkerState(3, 1, WorkerState::WORKER_UNINSPECTED); - scoped_refptr<DevToolsAgentHost> agent_host( - GetDevToolsAgentHostForWorker(3, 1)); - EXPECT_TRUE(agent_host.get()); - CheckWorkerState(3, 1, WorkerState::WORKER_UNINSPECTED); - client_host->InspectAgentHost(agent_host.get()); - CheckWorkerState(3, 1, WorkerState::WORKER_INSPECTED); - manager_->WorkerDestroyed(3, 1); - CheckWorkerState(3, 1, WorkerState::WORKER_TERMINATED); - // ClientHostClosing -> Re-created -> release agent_host -> Destroyed - client_host->InspectAgentHost(nullptr); - CheckWorkerState(3, 1, WorkerState::WORKER_TERMINATED); - manager_->WorkerCreated(3, 2, instance); - CheckWorkerState(3, 2, WorkerState::WORKER_UNINSPECTED); - agent_host = nullptr; - CheckWorkerState(3, 2, WorkerState::WORKER_UNINSPECTED); - manager_->WorkerDestroyed(3, 2); - CheckWorkerNotExist(3, 2); - CheckWorkerCount(0); -} - -TEST_F(SharedWorkerDevToolsManagerTest, PauseOnStartTest) { - SharedWorkerInstance instance( - GURL("http://example.com/w3.js"), std::string(), - url::Origin::Create(GURL("http://example.com/")), std::string(), - blink::kWebContentSecurityPolicyTypeReport, blink::kWebAddressSpacePublic, - browser_context_->GetResourceContext(), partition_id_, - blink::mojom::SharedWorkerCreationContextType::kNonsecure, - base::UnguessableToken::Create()); - std::unique_ptr<TestDevToolsClientHost> client_host( - new TestDevToolsClientHost()); - manager_->WorkerCreated(3, 1, instance); - CheckWorkerState(3, 1, WorkerState::WORKER_UNINSPECTED); - scoped_refptr<SharedWorkerDevToolsAgentHost> agent_host( - GetDevToolsAgentHostForWorker(3, 1)); - EXPECT_TRUE(agent_host.get()); - CheckWorkerState(3, 1, WorkerState::WORKER_UNINSPECTED); - agent_host->PauseForDebugOnStart(); - CheckWorkerState(3, 1, WorkerState::WORKER_PAUSED_FOR_DEBUG_ON_START); - EXPECT_FALSE(agent_host->IsReadyForInspection()); - manager_->WorkerReadyForInspection(3, 1); - CheckWorkerState(3, 1, WorkerState::WORKER_READY_FOR_DEBUG_ON_START); - client_host->InspectAgentHost(agent_host.get()); - CheckWorkerState(3, 1, WorkerState::WORKER_INSPECTED); - client_host->InspectAgentHost(nullptr); - agent_host = nullptr; - CheckWorkerState(3, 1, WorkerState::WORKER_UNINSPECTED); - manager_->WorkerDestroyed(3, 1); - CheckWorkerNotExist(3, 1); - CheckWorkerCount(0); -} - -} // namespace content
diff --git a/content/browser/frame_host/frame_navigation_entry.cc b/content/browser/frame_host/frame_navigation_entry.cc index 2ecfb5d..608c490 100644 --- a/content/browser/frame_host/frame_navigation_entry.cc +++ b/content/browser/frame_host/frame_navigation_entry.cc
@@ -8,7 +8,6 @@ #include "base/strings/utf_string_conversions.h" #include "content/common/page_state_serialization.h" -#include "content/common/site_isolation_policy.h" namespace content {
diff --git a/content/browser/frame_host/frame_tree.cc b/content/browser/frame_host/frame_tree.cc index f7ac86c..30f104e 100644 --- a/content/browser/frame_host/frame_tree.cc +++ b/content/browser/frame_host/frame_tree.cc
@@ -28,7 +28,6 @@ #include "content/common/content_switches_internal.h" #include "content/common/frame_owner_properties.h" #include "content/common/input_messages.h" -#include "content/common/site_isolation_policy.h" #include "third_party/WebKit/common/frame_policy.h" namespace content {
diff --git a/content/browser/frame_host/frame_tree_node.cc b/content/browser/frame_host/frame_tree_node.cc index 8990d03..c66ae70 100644 --- a/content/browser/frame_host/frame_tree_node.cc +++ b/content/browser/frame_host/frame_tree_node.cc
@@ -22,7 +22,6 @@ #include "content/browser/frame_host/render_frame_host_impl.h" #include "content/browser/renderer_host/render_view_host_impl.h" #include "content/common/frame_messages.h" -#include "content/common/site_isolation_policy.h" #include "content/public/browser/browser_thread.h" #include "content/public/common/browser_side_navigation_policy.h" #include "third_party/WebKit/common/sandbox_flags.h"
diff --git a/content/browser/frame_host/navigation_controller_impl.cc b/content/browser/frame_host/navigation_controller_impl.cc index a5ac096..a289937 100644 --- a/content/browser/frame_host/navigation_controller_impl.cc +++ b/content/browser/frame_host/navigation_controller_impl.cc
@@ -62,7 +62,6 @@ #include "content/browser/renderer_host/render_view_host_impl.h" // Temporary #include "content/browser/site_instance_impl.h" #include "content/common/frame_messages.h" -#include "content/common/site_isolation_policy.h" #include "content/common/view_messages.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/content_browser_client.h" @@ -687,7 +686,7 @@ default: NOTREACHED(); break; - }; + } // The user initiated a load, we don't need to reload anymore. needs_reload_ = false; @@ -785,7 +784,7 @@ default: NOTREACHED(); break; - }; + } entry->set_started_from_context_menu(params.started_from_context_menu); LoadEntry(std::move(entry));
diff --git a/content/browser/frame_host/navigation_controller_impl_browsertest.cc b/content/browser/frame_host/navigation_controller_impl_browsertest.cc index 69cdeea0..7a68e30 100644 --- a/content/browser/frame_host/navigation_controller_impl_browsertest.cc +++ b/content/browser/frame_host/navigation_controller_impl_browsertest.cc
@@ -29,7 +29,6 @@ #include "content/browser/web_contents/web_contents_impl.h" #include "content/common/frame_messages.h" #include "content/common/page_state_serialization.h" -#include "content/common/site_isolation_policy.h" #include "content/public/browser/navigation_controller.h" #include "content/public/browser/render_view_host.h" #include "content/public/browser/resource_dispatcher_host.h"
diff --git a/content/browser/frame_host/navigation_controller_impl_unittest.cc b/content/browser/frame_host/navigation_controller_impl_unittest.cc index 7024ee4..c94bb2fd 100644 --- a/content/browser/frame_host/navigation_controller_impl_unittest.cc +++ b/content/browser/frame_host/navigation_controller_impl_unittest.cc
@@ -32,7 +32,6 @@ #include "content/browser/web_contents/web_contents_impl.h" #include "content/common/frame_messages.h" #include "content/common/frame_owner_properties.h" -#include "content/common/site_isolation_policy.h" #include "content/common/view_messages.h" #include "content/public/browser/render_view_host.h" #include "content/public/browser/web_contents_delegate.h"
diff --git a/content/browser/frame_host/navigation_entry_impl.cc b/content/browser/frame_host/navigation_entry_impl.cc index aadd134..20bb33c 100644 --- a/content/browser/frame_host/navigation_entry_impl.cc +++ b/content/browser/frame_host/navigation_entry_impl.cc
@@ -22,7 +22,6 @@ #include "content/common/content_constants_internal.h" #include "content/common/navigation_params.h" #include "content/common/page_state_serialization.h" -#include "content/common/site_isolation_policy.h" #include "content/public/browser/reload_type.h" #include "content/public/common/browser_side_navigation_policy.h" #include "content/public/common/content_constants.h"
diff --git a/content/browser/frame_host/navigation_handle_impl.cc b/content/browser/frame_host/navigation_handle_impl.cc index 73afa8b3..b49aa497 100644 --- a/content/browser/frame_host/navigation_handle_impl.cc +++ b/content/browser/frame_host/navigation_handle_impl.cc
@@ -27,7 +27,6 @@ #include "content/browser/service_worker/service_worker_navigation_handle.h" #include "content/common/child_process_host_impl.h" #include "content/common/frame_messages.h" -#include "content/common/site_isolation_policy.h" #include "content/public/browser/content_browser_client.h" #include "content/public/browser/navigation_ui_data.h" #include "content/public/browser/site_instance.h"
diff --git a/content/browser/frame_host/navigator_impl.cc b/content/browser/frame_host/navigator_impl.cc index c6f7420..2858d64 100644 --- a/content/browser/frame_host/navigator_impl.cc +++ b/content/browser/frame_host/navigator_impl.cc
@@ -28,7 +28,6 @@ #include "content/common/frame_messages.h" #include "content/common/navigation_params.h" #include "content/common/page_messages.h" -#include "content/common/site_isolation_policy.h" #include "content/common/view_messages.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/content_browser_client.h"
diff --git a/content/browser/frame_host/navigator_impl_unittest.cc b/content/browser/frame_host/navigator_impl_unittest.cc index 05d8ab6..668680a 100644 --- a/content/browser/frame_host/navigator_impl_unittest.cc +++ b/content/browser/frame_host/navigator_impl_unittest.cc
@@ -20,7 +20,6 @@ #include "content/common/frame.mojom.h" #include "content/common/frame_messages.h" #include "content/common/navigation_params.h" -#include "content/common/site_isolation_policy.h" #include "content/public/browser/navigation_data.h" #include "content/public/browser/stream_handle.h" #include "content/public/common/content_features.h"
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc index 5202167e..bfd01a7 100644 --- a/content/browser/frame_host/render_frame_host_impl.cc +++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -95,7 +95,6 @@ #include "content/common/navigation_subresource_loader_params.h" #include "content/common/render_message_filter.mojom.h" #include "content/common/renderer.mojom.h" -#include "content/common/site_isolation_policy.h" #include "content/common/swapped_out_messages.h" #include "content/common/url_loader_factory_bundle.mojom.h" #include "content/common/widget.mojom.h"
diff --git a/content/browser/frame_host/render_frame_host_manager.cc b/content/browser/frame_host/render_frame_host_manager.cc index 53b0f5b..99b3b01a 100644 --- a/content/browser/frame_host/render_frame_host_manager.cc +++ b/content/browser/frame_host/render_frame_host_manager.cc
@@ -35,10 +35,10 @@ #include "content/browser/renderer_host/render_view_host_factory.h" #include "content/browser/renderer_host/render_view_host_impl.h" #include "content/browser/site_instance_impl.h" +#include "content/browser/site_isolation_policy.h" #include "content/browser/webui/web_ui_controller_factory_registry.h" #include "content/common/frame_messages.h" #include "content/common/frame_owner_properties.h" -#include "content/common/site_isolation_policy.h" #include "content/common/view_messages.h" #include "content/public/browser/child_process_security_policy.h" #include "content/public/browser/content_browser_client.h"
diff --git a/content/browser/frame_host/render_frame_host_manager_browsertest.cc b/content/browser/frame_host/render_frame_host_manager_browsertest.cc index a827e02..e8028dcf 100644 --- a/content/browser/frame_host/render_frame_host_manager_browsertest.cc +++ b/content/browser/frame_host/render_frame_host_manager_browsertest.cc
@@ -30,7 +30,6 @@ #include "content/browser/webui/web_ui_impl.h" #include "content/common/content_constants_internal.h" #include "content/common/input_messages.h" -#include "content/common/site_isolation_policy.h" #include "content/public/browser/navigation_controller.h" #include "content/public/browser/navigation_entry.h" #include "content/public/browser/render_process_host.h"
diff --git a/content/browser/frame_host/render_frame_host_manager_unittest.cc b/content/browser/frame_host/render_frame_host_manager_unittest.cc index 334e84d..c38b650 100644 --- a/content/browser/frame_host/render_frame_host_manager_unittest.cc +++ b/content/browser/frame_host/render_frame_host_manager_unittest.cc
@@ -31,7 +31,6 @@ #include "content/common/frame_messages.h" #include "content/common/frame_owner_properties.h" #include "content/common/input_messages.h" -#include "content/common/site_isolation_policy.h" #include "content/common/view_messages.h" #include "content/public/browser/notification_details.h" #include "content/public/browser/notification_service.h"
diff --git a/content/browser/frame_host/render_widget_host_view_guest.cc b/content/browser/frame_host/render_widget_host_view_guest.cc index cd752be..6b134951 100644 --- a/content/browser/frame_host/render_widget_host_view_guest.cc +++ b/content/browser/frame_host/render_widget_host_view_guest.cc
@@ -28,7 +28,6 @@ #include "content/common/content_switches_internal.h" #include "content/common/frame_messages.h" #include "content/common/input/web_touch_event_traits.h" -#include "content/common/site_isolation_policy.h" #include "content/common/view_messages.h" #include "content/public/common/content_switches.h" #include "gpu/ipc/common/gpu_messages.h"
diff --git a/content/browser/loader/resource_dispatcher_host_impl.cc b/content/browser/loader/resource_dispatcher_host_impl.cc index 0475d83..336cd11 100644 --- a/content/browser/loader/resource_dispatcher_host_impl.cc +++ b/content/browser/loader/resource_dispatcher_host_impl.cc
@@ -68,13 +68,13 @@ #include "content/browser/service_worker/service_worker_context_wrapper.h" #include "content/browser/service_worker/service_worker_navigation_handle_core.h" #include "content/browser/service_worker/service_worker_request_handler.h" +#include "content/browser/site_isolation_policy.h" #include "content/browser/streams/stream.h" #include "content/browser/streams/stream_context.h" #include "content/browser/streams/stream_registry.h" #include "content/common/loader_util.h" #include "content/common/net/url_request_service_worker_data.h" #include "content/common/resource_messages.h" -#include "content/common/site_isolation_policy.h" #include "content/common/view_messages.h" #include "content/public/browser/browser_child_process_host.h" #include "content/public/browser/browser_thread.h"
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index f8c24b4..4107667 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -132,6 +132,7 @@ #include "content/browser/service_worker/service_worker_context_wrapper.h" #include "content/browser/service_worker/service_worker_dispatcher_host.h" #include "content/browser/site_instance_impl.h" +#include "content/browser/site_isolation_policy.h" #include "content/browser/speech/speech_recognition_dispatcher_host.h" #include "content/browser/storage_partition_impl.h" #include "content/browser/streams/stream_context.h" @@ -146,7 +147,6 @@ #include "content/common/resource_messages.h" #include "content/common/service_manager/child_connection.h" #include "content/common/service_manager/service_manager_connection_impl.h" -#include "content/common/site_isolation_policy.h" #include "content/common/view_messages.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_thread.h"
diff --git a/content/browser/renderer_host/render_view_host_impl.cc b/content/browser/renderer_host/render_view_host_impl.cc index bf19ad4..b83591e 100644 --- a/content/browser/renderer_host/render_view_host_impl.cc +++ b/content/browser/renderer_host/render_view_host_impl.cc
@@ -50,7 +50,6 @@ #include "content/common/inter_process_time_ticks_converter.h" #include "content/common/render_message_filter.mojom.h" #include "content/common/renderer.mojom.h" -#include "content/common/site_isolation_policy.h" #include "content/common/speech_recognition_messages.h" #include "content/common/swapped_out_messages.h" #include "content/common/view_messages.h"
diff --git a/content/browser/renderer_host/render_widget_host_view_android.cc b/content/browser/renderer_host/render_widget_host_view_android.cc index b12edad..439e96d1 100644 --- a/content/browser/renderer_host/render_widget_host_view_android.cc +++ b/content/browser/renderer_host/render_widget_host_view_android.cc
@@ -67,7 +67,6 @@ #include "content/common/content_switches_internal.h" #include "content/common/gpu_stream_constants.h" #include "content/common/input_messages.h" -#include "content/common/site_isolation_policy.h" #include "content/common/view_messages.h" #include "content/public/browser/android/compositor.h" #include "content/public/browser/android/synchronous_compositor_client.h"
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc index 3adf96ed..89040091 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura.cc +++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
@@ -50,7 +50,6 @@ #include "content/common/content_switches_internal.h" #include "content/common/input_messages.h" #include "content/common/render_widget_window_tree_client_factory.mojom.h" -#include "content/common/site_isolation_policy.h" #include "content/common/text_input_state.h" #include "content/common/view_messages.h" #include "content/public/browser/content_browser_client.h"
diff --git a/content/browser/renderer_host/render_widget_host_view_event_handler.cc b/content/browser/renderer_host/render_widget_host_view_event_handler.cc index 50f0b90..d4b41dd4e 100644 --- a/content/browser/renderer_host/render_widget_host_view_event_handler.cc +++ b/content/browser/renderer_host/render_widget_host_view_event_handler.cc
@@ -15,7 +15,6 @@ #include "content/browser/renderer_host/render_widget_host_view_base.h" #include "content/browser/renderer_host/text_input_manager.h" #include "content/common/content_switches_internal.h" -#include "content/common/site_isolation_policy.h" #include "content/public/browser/render_view_host.h" #include "content/public/browser/render_widget_host.h" #include "content/public/common/content_features.h"
diff --git a/content/browser/renderer_host/render_widget_host_view_mac.mm b/content/browser/renderer_host/render_widget_host_view_mac.mm index d080dd0..dcc489c 100644 --- a/content/browser/renderer_host/render_widget_host_view_mac.mm +++ b/content/browser/renderer_host/render_widget_host_view_mac.mm
@@ -56,7 +56,6 @@ #include "content/common/accessibility_messages.h" #include "content/common/edit_command.h" #include "content/common/input_messages.h" -#include "content/common/site_isolation_policy.h" #include "content/common/text_input_state.h" #include "content/common/view_messages.h" #include "content/public/browser/browser_context.h"
diff --git a/content/browser/shared_worker/shared_worker_host.cc b/content/browser/shared_worker/shared_worker_host.cc index 6b09861..5d0f4580 100644 --- a/content/browser/shared_worker/shared_worker_host.cc +++ b/content/browser/shared_worker/shared_worker_host.cc
@@ -70,10 +70,8 @@ SharedWorkerHost::~SharedWorkerHost() { UMA_HISTOGRAM_LONG_TIMES("SharedWorker.TimeToDeleted", base::TimeTicks::Now() - creation_time_); - if (!closed_ && !termination_message_sent_) { - SharedWorkerDevToolsManager::GetInstance()->WorkerDestroyed(process_id_, - route_id_); - } + if (!closed_ && !termination_message_sent_) + SharedWorkerDevToolsManager::GetInstance()->WorkerDestroyed(this); } void SharedWorkerHost::Start(mojom::SharedWorkerFactoryPtr factory, @@ -127,11 +125,12 @@ } void SharedWorkerHost::TerminateWorker() { + // This can be called twice in tests while cleaning up all the workers. + if (termination_message_sent_) + return; termination_message_sent_ = true; - if (!closed_) { - SharedWorkerDevToolsManager::GetInstance()->WorkerDestroyed(process_id_, - route_id_); - } + if (!closed_) + SharedWorkerDevToolsManager::GetInstance()->WorkerDestroyed(this); worker_->Terminate(); // Now, we wait to observe OnWorkerConnectionLost. } @@ -164,15 +163,13 @@ // being sent to the worker (messages can still be sent from the worker, // for exception reporting, etc). closed_ = true; - if (!termination_message_sent_) { - SharedWorkerDevToolsManager::GetInstance()->WorkerDestroyed(process_id_, - route_id_); - } + if (!termination_message_sent_) + SharedWorkerDevToolsManager::GetInstance()->WorkerDestroyed(this); } void SharedWorkerHost::OnReadyForInspection() { - SharedWorkerDevToolsManager::GetInstance()->WorkerReadyForInspection( - process_id_, route_id_); + if (!closed_ && !termination_message_sent_) + SharedWorkerDevToolsManager::GetInstance()->WorkerReadyForInspection(this); } void SharedWorkerHost::OnScriptLoaded() {
diff --git a/content/browser/shared_worker/shared_worker_service_impl.cc b/content/browser/shared_worker/shared_worker_service_impl.cc index ecf29e78..5ed5c0b 100644 --- a/content/browser/shared_worker/shared_worker_service_impl.cc +++ b/content/browser/shared_worker/shared_worker_service_impl.cc
@@ -87,15 +87,6 @@ return false; } -bool SharedWorkerServiceImpl::TerminateWorkerById(int process_id, - int route_id) { - SharedWorkerHost* host = FindSharedWorkerHost(process_id, route_id); - if (!host || !host->instance()) - return false; - host->TerminateWorker(); - return true; -} - void SharedWorkerServiceImpl::TerminateAllWorkersForTesting( base::OnceClosure callback) { DCHECK_CURRENTLY_ON(BrowserThread::UI); @@ -210,13 +201,12 @@ // Dev Tools will need to be modified to use something else as an identifier. int worker_route_id = process_host->GetNextRoutingID(); - bool pause_on_start = - SharedWorkerDevToolsManager::GetInstance()->WorkerCreated( - worker_process_id, worker_route_id, *instance); - auto host = std::make_unique<SharedWorkerHost>( std::move(instance), worker_process_id, worker_route_id); + bool pause_on_start = + SharedWorkerDevToolsManager::GetInstance()->WorkerCreated(host.get()); + // Get the factory used to instantiate the new shared worker instance in // the target process. mojom::SharedWorkerFactoryPtr factory;
diff --git a/content/browser/shared_worker/shared_worker_service_impl.h b/content/browser/shared_worker/shared_worker_service_impl.h index ce7d66db..e634b61 100644 --- a/content/browser/shared_worker/shared_worker_service_impl.h +++ b/content/browser/shared_worker/shared_worker_service_impl.h
@@ -40,8 +40,6 @@ StoragePartition* storage_partition, ResourceContext* resource_context) override; - // Terminates the given worker. Returns true if the process was found. - bool TerminateWorkerById(int process_id, int route_id); void TerminateAllWorkersForTesting(base::OnceClosure callback); // Creates the worker if necessary or connects to an already existing worker.
diff --git a/content/browser/site_instance_impl.cc b/content/browser/site_instance_impl.cc index 827e674c..75aee7d 100644 --- a/content/browser/site_instance_impl.cc +++ b/content/browser/site_instance_impl.cc
@@ -13,8 +13,8 @@ #include "content/browser/frame_host/debug_urls.h" #include "content/browser/frame_host/frame_tree_node.h" #include "content/browser/renderer_host/render_process_host_impl.h" +#include "content/browser/site_isolation_policy.h" #include "content/browser/storage_partition_impl.h" -#include "content/common/site_isolation_policy.h" #include "content/public/browser/content_browser_client.h" #include "content/public/browser/render_process_host_factory.h" #include "content/public/browser/web_ui_controller_factory.h"
diff --git a/content/common/site_isolation_policy.cc b/content/browser/site_isolation_policy.cc similarity index 75% rename from content/common/site_isolation_policy.cc rename to content/browser/site_isolation_policy.cc index 0d277b0..eec976c1 100644 --- a/content/common/site_isolation_policy.cc +++ b/content/browser/site_isolation_policy.cc
@@ -2,14 +2,19 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "content/common/site_isolation_policy.h" +#include "content/browser/site_isolation_policy.h" +#include <algorithm> +#include <iterator> #include <string> +#include <utility> #include "base/command_line.h" #include "base/feature_list.h" #include "base/metrics/field_trial_params.h" #include "base/strings/string_split.h" +#include "content/public/browser/content_browser_client.h" +#include "content/public/common/content_client.h" #include "content/public/common/content_features.h" #include "content/public/common/content_switches.h" #include "url/gurl.h" @@ -40,7 +45,8 @@ } // static -std::vector<url::Origin> SiteIsolationPolicy::GetIsolatedOrigins() { +std::vector<url::Origin> +SiteIsolationPolicy::GetIsolatedOriginsFromEnvironment() { std::string cmdline_arg = base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( switches::kIsolateOrigins); @@ -58,6 +64,20 @@ } // static +std::vector<url::Origin> SiteIsolationPolicy::GetIsolatedOrigins() { + std::vector<url::Origin> from_environment = + GetIsolatedOriginsFromEnvironment(); + std::vector<url::Origin> from_embedder = + GetContentClient()->browser()->GetOriginsRequiringDedicatedProcess(); + + std::vector<url::Origin> result = std::move(from_environment); + result.reserve(result.size() + from_embedder.size()); + std::move(from_embedder.begin(), from_embedder.end(), + std::back_inserter(result)); + return result; +} + +// static std::vector<url::Origin> SiteIsolationPolicy::ParseIsolatedOrigins( base::StringPiece arg) { std::vector<base::StringPiece> origin_strings = base::SplitStringPiece(
diff --git a/content/common/site_isolation_policy.h b/content/browser/site_isolation_policy.h similarity index 82% rename from content/common/site_isolation_policy.h rename to content/browser/site_isolation_policy.h index 44afe7d..5662adf 100644 --- a/content/common/site_isolation_policy.h +++ b/content/browser/site_isolation_policy.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CONTENT_COMMON_SITE_ISOLATION_POLICY_H_ -#define CONTENT_COMMON_SITE_ISOLATION_POLICY_H_ +#ifndef CONTENT_BROWSER_SITE_ISOLATION_POLICY_H_ +#define CONTENT_BROWSER_SITE_ISOLATION_POLICY_H_ #include <vector> @@ -36,19 +36,21 @@ // Returns the origins to isolate. See also AreIsolatedOriginsEnabled. // This list applies globally to the whole browser in all profiles. - // TODO(lukasza): Make sure this list also includes the origins returned by - // ContentBrowserClient::GetOriginsRequiringDedicatedProcess. static std::vector<url::Origin> GetIsolatedOrigins(); private: SiteIsolationPolicy(); // Not instantiable. - FRIEND_TEST_ALL_PREFIXES(SiteIsolationPolicyTest, ParseIsolatedOrigins); + // Parses |arg| into a list of origins. static std::vector<url::Origin> ParseIsolatedOrigins(base::StringPiece arg); + FRIEND_TEST_ALL_PREFIXES(SiteIsolationPolicyTest, ParseIsolatedOrigins); + + // Gets isolated origins from cmdline and/or from field trial param. + static std::vector<url::Origin> GetIsolatedOriginsFromEnvironment(); DISALLOW_COPY_AND_ASSIGN(SiteIsolationPolicy); }; } // namespace content -#endif // CONTENT_COMMON_SITE_ISOLATION_POLICY_H_ +#endif // CONTENT_BROWSER_SITE_ISOLATION_POLICY_H_
diff --git a/content/common/site_isolation_policy_unittest.cc b/content/browser/site_isolation_policy_unittest.cc similarity index 97% rename from content/common/site_isolation_policy_unittest.cc rename to content/browser/site_isolation_policy_unittest.cc index b3935e6..a60ec5d 100644 --- a/content/common/site_isolation_policy_unittest.cc +++ b/content/browser/site_isolation_policy_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "content/common/site_isolation_policy.h" +#include "content/browser/site_isolation_policy.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h"
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index f22cf700..e9ce6b0 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc
@@ -86,7 +86,6 @@ #include "content/common/page_messages.h" #include "content/common/page_state_serialization.h" #include "content/common/render_message_filter.mojom.h" -#include "content/common/site_isolation_policy.h" #include "content/common/view_messages.h" #include "content/public/browser/ax_event_notification_details.h" #include "content/public/browser/browser_context.h"
diff --git a/content/browser/web_contents/web_contents_impl_browsertest.cc b/content/browser/web_contents/web_contents_impl_browsertest.cc index 3ad3a9f..ac45c08d 100644 --- a/content/browser/web_contents/web_contents_impl_browsertest.cc +++ b/content/browser/web_contents/web_contents_impl_browsertest.cc
@@ -16,7 +16,6 @@ #include "content/browser/web_contents/web_contents_impl.h" #include "content/browser/web_contents/web_contents_view.h" #include "content/common/frame_messages.h" -#include "content/common/site_isolation_policy.h" #include "content/public/browser/javascript_dialog_manager.h" #include "content/public/browser/load_notification_details.h" #include "content/public/browser/navigation_controller.h"
diff --git a/content/browser/web_contents/web_contents_impl_unittest.cc b/content/browser/web_contents/web_contents_impl_unittest.cc index 183999c9..0cc629a 100644 --- a/content/browser/web_contents/web_contents_impl_unittest.cc +++ b/content/browser/web_contents/web_contents_impl_unittest.cc
@@ -24,7 +24,6 @@ #include "content/common/frame_messages.h" #include "content/common/input/synthetic_web_input_event_builders.h" #include "content/common/media/media_player_delegate_messages.h" -#include "content/common/site_isolation_policy.h" #include "content/common/view_messages.h" #include "content/public/browser/content_browser_client.h" #include "content/public/browser/download_url_parameters.h"
diff --git a/content/common/BUILD.gn b/content/common/BUILD.gn index 29cc2d2..56586fc0 100644 --- a/content/common/BUILD.gn +++ b/content/common/BUILD.gn
@@ -292,8 +292,6 @@ "service_worker/service_worker_types.h", "service_worker/service_worker_utils.cc", "service_worker/service_worker_utils.h", - "site_isolation_policy.cc", - "site_isolation_policy.h", "speech_recognition_messages.h", "swapped_out_messages.cc", "swapped_out_messages.h",
diff --git a/content/public/test/test_utils.cc b/content/public/test/test_utils.cc index 2784313..6efe48c 100644 --- a/content/public/test/test_utils.cc +++ b/content/public/test/test_utils.cc
@@ -21,7 +21,6 @@ #include "base/values.h" #include "build/build_config.h" #include "components/variations/variations_params_manager.h" -#include "content/common/site_isolation_policy.h" #include "content/common/url_schemes.h" #include "content/public/browser/browser_child_process_host_iterator.h" #include "content/public/browser/notification_service.h"
diff --git a/content/renderer/accessibility/render_accessibility_impl_browsertest.cc b/content/renderer/accessibility/render_accessibility_impl_browsertest.cc index a9bdd34..4da5dec 100644 --- a/content/renderer/accessibility/render_accessibility_impl_browsertest.cc +++ b/content/renderer/accessibility/render_accessibility_impl_browsertest.cc
@@ -10,7 +10,6 @@ #include "build/build_config.h" #include "content/common/accessibility_messages.h" #include "content/common/frame_messages.h" -#include "content/common/site_isolation_policy.h" #include "content/common/view_message_enums.h" #include "content/public/common/content_switches.h" #include "content/public/test/render_view_test.h"
diff --git a/content/renderer/device_sensors/device_orientation_event_pump.cc b/content/renderer/device_sensors/device_orientation_event_pump.cc index 0905e17..22a1428 100644 --- a/content/renderer/device_sensors/device_orientation_event_pump.cc +++ b/content/renderer/device_sensors/device_orientation_event_pump.cc
@@ -137,7 +137,7 @@ void DeviceOrientationEventPump::DidStartIfPossible() { if (!absolute_ && !relative_orientation_sensor_.sensor && - fall_back_to_absolute_orientation_sensor_) { + fall_back_to_absolute_orientation_sensor_ && sensor_provider_) { // When relative orientation sensor is not available fall back to using // the absolute orientation sensor but only on the first failure. fall_back_to_absolute_orientation_sensor_ = false;
diff --git a/content/renderer/media/user_media_processor.cc b/content/renderer/media/user_media_processor.cc index d5c65a2..7faa066 100644 --- a/content/renderer/media/user_media_processor.cc +++ b/content/renderer/media/user_media_processor.cc
@@ -456,14 +456,7 @@ GetUserMediaRequestFailed(result, failed_constraint_name); return; } - base::PostTaskAndReplyWithResult( - worker_task_runner_.get(), FROM_HERE, - base::Bind(&SelectSettingsVideoContentCapture, - current_request_info_->web_request().VideoConstraints(), - video_controls.stream_source), - base::Bind(&UserMediaProcessor::FinalizeSelectVideoContentSettings, - weak_factory_.GetWeakPtr(), - current_request_info_->web_request())); + SelectVideoContentSettings(); } } @@ -513,13 +506,12 @@ GenerateStreamForCurrentRequestInfo(); } -void UserMediaProcessor::FinalizeSelectVideoContentSettings( - const blink::WebUserMediaRequest& web_request, - const VideoCaptureSettings& settings) { +void UserMediaProcessor::SelectVideoContentSettings() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (!IsCurrentRequestInfo(web_request)) - return; - + DCHECK(current_request_info_); + VideoCaptureSettings settings = SelectSettingsVideoContentCapture( + current_request_info_->web_request().VideoConstraints(), + current_request_info_->stream_controls()->video.stream_source); if (!settings.HasValue()) { blink::WebString failed_constraint_name = blink::WebString::FromASCII(settings.failed_constraint_name());
diff --git a/content/renderer/media/user_media_processor.h b/content/renderer/media/user_media_processor.h index 99f844b..743b9333 100644 --- a/content/renderer/media/user_media_processor.h +++ b/content/renderer/media/user_media_processor.h
@@ -7,6 +7,7 @@ #include <memory> #include <string> +#include <utility> #include <vector> #include "base/callback_forward.h" @@ -255,9 +256,7 @@ void FinalizeSelectVideoDeviceSettings( const blink::WebUserMediaRequest& web_request, const VideoCaptureSettings& settings); - void FinalizeSelectVideoContentSettings( - const blink::WebUserMediaRequest& web_request, - const VideoCaptureSettings& settings); + void SelectVideoContentSettings(); void GenerateStreamForCurrentRequestInfo();
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index 609dd65..d7dfa63 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -61,7 +61,6 @@ #include "content/common/savable_subframe.h" #include "content/common/service_worker/service_worker_types.h" #include "content/common/service_worker/service_worker_utils.h" -#include "content/common/site_isolation_policy.h" #include "content/common/swapped_out_messages.h" #include "content/common/view_messages.h" #include "content/public/common/appcache_info.h"
diff --git a/content/renderer/render_frame_proxy.cc b/content/renderer/render_frame_proxy.cc index 6d74f5d7..d451dac 100644 --- a/content/renderer/render_frame_proxy.cc +++ b/content/renderer/render_frame_proxy.cc
@@ -17,7 +17,6 @@ #include "content/common/frame_replication_state.h" #include "content/common/input_messages.h" #include "content/common/page_messages.h" -#include "content/common/site_isolation_policy.h" #include "content/common/swapped_out_messages.h" #include "content/common/view_messages.h" #include "content/public/common/content_switches.h" @@ -715,4 +714,4 @@ } #endif -} // namespace +} // namespace content
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc index ee79aaf2..e6f8670 100644 --- a/content/renderer/render_thread_impl.cc +++ b/content/renderer/render_thread_impl.cc
@@ -69,7 +69,6 @@ #include "content/common/frame_owner_properties.h" #include "content/common/gpu_stream_constants.h" #include "content/common/resource_messages.h" -#include "content/common/site_isolation_policy.h" #include "content/common/view_messages.h" #include "content/public/common/content_constants.h" #include "content/public/common/content_features.h" @@ -443,7 +442,8 @@ // thread. class UkmRecorderFactoryImpl : public cc::UkmRecorderFactory { public: - UkmRecorderFactoryImpl(std::unique_ptr<service_manager::Connector> connector) + explicit UkmRecorderFactoryImpl( + std::unique_ptr<service_manager::Connector> connector) : connector_(std::move(connector)) { DCHECK(connector_); }
diff --git a/content/renderer/render_view_browsertest.cc b/content/renderer/render_view_browsertest.cc index f02e349..a82a9b3 100644 --- a/content/renderer/render_view_browsertest.cc +++ b/content/renderer/render_view_browsertest.cc
@@ -27,7 +27,6 @@ #include "content/common/frame_owner_properties.h" #include "content/common/frame_replication_state.h" #include "content/common/renderer.mojom.h" -#include "content/common/site_isolation_policy.h" #include "content/common/view_messages.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/native_web_keyboard_event.h"
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index 9c2f2d4..e5e29608 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -1203,7 +1203,6 @@ "../browser/devtools/devtools_http_handler_unittest.cc", "../browser/devtools/devtools_manager_unittest.cc", "../browser/devtools/protocol/tracing_handler_unittest.cc", - "../browser/devtools/shared_worker_devtools_manager_unittest.cc", "../browser/dom_storage/dom_storage_area_unittest.cc", "../browser/dom_storage/dom_storage_context_impl_unittest.cc", "../browser/dom_storage/dom_storage_database_unittest.cc", @@ -1426,6 +1425,7 @@ "../browser/shared_worker/shared_worker_instance_unittest.cc", "../browser/shared_worker/shared_worker_service_impl_unittest.cc", "../browser/site_instance_impl_unittest.cc", + "../browser/site_isolation_policy_unittest.cc", "../browser/startup_task_runner_unittest.cc", "../browser/storage_partition_impl_map_unittest.cc", "../browser/storage_partition_impl_unittest.cc", @@ -1491,7 +1491,6 @@ "../common/service_manager/service_manager_connection_impl_unittest.cc", "../common/service_worker/service_worker_types_unittest.cc", "../common/service_worker/service_worker_utils_unittest.cc", - "../common/site_isolation_policy_unittest.cc", "../common/throttling_url_loader_unittest.cc", "../common/unique_name_helper_unittest.cc", "../common/webplugininfo_unittest.cc",
diff --git a/ios/web/web_state/web_state_impl.h b/ios/web/web_state/web_state_impl.h index da10e00a..07eed9a 100644 --- a/ios/web/web_state/web_state_impl.h +++ b/ios/web/web_state/web_state_impl.h
@@ -79,7 +79,9 @@ // Notifies the observers that a navigation has started. void OnNavigationStarted(web::NavigationContext* context); - // Notifies the observers that a navigation has finished. + // Notifies the observers that a navigation has finished. For same-document + // navigations notifies the observers about favicon URLs update using + // candidates received in OnFaviconUrlUpdated. void OnNavigationFinished(web::NavigationContext* context); // Called when page title was changed. @@ -378,6 +380,12 @@ // history into WKWebView when web usage is re-enabled. base::scoped_nsobject<CRWSessionStorage> cached_session_storage_; + // Favicons URLs received in OnFaviconUrlUpdated. + // WebStateObserver:FaviconUrlUpdated must be called for same-document + // navigations, so this cache will be used to avoid running expensive favicon + // fetching JavaScript. + std::vector<web::FaviconURL> cached_favicon_urls_; + DISALLOW_COPY_AND_ASSIGN(WebStateImpl); };
diff --git a/ios/web/web_state/web_state_impl.mm b/ios/web/web_state/web_state_impl.mm index 178893d..3fed0c3 100644 --- a/ios/web/web_state/web_state_impl.mm +++ b/ios/web/web_state/web_state_impl.mm
@@ -261,6 +261,7 @@ void WebStateImpl::OnFaviconUrlUpdated( const std::vector<FaviconURL>& candidates) { + cached_favicon_urls_ = candidates; for (auto& observer : observers_) observer.FaviconUrlUpdated(this, candidates); } @@ -736,6 +737,19 @@ void WebStateImpl::OnNavigationFinished(web::NavigationContext* context) { for (auto& observer : observers_) observer.DidFinishNavigation(this, context); + + // Update cached_favicon_urls_. + if (!context->IsSameDocument()) { + // Favicons are not valid after document change. Favicon URLs will be + // refetched by CRWWebController and passed to OnFaviconUrlUpdated. + cached_favicon_urls_.clear(); + } else if (!cached_favicon_urls_.empty()) { + // For same-document navigations favicon urls will not be refetched and + // WebStateObserver:FaviconUrlUpdated must use the cached results. + for (auto& observer : observers_) { + observer.FaviconUrlUpdated(this, cached_favicon_urls_); + } + } } #pragma mark - NavigationManagerDelegate implementation
diff --git a/ios/web/web_state/web_state_impl_unittest.mm b/ios/web/web_state/web_state_impl_unittest.mm index d75b2fd..61324ab0 100644 --- a/ios/web/web_state/web_state_impl_unittest.mm +++ b/ios/web/web_state/web_state_impl_unittest.mm
@@ -18,6 +18,7 @@ #import "base/test/ios/wait_util.h" #import "ios/web/public/java_script_dialog_presenter.h" #include "ios/web/public/load_committed_details.h" +#import "ios/web/public/test/fakes/fake_navigation_context.h" #include "ios/web/public/test/fakes/test_browser_state.h" #import "ios/web/public/test/fakes/test_web_state_delegate.h" #import "ios/web/public/test/fakes/test_web_state_observer.h" @@ -772,4 +773,53 @@ EXPECT_TRUE(web_state_with_opener->HasOpener()); } +// Tests that WebStateObserver::FaviconUrlUpdated is called for same-document +// navigations. +TEST_F(WebStateImplTest, FaviconUpdateForSameDocumentNavigations) { + auto observer = std::make_unique<TestWebStateObserver>(web_state_.get()); + + // No callback if icons has not been fetched yet. + FakeNavigationContext context; + context.SetIsSameDocument(true); + web_state_->OnNavigationFinished(&context); + EXPECT_FALSE(observer->update_favicon_url_candidates_info()); + + // Callback is called when icons were fetched. + observer = base::MakeUnique<TestWebStateObserver>(web_state_.get()); + web::FaviconURL favicon_url(GURL("https://chromium.test/"), + web::FaviconURL::IconType::kTouchIcon, + {gfx::Size(5, 6)}); + web_state_->OnFaviconUrlUpdated({favicon_url}); + EXPECT_TRUE(observer->update_favicon_url_candidates_info()); + + // Callback is now called after same-document navigation. + observer = std::make_unique<TestWebStateObserver>(web_state_.get()); + web_state_->OnNavigationFinished(&context); + ASSERT_TRUE(observer->update_favicon_url_candidates_info()); + ASSERT_EQ(1U, + observer->update_favicon_url_candidates_info()->candidates.size()); + const web::FaviconURL& actual_favicon_url = + observer->update_favicon_url_candidates_info()->candidates[0]; + EXPECT_EQ(favicon_url.icon_url, actual_favicon_url.icon_url); + EXPECT_EQ(favicon_url.icon_type, actual_favicon_url.icon_type); + ASSERT_EQ(favicon_url.icon_sizes.size(), + actual_favicon_url.icon_sizes.size()); + EXPECT_EQ(favicon_url.icon_sizes[0].width(), + actual_favicon_url.icon_sizes[0].width()); + EXPECT_EQ(favicon_url.icon_sizes[0].height(), + actual_favicon_url.icon_sizes[0].height()); + + // Document change navigation does not call callback. + observer = std::make_unique<TestWebStateObserver>(web_state_.get()); + context.SetIsSameDocument(false); + web_state_->OnNavigationFinished(&context); + EXPECT_FALSE(observer->update_favicon_url_candidates_info()); + + // Previous candidates were invalidated by the document change. No callback + // if icons has not been fetched yet. + context.SetIsSameDocument(true); + web_state_->OnNavigationFinished(&context); + EXPECT_FALSE(observer->update_favicon_url_candidates_info()); +} + } // namespace web
diff --git a/media/gpu/vaapi/vaapi_tfp_picture.cc b/media/gpu/vaapi/vaapi_tfp_picture.cc index e9eecce..bd7823c 100644 --- a/media/gpu/vaapi/vaapi_tfp_picture.cc +++ b/media/gpu/vaapi/vaapi_tfp_picture.cc
@@ -72,7 +72,8 @@ bool VaapiTFPPicture::Allocate(gfx::BufferFormat format) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (format != gfx::BufferFormat::BGRX_8888 && - format != gfx::BufferFormat::BGRA_8888) { + format != gfx::BufferFormat::BGRA_8888 && + format != gfx::BufferFormat::RGBX_8888) { DLOG(ERROR) << "Unsupported format"; return false; }
diff --git a/pdf/timer.cc b/pdf/timer.cc index d07e2e9..cbd11a0 100644 --- a/pdf/timer.cc +++ b/pdf/timer.cc
@@ -9,8 +9,7 @@ namespace chrome_pdf { -Timer::Timer(int delay_in_milliseconds) - : delay_(delay_in_milliseconds), callback_factory_(this) { +Timer::Timer(base::TimeDelta delay) : delay_(delay), callback_factory_(this) { PostCallback(); } @@ -19,7 +18,8 @@ void Timer::PostCallback() { pp::CompletionCallback callback = callback_factory_.NewCallback(&Timer::TimerProc); - pp::Module::Get()->core()->CallOnMainThread(delay_, callback, 0); + pp::Module::Get()->core()->CallOnMainThread(delay_.InMilliseconds(), callback, + 0); } void Timer::TimerProc(int32_t /*result*/) {
diff --git a/pdf/timer.h b/pdf/timer.h index a27f78f3..cff2b88 100644 --- a/pdf/timer.h +++ b/pdf/timer.h
@@ -6,6 +6,7 @@ #define PDF_TIMER_H_ #include "base/macros.h" +#include "base/time/time.h" #include "ppapi/utility/completion_callback_factory.h" namespace chrome_pdf { @@ -15,7 +16,7 @@ // base::MessageLoop, on which it is based. class Timer { public: - explicit Timer(int delay_in_milliseconds); + explicit Timer(base::TimeDelta delay); virtual ~Timer(); virtual void OnTimer() = 0; @@ -24,7 +25,7 @@ void PostCallback(); void TimerProc(int32_t result); - int delay_; + const base::TimeDelta delay_; pp::CompletionCallbackFactory<Timer> callback_factory_; DISALLOW_COPY_AND_ASSIGN(Timer);
diff --git a/pdf/url_loader_wrapper_impl.cc b/pdf/url_loader_wrapper_impl.cc index 0e3a066..6d8623b 100644 --- a/pdf/url_loader_wrapper_impl.cc +++ b/pdf/url_loader_wrapper_impl.cc
@@ -19,8 +19,9 @@ namespace chrome_pdf { namespace { + // We should read with delay to prevent block UI thread, and reduce CPU usage. -const int kReadDelayMs = 2; +constexpr base::TimeDelta kReadDelayMs = base::TimeDelta::FromMilliseconds(2); pp::URLRequestInfo MakeRangeRequest(pp::Instance* plugin_instance, const std::string& url,
diff --git a/services/service_manager/sandbox/linux/bpf_broker_policy_linux.cc b/services/service_manager/sandbox/linux/bpf_broker_policy_linux.cc index 9b368b43..86ce53a 100644 --- a/services/service_manager/sandbox/linux/bpf_broker_policy_linux.cc +++ b/services/service_manager/sandbox/linux/bpf_broker_policy_linux.cc
@@ -21,12 +21,12 @@ #if defined(__NR_access) case __NR_access: #endif -#if defined(__NR_open) - case __NR_open: -#endif #if defined(__NR_faccessat) case __NR_faccessat: #endif +#if defined(__NR_open) + case __NR_open: +#endif #if defined(__NR_openat) case __NR_openat: #endif @@ -48,6 +48,12 @@ #if defined(__NR_newfstatat) case __NR_newfstatat: #endif +#if defined(__NR_readlink) + case __NR_readlink: +#endif +#if defined(__NR_readlinkat) + case __NR_readlinkat: +#endif return Allow(); default: return BPFBasePolicy::EvaluateSyscall(sysno);
diff --git a/services/service_manager/sandbox/linux/bpf_network_policy_linux.cc b/services/service_manager/sandbox/linux/bpf_network_policy_linux.cc index ef1d5983..af5a894 100644 --- a/services/service_manager/sandbox/linux/bpf_network_policy_linux.cc +++ b/services/service_manager/sandbox/linux/bpf_network_policy_linux.cc
@@ -62,6 +62,12 @@ #if defined(__NR_rename) case __NR_rename: #endif +#if defined(__NR_readlink) + case __NR_readlink: +#endif +#if defined(__NR_readlinkat) + case __NR_readlinkat: +#endif return Trap(BrokerProcess::SIGSYS_Handler, SandboxLinux::GetInstance()->broker_process()); default:
diff --git a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json index 7a501da7..a83d191 100644 --- a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json +++ b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json
@@ -231968,7 +231968,7 @@ "support" ], "common/media.js": [ - "a575b8135e6ddb1501fc2a082d7544ee86011b7d", + "33c78c9c056dc4879c2503075e6cedbf2211b6d2", "support" ], "common/media.js.headers": [ @@ -298256,7 +298256,7 @@ "support" ], "feature-policy/README.md": [ - "711c323f1690b0dbe780461241ad825cdd3cf274", + "67e317403163eb2f7b4d9599d21da97635fc14cf", "support" ], "feature-policy/payment-allowed-by-feature-policy-attribute-redirect-on-load.https.sub.html": [ @@ -300592,7 +300592,7 @@ "testharness" ], "html/browsers/browsing-the-web/read-media/pageload-video.html": [ - "2d8749e1d5f585ba60ce0a20367d116d126df475", + "2ae6e21db438a657afd934bb8fb8a21de5f5f2cf", "testharness" ], "html/browsers/browsing-the-web/read-multipart-x-mixed-replace/.gitkeep": [ @@ -328772,7 +328772,7 @@ "support" ], "preload/modulepreload.html": [ - "89d25610cb5cab74248ee78bdf5940315b0f7f70", + "02861e80c504a4d8de8474cb6620c10849c2a329", "testharness" ], "preload/onerror-event.html": [
diff --git a/third_party/WebKit/LayoutTests/external/wpt/common/media.js b/third_party/WebKit/LayoutTests/external/wpt/common/media.js index 6bddea5..7cea1ac 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/common/media.js +++ b/third_party/WebKit/LayoutTests/external/wpt/common/media.js
@@ -33,3 +33,14 @@ return base + extension; } + +function getMediaContentType(url) { + var extension = new URL(url, location).pathname.split(".").pop(); + var map = { + "mp4": "video/mp4", + "ogv": "video/ogg", + "mp3": "audio/mp3", + "oga": "audio/ogg", + }; + return map[extension]; +}
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/browsers/browsing-the-web/read-media/pageload-video.html b/third_party/WebKit/LayoutTests/external/wpt/html/browsers/browsing-the-web/read-media/pageload-video.html index 69ef741..1ae414ce 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/html/browsers/browsing-the-web/read-media/pageload-video.html +++ b/third_party/WebKit/LayoutTests/external/wpt/html/browsers/browsing-the-web/read-media/pageload-video.html
@@ -1,30 +1,27 @@ <!DOCTYPE HTML> -<html> -<head> - <title>Media documents: video</title> - <link rel="author" title="Michael Ventnor" href="mailto:mventnor@mozilla.com"> - <link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com"> - <link rel="help" href="https://html.spec.whatwg.org/multipage/#read-media"> - <script src="/resources/testharness.js"></script> - <script src="/resources/testharnessreport.js"></script> - +<meta charset="utf-8"> +<title>Media documents: video</title> +<link rel="author" title="Michael Ventnor" href="mailto:mventnor@mozilla.com"> +<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com"> +<link rel="help" href="https://html.spec.whatwg.org/multipage/#read-media"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/common/media.js"></script> +<div id="log"></div> <script> - var t = async_test("The document for a standalone media file should have one child in the body."); - - function frameLoaded() { - var testframe = document.getElementById('testframe'); - assert_equals(testframe.contentDocument.contentType, "video/webm"); +async_test(function() { + var testframe = document.createElement('iframe'); + var url = getVideoURI("/media/A4"); + var contentType = getMediaContentType(url); + testframe.onload = this.step_func_done(function() { + assert_equals(testframe.contentDocument.contentType, contentType); var testframeChildren = testframe.contentDocument.body.childNodes; assert_equals(testframeChildren.length, 1, "Body of image document has 1 child"); assert_equals(testframeChildren[0].nodeName, "VIDEO", "Only child of body must be an <video> element"); assert_equals(testframeChildren[0].namespaceURI, "http://www.w3.org/1999/xhtml", "Only child of body must be an HTML element"); - t.done(); - } + }); + testframe.src = url; + document.body.appendChild(testframe); +}, "The document for a standalone media file should have one child in the body."); </script> -</head> -<body> - <div id="log"></div> - <iframe id="testframe" onload="t.step(frameLoaded)" src="/media/white.webm"></iframe> -</body> -</html>
diff --git a/third_party/WebKit/Source/OWNERS b/third_party/WebKit/Source/OWNERS new file mode 100644 index 0000000..99a70f4 --- /dev/null +++ b/third_party/WebKit/Source/OWNERS
@@ -0,0 +1,3 @@ +per-file DEPS=dcheng@chromium.org +per-file DEPS=haraken@chromium.org +per-file DEPS=jbroman@chromium.org
diff --git a/third_party/WebKit/Source/core/dom/ClassicPendingScript.cpp b/third_party/WebKit/Source/core/dom/ClassicPendingScript.cpp index ef81067..7be44c8 100644 --- a/third_party/WebKit/Source/core/dom/ClassicPendingScript.cpp +++ b/third_party/WebKit/Source/core/dom/ClassicPendingScript.cpp
@@ -239,7 +239,7 @@ ScriptSourceCode source_code(GetElement()->TextFromChildren(), source_location_type_, document_url, StartingPosition()); - return ClassicScript::Create(source_code, options_); + return ClassicScript::Create(source_code, options_, kSharableCrossOrigin); } DCHECK(GetResource()->IsLoaded()); @@ -247,7 +247,8 @@ !streamer_->StreamingSuppressed(); ScriptSourceCode source_code(streamer_ready ? streamer_ : nullptr, GetResource()); - return ClassicScript::Create(source_code, options_); + return ClassicScript::Create(source_code, options_, + GetResource()->CalculateAccessControlStatus()); } void ClassicPendingScript::SetStreamer(ScriptStreamer* streamer) {
diff --git a/third_party/WebKit/Source/core/dom/ClassicScript.cpp b/third_party/WebKit/Source/core/dom/ClassicScript.cpp index 3bf4f195..bd769ef 100644 --- a/third_party/WebKit/Source/core/dom/ClassicScript.cpp +++ b/third_party/WebKit/Source/core/dom/ClassicScript.cpp
@@ -10,7 +10,6 @@ #include "core/frame/UseCounter.h" #include "core/inspector/ConsoleMessage.h" #include "core/loader/AllowedByNosniff.h" -#include "platform/loader/fetch/AccessControlStatus.h" #include "platform/network/mime/MIMETypeRegistry.h" namespace blink { @@ -29,19 +28,8 @@ void ClassicScript::RunScript(LocalFrame* frame, const SecurityOrigin* security_origin) const { - const bool is_external_script = GetScriptSourceCode().GetResource(); - - AccessControlStatus access_control_status = kNotSharableCrossOrigin; - if (!is_external_script) { - access_control_status = kSharableCrossOrigin; - } else { - CHECK(GetScriptSourceCode().GetResource()); - access_control_status = - GetScriptSourceCode().GetResource()->CalculateAccessControlStatus(); - } - frame->GetScriptController().ExecuteScriptInMainWorld( - GetScriptSourceCode(), FetchOptions(), access_control_status); + GetScriptSourceCode(), FetchOptions(), access_control_status_); } } // namespace blink
diff --git a/third_party/WebKit/Source/core/dom/ClassicScript.h b/third_party/WebKit/Source/core/dom/ClassicScript.h index 1582a76..59b3e690 100644 --- a/third_party/WebKit/Source/core/dom/ClassicScript.h +++ b/third_party/WebKit/Source/core/dom/ClassicScript.h
@@ -8,6 +8,8 @@ #include "bindings/core/v8/ScriptSourceCode.h" #include "core/CoreExport.h" #include "core/dom/Script.h" +#include "core/loader/resource/ScriptResource.h" +#include "platform/loader/fetch/AccessControlStatus.h" #include "platform/loader/fetch/ScriptFetchOptions.h" namespace blink { @@ -15,8 +17,10 @@ class CORE_EXPORT ClassicScript final : public Script { public: static ClassicScript* Create(const ScriptSourceCode& script_source_code, - const ScriptFetchOptions& fetch_options) { - return new ClassicScript(script_source_code, fetch_options); + const ScriptFetchOptions& fetch_options, + AccessControlStatus access_control_status) { + return new ClassicScript(script_source_code, fetch_options, + access_control_status); } void Trace(blink::Visitor*); @@ -27,8 +31,11 @@ private: ClassicScript(const ScriptSourceCode& script_source_code, - const ScriptFetchOptions& fetch_options) - : Script(fetch_options), script_source_code_(script_source_code) {} + const ScriptFetchOptions& fetch_options, + AccessControlStatus access_control_status) + : Script(fetch_options), + script_source_code_(script_source_code), + access_control_status_(access_control_status) {} ScriptType GetScriptType() const override { return ScriptType::kClassic; } bool CheckMIMETypeBeforeRunScript(Document* context_document, @@ -39,6 +46,7 @@ } const ScriptSourceCode script_source_code_; + const AccessControlStatus access_control_status_; }; } // namespace blink
diff --git a/third_party/WebKit/Source/modules/vr/VRDisplay.cpp b/third_party/WebKit/Source/modules/vr/VRDisplay.cpp index de9c6e77..18530631 100644 --- a/third_party/WebKit/Source/modules/vr/VRDisplay.cpp +++ b/third_party/WebKit/Source/modules/vr/VRDisplay.cpp
@@ -1035,9 +1035,11 @@ void VRDisplay::OnPresentationProviderConnectionError() { vr_presentation_provider_.reset(); - ForceExitPresent(); - pending_vsync_ = false; - RequestVSync(); + if (is_presenting_) { + ForceExitPresent(); + pending_vsync_ = false; + RequestVSync(); + } } ScriptedAnimationController& VRDisplay::EnsureScriptedAnimationController(
diff --git a/third_party/WebKit/Source/platform/graphics/CanvasHeuristicParameters.h b/third_party/WebKit/Source/platform/graphics/CanvasHeuristicParameters.h index 9f6210d..acfe4919 100644 --- a/third_party/WebKit/Source/platform/graphics/CanvasHeuristicParameters.h +++ b/third_party/WebKit/Source/platform/graphics/CanvasHeuristicParameters.h
@@ -10,25 +10,13 @@ namespace CanvasHeuristicParameters { enum { - // Layer promotion heuristic parameters + // Disable Deferral overdraw parameters //====================================== - // FIXME (crbug.com/463239): - // The Layer promotion heuristics should go away after slimming paint - // is completely phased in and display list canvases are modified to - // use a lightweight layering primitive instead of the - // SkCanvas::saveLayer. - // Heuristic: Canvases that are overdrawn beyond this factor in a - // single frame are promoted to a direct composited layer so that - // their contents not be re-rasterized by the compositor when the - // containing layer is the object of a paint invalidation. + // single frame will be disabled deferral. kExpensiveOverdrawThreshold = 10, - kComplexClipsAreExpensive = 1, - - kBlurredShadowsAreExpensive = 1, - // Disable Acceleration heuristic parameters //===========================================
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_importer.py b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_importer.py index 173235c..844a1b9 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_importer.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_importer.py
@@ -36,7 +36,7 @@ TIMEOUT_SECONDS = 210 * 60 # Sheriff calendar URL, used for getting the ecosystem infra sheriff to TBR. -ROTATIONS_URL = 'http://chromium-build.appspot.com/p/chromium/all_rotations.js' +ROTATIONS_URL = 'https://build.chromium.org/deprecated/chromium/all_rotations.js' _log = logging.getLogger(__file__)
diff --git a/third_party/android_platform/README.chromium b/third_party/android_platform/README.chromium index 9685213..2346f55 100644 --- a/third_party/android_platform/README.chromium +++ b/third_party/android_platform/README.chromium
@@ -40,10 +40,6 @@ Fixed invalid using decl in logging header debug.h Only attempt to symbolize with ELF libraries. -Changed the stack script to use llvm symbolizer instead of addr2line, -objdump, etc, since llvm symbolizer is more efficient in finding -function names, line numbers etc. - Android relocation packing tool details: Copy sources from AOSP bionic/tools/relocation_packer Remove scripts that regenerate golden test data (not relevant here)
diff --git a/third_party/android_platform/development/scripts/stack b/third_party/android_platform/development/scripts/stack index a69cec3..8d09461 100755 --- a/third_party/android_platform/development/scripts/stack +++ b/third_party/android_platform/development/scripts/stack
@@ -31,13 +31,8 @@ sys.path.insert(0, os.path.join(os.path.dirname(__file__), os.pardir, os.pardir, os.pardir, os.pardir, 'build', 'android')) - from pylib import constants -sys.path.insert(0, os.path.join(os.path.dirname(__file__), - os.pardir, os.pardir, os.pardir, os.pardir, - 'tools', 'python')) -import llvm_symbolizer DEFAULT_SYMROOT='/tmp/symbols' # From: https://source.android.com/source/build-numbers.html @@ -230,12 +225,10 @@ print ("Reading Android symbols from: " + os.path.normpath(symbol.SYMBOLS_DIR)) chrome_search_path = symbol.GetLibrarySearchPaths() - - with llvm_symbolizer.LLVMSymbolizer() as symbolizer: - print ("Searching for Chrome symbols from within: " - + ':'.join((os.path.normpath(d) for d in chrome_search_path))) - stack_core.ConvertTrace(lines, load_vaddrs, more_info, fallback_monochrome, - arch_defined, symbolizer) + print ("Searching for Chrome symbols from within: " + + ':'.join((os.path.normpath(d) for d in chrome_search_path))) + stack_core.ConvertTrace(lines, load_vaddrs, more_info, fallback_monochrome, + arch_defined) if rootdir: # be a good citizen and clean up...os.rmdir and os.removedirs() don't work
diff --git a/third_party/android_platform/development/scripts/stack_core.py b/third_party/android_platform/development/scripts/stack_core.py index aa7da9f..f206793 100755 --- a/third_party/android_platform/development/scripts/stack_core.py +++ b/third_party/android_platform/development/scripts/stack_core.py
@@ -158,7 +158,7 @@ print print '-----------------------------------------------------\n' -def ConvertTrace(lines, load_vaddrs, more_info, fallback_monochrome, arch_defined, llvm_symbolizer): +def ConvertTrace(lines, load_vaddrs, more_info, fallback_monochrome, arch_defined): """Convert strings containing native crash to a stack.""" InitWidthRelatedLineMatchers() @@ -189,7 +189,7 @@ print ('Find ABI:' + arch) symbol.ARCH = arch - ResolveCrashSymbol(list(useful_log), more_info, llvm_symbolizer) + ResolveCrashSymbol(list(useful_log), more_info) end = time.time() logging.debug('Finished resolving symbols. Elapsed time: %.4fs', (end - start)) @@ -304,7 +304,7 @@ useful_log.append(line) return useful_log, self._so_dirs -def ResolveCrashSymbol(lines, more_info, llvm_symbolizer): +def ResolveCrashSymbol(lines, more_info): """Convert unicode strings which contains native crash to a stack """ @@ -313,6 +313,39 @@ last_frame = -1 pid = -1 + # It is faster to get symbol information with a single call rather than with + # separate calls for each line. Since symbol.SymbolInformation caches results, + # we can extract all the addresses that we will want symbol information for + # from the log and call symbol.SymbolInformation so that the results are + # cached in the following lookups. + code_addresses = {} + + # Collects all java exception lines, keyed by pid for later output during + # native crash handling. + java_stderr_by_pid = {} + for line in lines: + lib, address = None, None + + match = _TRACE_LINE.match(line) or _DEBUG_TRACE_LINE.match(line) + if match: + address, lib = match.group('address', 'lib') + + match = _VALUE_LINE.match(line) + if match and not _CODE_LINE.match(line): + (_0, _1, address, lib, _2, _3) = match.groups() + + if lib: + code_addresses.setdefault(lib, set()).add(address) + + java_stderr_match = _JAVA_STDERR_LINE.search(line) + if java_stderr_match: + pid, msg = java_stderr_match.groups() + java_stderr_by_pid.setdefault(pid, []).append(msg) + + for lib in code_addresses: + symbol.SymbolInformationForSet( + symbol.TranslateLibPath(lib), code_addresses[lib], more_info) + for line in lines: # AndroidFeedback adds zero width spaces into its crash reports. These # should be removed or the regular expresssions will fail to match. @@ -377,19 +410,25 @@ logging.debug('Identified lib: %s' % area) # If a calls b which further calls c and c is inlined to b, we want to # display "a -> b -> c" in the stack trace instead of just "a -> c" - # To use llvm symbolizer, the hexadecimal address has to start with 0x. - info = llvm_symbolizer.GetSymbolInformation( - os.path.join(symbol.SYMBOLS_DIR, symbol.TranslateLibPath(area)), - '0x' + code_addr) + info = symbol.SymbolInformation(area, code_addr, more_info) logging.debug('symbol information: %s' % info) nest_count = len(info) - 1 - for source_symbol, source_location in info: + for (source_symbol, source_location, object_symbol_with_offset) in info: + if not source_symbol: + if symbol_present: + source_symbol = symbol.CallCppFilt(symbol_name) + else: + source_symbol = UNKNOWN + if not source_location: + source_location = area if nest_count > 0: nest_count = nest_count - 1 trace_lines.append(('v------>', source_symbol, source_location)) else: + if not object_symbol_with_offset: + object_symbol_with_offset = source_symbol trace_lines.append((code_addr, - source_symbol, + object_symbol_with_offset, source_location)) match = _VALUE_LINE.match(line) if match: @@ -397,14 +436,20 @@ if area == UNKNOWN or area == HEAP or area == STACK or not area: value_lines.append((addr, value, '', area)) else: - info = llvm_symbolizer.GetSymbolInformation( - os.path.join(symbol.SYMBOLS_DIR, symbol.TranslateLibPath(area)), - '0x' + code_addr) - source_symbol, source_location = info.pop() - + info = symbol.SymbolInformation(area, value, more_info) + (source_symbol, source_location, object_symbol_with_offset) = info.pop() + if not source_symbol: + if symbol_present: + source_symbol = symbol.CallCppFilt(symbol_name) + else: + source_symbol = UNKNOWN + if not source_location: + source_location = area + if not object_symbol_with_offset: + object_symbol_with_offset = source_symbol value_lines.append((addr, value, - source_symbol, + object_symbol_with_offset, source_location)) java_lines = []
diff --git a/third_party/android_platform/development/scripts/symbol.py b/third_party/android_platform/development/scripts/symbol.py index 7a82c82..469446ca 100755 --- a/third_party/android_platform/development/scripts/symbol.py +++ b/third_party/android_platform/development/scripts/symbol.py
@@ -69,6 +69,91 @@ return "linux-x86" return uname +def ToolPath(tool, toolchain_info=None): + """Return a full qualified path to the specified tool""" + # ToolPath looks for the tools in the completely incorrect directory. + # This looks in the checked in android_tools. + if ARCH == "arm": + toolchain_source = "arm-linux-androideabi-4.9" + toolchain_prefix = "arm-linux-androideabi" + ndk = "ndk" + elif ARCH == "arm64": + toolchain_source = "aarch64-linux-android-4.9" + toolchain_prefix = "aarch64-linux-android" + ndk = "ndk" + elif ARCH == "x86": + toolchain_source = "x86-4.9" + toolchain_prefix = "i686-linux-android" + ndk = "ndk" + elif ARCH == "x86_64" or ARCH == "x64": + toolchain_source = "x86_64-4.9" + toolchain_prefix = "x86_64-linux-android" + ndk = "ndk" + elif ARCH == "mips": + toolchain_source = "mipsel-linux-android-4.9" + toolchain_prefix = "mipsel-linux-android" + ndk = "ndk" + else: + raise Exception("Could not find tool chain for " + ARCH) + + toolchain_subdir = ( + "third_party/android_tools/%s/toolchains/%s/prebuilt/linux-x86_64/bin" % + (ndk, toolchain_source)) + + return os.path.join(CHROME_SRC, + toolchain_subdir, + toolchain_prefix + "-" + tool) + +def FindToolchain(): + """Look for the latest available toolchain + + Args: + None + + Returns: + A pair of strings containing toolchain label and target prefix. + """ + global TOOLCHAIN_INFO + if TOOLCHAIN_INFO is not None: + return TOOLCHAIN_INFO + + ## Known toolchains, newer ones in the front. + gcc_version = "4.9" + if ARCH == "arm64": + known_toolchains = [ + ("aarch64-linux-android-" + gcc_version, "aarch64", "aarch64-linux-android") + ] + elif ARCH == "arm": + known_toolchains = [ + ("arm-linux-androideabi-" + gcc_version, "arm", "arm-linux-androideabi") + ] + elif ARCH =="x86": + known_toolchains = [ + ("x86-" + gcc_version, "x86", "i686-linux-android") + ] + elif ARCH =="x86_64" or ARCH =="x64": + known_toolchains = [ + ("x86_64-" + gcc_version, "x86_64", "x86_64-linux-android") + ] + elif ARCH == "mips": + known_toolchains = [ + ("mipsel-linux-android-" + gcc_version, "mips", "mipsel-linux-android") + ] + else: + known_toolchains = [] + + logging.debug('FindToolcahin: known_toolchains=%s' % known_toolchains) + # Look for addr2line to check for valid toolchain path. + for (label, platform, target) in known_toolchains: + toolchain_info = (label, platform, target); + if os.path.exists(ToolPath("addr2line", toolchain_info)): + TOOLCHAIN_INFO = toolchain_info + print ("Using toolchain from: " + + os.path.normpath(ToolPath("", TOOLCHAIN_INFO))) + return toolchain_info + + raise Exception("Could not find tool chain") + def GetAapt(): """Returns the path to aapt. @@ -279,7 +364,260 @@ library_path = os.path.relpath(candidate_libraries[0], SYMBOLS_DIR) logging.debug('TranslateLibPath: library_path=%s' % library_path) - return library_path + return '/' + library_path + +def SymbolInformation(lib, addr, get_detailed_info): + """Look up symbol information about an address. + + Args: + lib: library (or executable) pathname containing symbols + addr: string hexidecimal address + + Returns: + A list of the form [(source_symbol, source_location, + object_symbol_with_offset)]. + + If the function has been inlined then the list may contain + more than one element with the symbols for the most deeply + nested inlined location appearing first. The list is + always non-empty, even if no information is available. + + Usually you want to display the source_location and + object_symbol_with_offset from the last element in the list. + """ + lib = TranslateLibPath(lib) + info = SymbolInformationForSet(lib, set([addr]), get_detailed_info) + return (info and info.get(addr)) or [(None, None, None)] + + +def SymbolInformationForSet(lib, unique_addrs, get_detailed_info): + """Look up symbol information for a set of addresses from the given library. + + Args: + lib: library (or executable) pathname containing symbols + unique_addrs: set of hexidecimal addresses + + Returns: + A dictionary of the form {addr: [(source_symbol, source_location, + object_symbol_with_offset)]} where each address has a list of + associated symbols and locations. The list is always non-empty. + + If the function has been inlined then the list may contain + more than one element with the symbols for the most deeply + nested inlined location appearing first. The list is + always non-empty, even if no information is available. + + Usually you want to display the source_location and + object_symbol_with_offset from the last element in the list. + """ + if not lib: + return None + + addr_to_line = CallAddr2LineForSet(lib, unique_addrs) + if not addr_to_line: + return None + + if get_detailed_info: + addr_to_objdump = CallObjdumpForSet(lib, unique_addrs) + if not addr_to_objdump: + return None + else: + addr_to_objdump = dict((addr, ("", 0)) for addr in unique_addrs) + + result = {} + for addr in unique_addrs: + source_info = addr_to_line.get(addr) + if not source_info: + source_info = [(None, None)] + if addr in addr_to_objdump: + (object_symbol, object_offset) = addr_to_objdump.get(addr) + object_symbol_with_offset = FormatSymbolWithOffset(object_symbol, + object_offset) + else: + object_symbol_with_offset = None + result[addr] = [(source_symbol, source_location, object_symbol_with_offset) + for (source_symbol, source_location) in source_info] + + return result + + +class MemoizedForSet(object): + def __init__(self, fn): + self.fn = fn + self.cache = {} + + def __call__(self, lib, unique_addrs): + lib_cache = self.cache.setdefault(lib, {}) + + no_cache = filter(lambda x: x not in lib_cache, unique_addrs) + if no_cache: + lib_cache.update((k, None) for k in no_cache) + result = self.fn(lib, no_cache) + if result: + lib_cache.update(result) + + return dict((k, lib_cache[k]) for k in unique_addrs if lib_cache[k]) + + +@MemoizedForSet +def CallAddr2LineForSet(lib, unique_addrs): + """Look up line and symbol information for a set of addresses. + + Args: + lib: library (or executable) pathname containing symbols + unique_addrs: set of string hexidecimal addresses look up. + + Returns: + A dictionary of the form {addr: [(symbol, file:line)]} where + each address has a list of associated symbols and locations + or an empty list if no symbol information was found. + + If the function has been inlined then the list may contain + more than one element with the symbols for the most deeply + nested inlined location appearing first. + """ + if not lib: + return None + + symbols = SYMBOLS_DIR + lib + if not os.path.splitext(symbols)[1] in ['', '.so', '.apk']: + return None + + if not os.path.isfile(symbols): + return None + + addrs = sorted(unique_addrs) + result = {} + + def _Callback(sym, addr): + records = [] + while sym: # Traverse all the inlines following the |inlined_by| chain. + if sym.source_path and sym.source_line: + location = '%s:%d' % (sym.source_path, sym.source_line) + else: + location = None + records += [(sym.name, location)] + sym = sym.inlined_by + result[addr] = records + + (label, platform, target) = FindToolchain() + symbolizer = elf_symbolizer.ELFSymbolizer( + elf_file_path=symbols, + addr2line_path=ToolPath("addr2line"), + callback=_Callback, + inlines=True) + + for addr in addrs: + symbolizer.SymbolizeAsync(int(addr, 16), addr) + symbolizer.Join() + return result + + +def StripPC(addr): + """Strips the Thumb bit a program counter address when appropriate. + + Args: + addr: the program counter address + + Returns: + The stripped program counter address. + """ + global ARCH + + if ARCH == "arm": + return addr & ~1 + return addr + +@MemoizedForSet +def CallObjdumpForSet(lib, unique_addrs): + """Use objdump to find out the names of the containing functions. + + Args: + lib: library (or executable) pathname containing symbols + unique_addrs: set of string hexidecimal addresses to find the functions for. + + Returns: + A dictionary of the form {addr: (string symbol, offset)}. + """ + if not lib: + return None + + symbols = SYMBOLS_DIR + lib + if not os.path.exists(symbols): + return None + + symbols = SYMBOLS_DIR + lib + if not os.path.exists(symbols): + return None + + result = {} + + # Function lines look like: + # 000177b0 <android::IBinder::~IBinder()+0x2c>: + # We pull out the address and function first. Then we check for an optional + # offset. This is tricky due to functions that look like "operator+(..)+0x2c" + func_regexp = re.compile("(^[a-f0-9]*) \<(.*)\>:$") + offset_regexp = re.compile("(.*)\+0x([a-f0-9]*)") + + # A disassembly line looks like: + # 177b2: b510 push {r4, lr} + asm_regexp = re.compile("(^[ a-f0-9]*):[ a-f0-0]*.*$") + + for target_addr in unique_addrs: + start_addr_dec = str(StripPC(int(target_addr, 16))) + stop_addr_dec = str(StripPC(int(target_addr, 16)) + 8) + cmd = [ToolPath("objdump"), + "--section=.text", + "--demangle", + "--disassemble", + "--start-address=" + start_addr_dec, + "--stop-address=" + stop_addr_dec, + symbols] + + current_symbol = None # The current function symbol in the disassembly. + current_symbol_addr = 0 # The address of the current function. + + stream = subprocess.Popen(cmd, stdout=subprocess.PIPE).stdout + for line in stream: + # Is it a function line like: + # 000177b0 <android::IBinder::~IBinder()>: + components = func_regexp.match(line) + if components: + # This is a new function, so record the current function and its address. + current_symbol_addr = int(components.group(1), 16) + current_symbol = components.group(2) + + # Does it have an optional offset like: "foo(..)+0x2c"? + components = offset_regexp.match(current_symbol) + if components: + current_symbol = components.group(1) + offset = components.group(2) + if offset: + current_symbol_addr -= int(offset, 16) + + # Is it an disassembly line like: + # 177b2: b510 push {r4, lr} + components = asm_regexp.match(line) + if components: + addr = components.group(1) + i_addr = int(addr, 16) + i_target = StripPC(int(target_addr, 16)) + if i_addr == i_target: + result[target_addr] = (current_symbol, i_target - current_symbol_addr) + stream.close() + + return result + + +def CallCppFilt(mangled_symbol): + cmd = [ToolPath("c++filt")] + process = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE) + process.stdin.write(mangled_symbol) + process.stdin.write("\n") + process.stdin.close() + demangled_symbol = process.stdout.readline().strip() + process.stdout.close() + return demangled_symbol def FormatSymbolWithOffset(symbol, offset): if offset == 0:
diff --git a/tools/grit/grit/format/android_xml.py b/tools/grit/grit/format/android_xml.py index 25774ab9..42ba6bc 100755 --- a/tools/grit/grit/format/android_xml.py +++ b/tools/grit/grit/format/android_xml.py
@@ -174,13 +174,17 @@ return None body_in = plural_match.group('items').strip() lines = [] + quantities_so_far = set() for item_match in _PLURALS_ITEM_PATTERN.finditer(body_in): quantity_in = item_match.group('quantity') quantity_out = _PLURALS_QUANTITY_MAP.get(quantity_in) value_in = item_match.group('value') value_out = '"' + value_in.replace('#', '%d') + '"' if quantity_out: - lines.append(_PLURALS_ITEM_TEMPLATE % (quantity_out, value_out)) + # only one line per quantity out (https://crbug.com/787488) + if quantity_out not in quantities_so_far: + quantities_so_far.add(quantity_out) + lines.append(_PLURALS_ITEM_TEMPLATE % (quantity_out, value_out)) else: raise Exception('Unsupported plural quantity for android ' 'strings.xml: %s' % quantity_in)
diff --git a/tools/grit/grit/format/android_xml_unittest.py b/tools/grit/grit/format/android_xml_unittest.py index 5e9871ed..6f496b61 100755 --- a/tools/grit/grit/format/android_xml_unittest.py +++ b/tools/grit/grit/format/android_xml_unittest.py
@@ -80,6 +80,34 @@ """ self.assertEqual(output.strip(), expected.strip()) + + def testConflictingPlurals(self): + root = util.ParseGrdForUnittest(ur""" + <messages> + <message name="IDS_PLURALS" desc="A string using the ICU plural format"> + {NUM_THINGS, plural, + =1 {Maybe I'll get one laser.} + one {Maybe I'll get one laser.} + other {Maybe I'll get # lasers.}} + </message> + </messages> + """) + + buf = StringIO.StringIO() + build.RcBuilder.ProcessNode(root, DummyOutput('android', 'en'), buf) + output = buf.getvalue() + expected = ur""" +<?xml version="1.0" encoding="utf-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android"> +<plurals name="plurals"> + <item quantity="one">"Maybe I\'ll get one laser."</item> + <item quantity="other">"Maybe I\'ll get %d lasers."</item> +</plurals> +</resources> +""" + self.assertEqual(output.strip(), expected.strip()) + + def testTaggedOnly(self): root = util.ParseGrdForUnittest(ur""" <messages>
diff --git a/tools/metrics/actions/actions.xml b/tools/metrics/actions/actions.xml index 8108a8d..7f333f9 100644 --- a/tools/metrics/actions/actions.xml +++ b/tools/metrics/actions/actions.xml
@@ -17519,6 +17519,36 @@ <description>User unmuted site via the tab strip.</description> </action> +<action name="SplitView_DoubleTapDividerSwapWindows"> + <owner>xdai@chromium.org</owner> + <description> + Recorded when the user double tapped on the split divider to swap windows in + tablet mode on Chrome OS. + </description> +</action> + +<action name="SplitView_EndSplitView"> + <owner>xdai@chromium.org</owner> + <description> + Recorded when the user ended split view mode in tablet mode on Chrome OS. + </description> +</action> + +<action name="SplitView_ResizeWindows"> + <owner>xdai@chromium.org</owner> + <description> + Recorded when the user dragged the split divider to resize the windows in + tablet mode on Chrome OS. + </description> +</action> + +<action name="SplitView_SnapWindow"> + <owner>xdai@chromium.org</owner> + <description> + Recorded when a window was just snapped in tablet mode on Chrome OS. + </description> +</action> + <action name="StackedTab_DragActiveTab"> <owner>bruthig@chromium.org</owner> <owner>tdanderson@chromium.org</owner> @@ -18544,6 +18574,22 @@ </description> </action> +<action name="Tablet_LongPressOverviewButtonEnterSplitView"> + <owner>xdai@chromium.org</owner> + <description> + Recorded when the user long pressed the overview button to enter split view + in tablet mode on Chrome OS. + </description> +</action> + +<action name="Tablet_LongPressOverviewButtonExitSplitView"> + <owner>xdai@chromium.org</owner> + <description> + Recorded when the user long pressed the overview button to exit split view + in tablet mode on Chrome OS. + </description> +</action> + <action name="Tablet_QuickSwitch"> <owner>sammiequon@chromium.org</owner> <description>
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 4cf6ed1d..4d6c2e47 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -3346,6 +3346,15 @@ </summary> </histogram> +<histogram name="Ash.SplitView.TimeInSplitView" units="ms"> + <owner>xdai@chromium.org</owner> + <summary> + The amount of time that the user spent in split view mode. The time is + measured from the moment a window is snapped to one side of the screen to + when split view mode is ended. + </summary> +</histogram> + <histogram name="Ash.StationaryTouchDuration" units="seconds"> <obsolete> Deprecated 02/2017 due to lack of usage. @@ -10109,6 +10118,17 @@ </summary> </histogram> +<histogram name="Compositing.Browser.HitTestTimeToFindClosestLayer" + units="microseconds"> + <owner>yigu@chromium.org</owner> + <summary> + Time spent finding the closest matching layer to a given point whenever we + do hit testing on LayerTreeImpl (in a browser process). + + Team: animations-dev@chromium.org. + </summary> +</histogram> + <histogram base="true" name="Compositing.Browser.LayersUpdateTime" units="microseconds"> <owner>threaded-rendering-dev@chromium.org</owner> @@ -10465,6 +10485,17 @@ </summary> </histogram> +<histogram name="Compositing.Renderer.HitTestTimeToFindClosestLayer" + units="microseconds"> + <owner>yigu@chromium.org</owner> + <summary> + Time spent finding the closest matching layer to a given point whenever we + do hit testing on LayerTreeImpl (in a renderer process). + + Team: animations-dev@chromium.org. + </summary> +</histogram> + <histogram base="true" name="Compositing.Renderer.LayersUpdateTime" units="microseconds"> <owner>threaded-rendering-dev@chromium.org</owner>
diff --git a/tools/python/llvm_symbolizer.py b/tools/python/llvm_symbolizer.py deleted file mode 100644 index fd0df11..0000000 --- a/tools/python/llvm_symbolizer.py +++ /dev/null
@@ -1,110 +0,0 @@ -# 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. - -import logging -import os -import re -import subprocess -import threading - -_CHROME_SRC = os.path.join(os.path.dirname(__file__), os.pardir, os.pardir) -_LLVM_SYMBOLIZER_PATH = os.path.join( - _CHROME_SRC, 'third_party', 'llvm-build', 'Release+Asserts', 'bin', - 'llvm-symbolizer') - -_BINARY = re.compile(r'0b[0,1]+') -_HEX = re.compile(r'0x[0-9,a-e]+') -_OCTAL = re.compile(r'0[0-7]+') - -_UNKNOWN = '<UNKNOWN>' - - -def _CheckValidAddr(addr): - """ - Check whether the addr is valid input to llvm symbolizer. - Valid addr has to be octal, binary, or hex number. - - Args: - addr: addr to be entered to llvm symbolizer. - - Returns: - whether the addr is valid input to llvm symbolizer. - """ - return _HEX.match(addr) or _OCTAL.match(addr) or _BINARY.match(addr) - - -class LLVMSymbolizer(object): - def __init__(self): - """Create a LLVMSymbolizer instance that interacts with the llvm symbolizer. - - The purpose of the LLVMSymbolizer is to get function names and line - numbers of an address from the symbols library. - """ - self._llvm_symbolizer_subprocess = None - # Allow only one thread to call GetSymbolInformation at a time. - self._lock = threading.Lock() - - def Start(self): - """Start the llvm symbolizer subprocess. - - Create a subprocess of the llvm symbolizer executable, which will be used - to retrieve function names etc. - """ - if os.path.isfile(_LLVM_SYMBOLIZER_PATH): - self._llvm_symbolizer_subprocess = subprocess.Popen( - [_LLVM_SYMBOLIZER_PATH], stdout=subprocess.PIPE, stdin=subprocess.PIPE) - else: - logging.error('Cannot find llvm_symbolizer here: %s.' % - _LLVM_SYMBOLIZER_PATH) - self._llvm_symbolizer_subprocess = None - - def Close(self): - """Close the llvm symbolizer subprocess. - - Close the subprocess by closing stdin, stdout and killing the subprocess. - """ - with self._lock: - if self._llvm_symbolizer_subprocess: - self._llvm_symbolizer_subprocess.kill() - self._llvm_symbolizer_subprocess = None - - def __enter__(self): - """Start the llvm symbolizer subprocess.""" - self.Start() - return self - - def __exit__(self, exc_type, exc_val, exc_tb): - """Close the llvm symbolizer subprocess.""" - self.Close() - - def GetSymbolInformation(self, lib, addr): - """Return the corresponding function names and line numbers. - - Args: - lib: library to search for info. - addr: address to look for info. - - Returns: - A list of (function name, line numbers) tuple. - """ - if (self._llvm_symbolizer_subprocess is None or not lib - or not _CheckValidAddr(addr) or not os.path.isfile(lib)): - return [(_UNKNOWN, lib)] - - with self._lock: - self._llvm_symbolizer_subprocess.stdin.write('%s %s\n' % (lib, addr)) - self._llvm_symbolizer_subprocess.stdin.flush() - - result = [] - # Read till see new line, which is a symbol of end of output. - # One line of function name is always followed by one line of line number. - while True: - line = self._llvm_symbolizer_subprocess.stdout.readline() - if line != '\n': - line_numbers = self._llvm_symbolizer_subprocess.stdout.readline() - result.append( - (line[:-1], - line_numbers[:-1])) - else: - return result