diff --git a/DEPS b/DEPS index a0fb00a..c821913 100644 --- a/DEPS +++ b/DEPS
@@ -40,11 +40,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': 'f3b46e5193da843cac07d42fdc36c76c05f7fa77', + 'skia_revision': 'cb2e235e6fb5d9230c41ccf58b865c90ff928f67', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'v8_revision': '25bd579f2ef421e2792c7fd6926f7ba80fd31a12', + 'v8_revision': 'ec22a93f56c44d4e435e1e9fe60fda3487f9cf64', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling swarming_client # and whatever else without interference from each other. @@ -64,7 +64,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. - 'pdfium_revision': 'ccd5be05f61c85754daf5c8155f4932f6d35a55a', + 'pdfium_revision': '4793f3474f2778dbbd225d797f011db0f45e0953', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling openmax_dl # and whatever else without interference from each other. @@ -96,7 +96,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. - 'catapult_revision': '8e06404d6939def91d0020d5082dca52546e3a31', + 'catapult_revision': '1831170b3594c3f34f84a6e9825637f442a2df80', # 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/system/tray/tray_background_view.cc b/ash/system/tray/tray_background_view.cc index b065e96..03d2e7f 100644 --- a/ash/system/tray/tray_background_view.cc +++ b/ash/system/tray/tray_background_view.cc
@@ -116,11 +116,11 @@ cc::PaintFlags background_flags; background_flags.setAntiAlias(true); background_flags.setColor(color_); - gfx::Insets insets = GetMirroredBackgroundInsets( - tray_background_view_->shelf()->IsHorizontalAlignment()); - gfx::Rect bounds = view->GetLocalBounds(); - bounds.Inset(insets); - canvas->DrawRoundRect(bounds, kTrayRoundedBorderRadius, background_flags); + + gfx::Rect bounds = tray_background_view_->GetBackgroundBounds(); + const float dsf = canvas->UndoDeviceScaleFactor(); + canvas->DrawRoundRect(gfx::ScaleToRoundedRect(bounds, dsf), + kTrayRoundedBorderRadius * dsf, background_flags); } // Reference to the TrayBackgroundView for which this is a background. @@ -169,9 +169,8 @@ set_ink_drop_visible_opacity(kShelfInkDropVisibleOpacity); SetLayoutManager(new views::FillLayout); + SetBackground(std::unique_ptr<views::Background>(background_)); - tray_container_->SetBackground( - std::unique_ptr<views::Background>(background_)); AddChildView(tray_container_); tray_event_filter_.reset(new TrayEventFilter); @@ -486,6 +485,13 @@ GetBubbleView()->GetWidget()->SetBounds(target_bounds); } +gfx::Rect TrayBackgroundView::GetBackgroundBounds() const { + gfx::Insets insets = GetBackgroundInsets(); + gfx::Rect bounds = GetLocalBounds(); + bounds.Inset(insets); + return bounds; +} + std::unique_ptr<views::InkDropMask> TrayBackgroundView::CreateInkDropMask() const { return base::MakeUnique<views::RoundRectInkDropMask>( @@ -511,6 +517,10 @@ ActionableView::HandlePerformActionResult(action_performed, event); } +views::PaintInfo::ScaleType TrayBackgroundView::GetPaintScaleType() const { + return views::PaintInfo::ScaleType::kUniformScaling; +} + gfx::Insets TrayBackgroundView::GetBackgroundInsets() const { gfx::Insets insets = GetMirroredBackgroundInsets(shelf_->IsHorizontalAlignment()); @@ -525,11 +535,5 @@ return insets; } -gfx::Rect TrayBackgroundView::GetBackgroundBounds() const { - gfx::Insets insets = GetBackgroundInsets(); - gfx::Rect bounds = GetLocalBounds(); - bounds.Inset(insets); - return bounds; -} } // namespace ash
diff --git a/ash/system/tray/tray_background_view.h b/ash/system/tray/tray_background_view.h index cbd40eb6f..357ca950 100644 --- a/ash/system/tray/tray_background_view.h +++ b/ash/system/tray/tray_background_view.h
@@ -126,6 +126,10 @@ // |close_bubble| is set. void AnimateToTargetBounds(const gfx::Rect& target_bounds, bool close_bubble); + // Helper function that calculates background bounds relative to local bounds + // based on background insets returned from GetBackgroundInsets(). + gfx::Rect GetBackgroundBounds() const; + protected: // ActionableView: std::unique_ptr<views::InkDropMask> CreateInkDropMask() const override; @@ -133,6 +137,7 @@ bool PerformAction(const ui::Event& event) override; void HandlePerformActionResult(bool action_performed, const ui::Event& event) override; + views::PaintInfo::ScaleType GetPaintScaleType() const override; TrayDragController* drag_controller() { return drag_controller_.get(); } void set_drag_controller( @@ -154,9 +159,6 @@ // Helper function that calculates background insets relative to local bounds. gfx::Insets GetBackgroundInsets() const; - // Helper function that calculates background bounds relative to local bounds - // based on background insets returned from GetBackgroundInsets(). - gfx::Rect GetBackgroundBounds() const; // The shelf containing the system tray for this view. Shelf* shelf_;
diff --git a/build/android/gyp/write_build_config.py b/build/android/gyp/write_build_config.py index 392673b..4294c79 100755 --- a/build/android/gyp/write_build_config.py +++ b/build/android/gyp/write_build_config.py
@@ -478,7 +478,12 @@ options.incremental_install_json_path) deps_info['enable_relocation_packing'] = options.enable_relocation_packing - if options.type in ('java_binary', 'java_library', 'android_apk', 'dist_jar'): + requires_javac_classpath = options.type in ( + 'java_binary', 'java_library', 'android_apk', 'dist_jar') + requires_full_classpath = ( + options.type == 'java_prebuilt' or requires_javac_classpath) + + if requires_javac_classpath: # Classpath values filled in below (after applying tested_apk_config). config['javac'] = {} @@ -574,8 +579,9 @@ if options.type in ['android_apk', 'deps_dex']: deps_dex_files = [c['dex_path'] for c in all_library_deps] - if options.type in ('java_binary', 'java_library', 'android_apk', 'dist_jar'): + if requires_javac_classpath: javac_classpath = [c['jar_path'] for c in direct_library_deps] + if requires_full_classpath: java_full_classpath = [c['jar_path'] for c in all_library_deps] if options.extra_classpath_jars: @@ -653,7 +659,7 @@ dex_config = config['final_dex'] dex_config['dependency_dex_files'] = deps_dex_files - if options.type in ('java_binary', 'java_library', 'android_apk', 'dist_jar'): + if requires_javac_classpath: config['javac']['classpath'] = javac_classpath javac_interface_classpath = [ _AsInterfaceJar(p) for p in javac_classpath @@ -661,6 +667,7 @@ javac_interface_classpath += deps_info.get('extra_classpath_jars', []) config['javac']['interface_classpath'] = javac_interface_classpath + if requires_full_classpath: deps_info['java'] = { 'full_classpath': java_full_classpath, }
diff --git a/build/config/android/internal_rules.gni b/build/config/android/internal_rules.gni index 3707e11c..5b8e8458 100644 --- a/build/config/android/internal_rules.gni +++ b/build/config/android/internal_rules.gni
@@ -1172,7 +1172,7 @@ _output_jar_path = invoker.output_jar_path _enable_assert = - defined(invoker.supports_android) && invoker.supports_android && + defined(invoker.enable_build_hooks) && invoker.enable_build_hooks && (is_java_debug || dcheck_always_on) _desugar = defined(invoker.supports_android) && invoker.supports_android @@ -2030,6 +2030,13 @@ _dex_target_name = "${_template_name}__dex" } + _enable_build_hooks = + _supports_android && + (!defined(invoker.no_build_hooks) || !invoker.no_build_hooks) + if (_enable_build_hooks) { + _deps += [ "//build/android/buildhooks:build_hooks_java" ] + } + write_build_config(_build_config_target_name) { type = "java_prebuilt" is_prebuilt_binary = defined(invoker.main_class) @@ -2074,6 +2081,7 @@ } supports_android = _supports_android + enable_build_hooks = _enable_build_hooks build_config = _build_config input_jar_path = invoker.jar_path output_jar_path = _jar_path @@ -2355,6 +2363,8 @@ "alternative_android_sdk_ijar", "alternative_android_sdk_ijar_dep", "alternative_android_sdk_jar", + "enable_build_hooks", + "enable_build_hooks_android", "jar_excluded_patterns", ]) supports_android = _supports_android @@ -2466,7 +2476,12 @@ _accumulated_deps += [ "//build/android/buildhooks:build_hooks_java" ] } - _enable_build_hooks_android = _enable_build_hooks && _requires_android + # Some testonly targets use their own resources and the code being + # tested will use custom resources so there's no need to enable this + # for testonly targets. + _enable_build_hooks_android = + _enable_build_hooks && _requires_android && + (!defined(invoker.testonly) || !invoker.testonly) if (_enable_build_hooks_android) { _accumulated_deps += [ "//build/android/buildhooks:build_hooks_android_java" ] @@ -2630,6 +2645,7 @@ supports_android = _supports_android requires_android = _requires_android emma_instrument = _emma_instrument + enable_build_hooks = _enable_build_hooks deps = _accumulated_deps } _accumulated_deps += [ ":$_compile_java_target" ]
diff --git a/build/config/android/rules.gni b/build/config/android/rules.gni index a9717e7..fa7861d 100644 --- a/build/config/android/rules.gni +++ b/build/config/android/rules.gni
@@ -3054,6 +3054,7 @@ [ "create_srcjar", "deps", + "testonly", ]) if (!defined(deps)) { deps = [] @@ -3110,6 +3111,7 @@ "jar_excluded_patterns", "proguard_configs", "requires_android", + "testonly", ]) if (!defined(deps)) { deps = []
diff --git a/cc/layers/layer.cc b/cc/layers/layer.cc index 3f334cd..850fe8c 100644 --- a/cc/layers/layer.cc +++ b/cc/layers/layer.cc
@@ -109,7 +109,6 @@ // reference to us. DCHECK(!layer_tree_host()); - RemoveFromScrollTree(); RemoveFromClipTree(); // Remove the parent reference from all children and dependents. @@ -721,32 +720,12 @@ if (inputs_.scroll_parent == parent) return; - if (inputs_.scroll_parent) - inputs_.scroll_parent->RemoveScrollChild(this); - inputs_.scroll_parent = parent; - if (inputs_.scroll_parent) - inputs_.scroll_parent->AddScrollChild(this); - SetPropertyTreesNeedRebuild(); SetNeedsCommit(); } -void Layer::AddScrollChild(Layer* child) { - if (!scroll_children_) - scroll_children_.reset(new std::set<Layer*>); - scroll_children_->insert(child); - SetNeedsCommit(); -} - -void Layer::RemoveScrollChild(Layer* child) { - scroll_children_->erase(child); - if (scroll_children_->empty()) - scroll_children_ = nullptr; - SetNeedsCommit(); -} - void Layer::SetClipParent(Layer* ancestor) { DCHECK(IsPropertyChangeAllowed()); if (inputs_.clip_parent == ancestor) @@ -1392,17 +1371,6 @@ return nullptr; } -void Layer::RemoveFromScrollTree() { - if (scroll_children_.get()) { - std::set<Layer*> copy = *scroll_children_; - for (std::set<Layer*>::iterator it = copy.begin(); it != copy.end(); ++it) - (*it)->SetScrollParent(nullptr); - } - - DCHECK(!scroll_children_); - SetScrollParent(nullptr); -} - void Layer::RemoveFromClipTree() { if (clip_children_.get()) { std::set<Layer*> copy = *clip_children_;
diff --git a/cc/layers/layer.h b/cc/layers/layer.h index 7834546..2e61192 100644 --- a/cc/layers/layer.h +++ b/cc/layers/layer.h
@@ -201,11 +201,6 @@ Layer* scroll_parent() { return inputs_.scroll_parent; } - std::set<Layer*>* scroll_children() { return scroll_children_.get(); } - const std::set<Layer*>* scroll_children() const { - return scroll_children_.get(); - } - void SetClipParent(Layer* ancestor); Layer* clip_parent() { return inputs_.clip_parent; } @@ -496,9 +491,6 @@ bool ScrollOffsetAnimationWasInterrupted() const; - void AddScrollChild(Layer* child); - void RemoveScrollChild(Layer* child); - void AddClipChild(Layer* child); void RemoveClipChild(Layer* child); @@ -508,10 +500,6 @@ // This should only be called from RemoveFromParent(). void RemoveChildOrDependent(Layer* child); - // If this layer has a scroll parent, it removes |this| from its list of - // scroll children. - void RemoveFromScrollTree(); - // If this layer has a clip parent, it removes |this| from its list of clip // children. void RemoveFromClipTree(); @@ -668,7 +656,6 @@ // This value is valid only when LayerTreeHost::has_copy_request() is true bool subtree_has_copy_request_ : 1; SkColor safe_opaque_background_color_; - std::unique_ptr<std::set<Layer*>> scroll_children_; std::unique_ptr<std::set<Layer*>> clip_children_;
diff --git a/cc/layers/layer_impl.cc b/cc/layers/layer_impl.cc index 4193566..2cc1480 100644 --- a/cc/layers/layer_impl.cc +++ b/cc/layers/layer_impl.cc
@@ -94,11 +94,8 @@ LayerImpl::~LayerImpl() { DCHECK_EQ(DRAW_MODE_NONE, current_draw_mode_); - layer_tree_impl_->UnregisterLayer(this); - layer_tree_impl_->RemoveFromElementMap(this); - TRACE_EVENT_OBJECT_DELETED_WITH_ID( TRACE_DISABLED_BY_DEFAULT("cc.debug"), "cc::LayerImpl", this); }
diff --git a/cc/layers/layer_impl_test_properties.h b/cc/layers/layer_impl_test_properties.h index e9bfa6d..5347236 100644 --- a/cc/layers/layer_impl_test_properties.h +++ b/cc/layers/layer_impl_test_properties.h
@@ -54,7 +54,6 @@ gfx::Point3F transform_origin; gfx::Transform transform; LayerImpl* scroll_parent; - std::unique_ptr<std::set<LayerImpl*>> scroll_children; LayerImpl* clip_parent; std::unique_ptr<std::set<LayerImpl*>> clip_children; std::vector<std::unique_ptr<viz::CopyOutputRequest>> copy_requests;
diff --git a/cc/layers/layer_unittest.cc b/cc/layers/layer_unittest.cc index a02ab16..e727164 100644 --- a/cc/layers/layer_unittest.cc +++ b/cc/layers/layer_unittest.cc
@@ -605,14 +605,13 @@ EXPECT_EQ(child1, parent->children()[0]); EXPECT_EQ(child2, parent->children()[1]); - EXPECT_SET_NEEDS_COMMIT(2, child1->SetScrollParent(child2.get())); + EXPECT_SET_NEEDS_COMMIT(1, child1->SetScrollParent(child2.get())); EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, child2->RemoveFromParent()); child1->ResetNeedsPushPropertiesForTesting(); - EXPECT_SET_NEEDS_COMMIT(1, child2 = nullptr); - + EXPECT_SET_NEEDS_COMMIT(1, child1->SetScrollParent(nullptr)); EXPECT_TRUE( layer_tree_host_->LayerNeedsPushPropertiesForTesting(child1.get())); @@ -635,17 +634,9 @@ EXPECT_EQ(child1, parent->children()[0]); EXPECT_EQ(child2, parent->children()[1]); - EXPECT_SET_NEEDS_COMMIT(2, child1->SetScrollParent(child2.get())); + EXPECT_SET_NEEDS_COMMIT(1, child1->SetScrollParent(child2.get())); EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, child1->RemoveFromParent()); - - child2->ResetNeedsPushPropertiesForTesting(); - - EXPECT_SET_NEEDS_COMMIT(1, child1 = nullptr); - - EXPECT_TRUE( - layer_tree_host_->LayerNeedsPushPropertiesForTesting(child2.get())); - EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, layer_tree_host_->SetRootLayer(nullptr)); }
diff --git a/cc/layers/painted_scrollbar_layer.cc b/cc/layers/painted_scrollbar_layer.cc index c84f769f6..0ce5723c 100644 --- a/cc/layers/painted_scrollbar_layer.cc +++ b/cc/layers/painted_scrollbar_layer.cc
@@ -23,6 +23,10 @@ #include "ui/gfx/geometry/size_conversions.h" #include "ui/gfx/skia_util.h" +namespace { +static constexpr int kMaxScrollbarDimension = 8192; +}; + namespace cc { std::unique_ptr<LayerImpl> PaintedScrollbarLayer::CreateLayerImpl( @@ -246,13 +250,23 @@ UIResourceBitmap PaintedScrollbarLayer::RasterizeScrollbarPart( const gfx::Rect& layer_rect, - const gfx::Rect& content_rect, + const gfx::Rect& requested_content_rect, ScrollbarPart part) { - DCHECK(!content_rect.size().IsEmpty()); + DCHECK(!requested_content_rect.size().IsEmpty()); DCHECK(!layer_rect.size().IsEmpty()); + gfx::Rect content_rect = requested_content_rect; + + // Pages can end up requesting arbitrarily large scrollbars. Prevent this + // from crashing due to OOM and try something smaller. SkBitmap skbitmap; - skbitmap.allocN32Pixels(content_rect.width(), content_rect.height()); + if (!skbitmap.tryAllocN32Pixels(content_rect.width(), + content_rect.height())) { + content_rect.Intersect( + gfx::Rect(requested_content_rect.x(), requested_content_rect.y(), + kMaxScrollbarDimension, kMaxScrollbarDimension)); + skbitmap.allocN32Pixels(content_rect.width(), content_rect.height()); + } SkiaPaintCanvas canvas(skbitmap); float scale_x =
diff --git a/cc/resources/layer_tree_resource_provider.cc b/cc/resources/layer_tree_resource_provider.cc index c37f56a..45a8703 100644 --- a/cc/resources/layer_tree_resource_provider.cc +++ b/cc/resources/layer_tree_resource_provider.cc
@@ -85,9 +85,6 @@ unverified_sync_tokens.push_back(new_sync_token.GetData()); } - if (compositor_context_provider_) - compositor_context_provider_->ContextSupport()->FlushPendingWork(); - if (!unverified_sync_tokens.empty()) { DCHECK(settings_.delegated_sync_points_required); DCHECK(gl);
diff --git a/cc/scheduler/scheduler_state_machine.cc b/cc/scheduler/scheduler_state_machine.cc index aae639b..f75966b4 100644 --- a/cc/scheduler/scheduler_state_machine.cc +++ b/cc/scheduler/scheduler_state_machine.cc
@@ -355,7 +355,7 @@ return needs_redraw_; } -bool SchedulerStateMachine::ShouldActivatePendingTree() const { +bool SchedulerStateMachine::ShouldActivateSyncTree() const { // There is nothing to activate. if (!has_pending_tree_) return false; @@ -559,7 +559,7 @@ } SchedulerStateMachine::Action SchedulerStateMachine::NextAction() const { - if (ShouldActivatePendingTree()) + if (ShouldActivateSyncTree()) return ACTION_ACTIVATE_SYNC_TREE; if (ShouldCommit()) return ACTION_COMMIT;
diff --git a/cc/scheduler/scheduler_state_machine.h b/cc/scheduler/scheduler_state_machine.h index f5036123..3370c63e 100644 --- a/cc/scheduler/scheduler_state_machine.h +++ b/cc/scheduler/scheduler_state_machine.h
@@ -311,7 +311,7 @@ bool ShouldBeginLayerTreeFrameSinkCreation() const; bool ShouldDraw() const; - bool ShouldActivatePendingTree() const; + bool ShouldActivateSyncTree() const; bool ShouldSendBeginMainFrame() const; bool ShouldCommit() const; bool ShouldPrepareTiles() const;
diff --git a/cc/tiles/tile_manager.cc b/cc/tiles/tile_manager.cc index 8cf047b..650c5cb 100644 --- a/cc/tiles/tile_manager.cc +++ b/cc/tiles/tile_manager.cc
@@ -1401,6 +1401,8 @@ resource_pool_->ReduceResourceUsage(); image_controller_.ReduceMemoryUsage(); + raster_buffer_provider_->Flush(); + // TODO(vmpstr): Temporary check to debug crbug.com/642927. CHECK(tile_task_manager_);
diff --git a/cc/trees/layer_tree_host.cc b/cc/trees/layer_tree_host.cc index 693ab2d1..797e669 100644 --- a/cc/trees/layer_tree_host.cc +++ b/cc/trees/layer_tree_host.cc
@@ -225,6 +225,14 @@ void LayerTreeHost::QueueSwapPromise( std::unique_ptr<SwapPromise> swap_promise) { swap_promise_manager_.QueueSwapPromise(std::move(swap_promise)); + + // Request a main frame if one is not already in progress. This might either + // A) request a commit ahead of time or B) request a commit which is not + // needed because there are not pending updates. If B) then the frame will + // be aborted early and the swap promises will be broken (see + // EarlyOut_NoUpdates). + if (!inside_main_frame_) + SetNeedsAnimate(); } viz::SurfaceSequenceGenerator* LayerTreeHost::GetSurfaceSequenceGenerator() {
diff --git a/cc/trees/layer_tree_host_common_unittest.cc b/cc/trees/layer_tree_host_common_unittest.cc index 1ab182a..48ae628 100644 --- a/cc/trees/layer_tree_host_common_unittest.cc +++ b/cc/trees/layer_tree_host_common_unittest.cc
@@ -5709,9 +5709,6 @@ scroll_parent_clip->SetMasksToBounds(true); scroll_child->test_properties()->scroll_parent = scroll_parent; - scroll_parent->test_properties()->scroll_children = - std::make_unique<std::set<LayerImpl*>>(); - scroll_parent->test_properties()->scroll_children->insert(scroll_child); root->SetBounds(gfx::Size(50, 50)); scroll_parent_border->SetBounds(gfx::Size(40, 40)); @@ -5739,9 +5736,6 @@ scroll_child->SetDrawsContent(true); scroll_child->test_properties()->scroll_parent = scroll_parent; - scroll_parent->test_properties()->scroll_children = - std::make_unique<std::set<LayerImpl*>>(); - scroll_parent->test_properties()->scroll_children->insert(scroll_child); root->SetBounds(gfx::Size(50, 50)); scroll_child_target->SetBounds(gfx::Size(50, 50)); @@ -5841,9 +5835,6 @@ scroll_child->SetBounds(gfx::Size(50, 50)); scroll_child->test_properties()->scroll_parent = scroll_parent; - scroll_parent->test_properties()->scroll_children = - std::make_unique<std::set<LayerImpl*>>(); - scroll_parent->test_properties()->scroll_children->insert(scroll_child); ExecuteCalculateDrawProperties(root); @@ -5884,15 +5875,8 @@ scroll_grandparent_clip->SetMasksToBounds(true); scroll_child->test_properties()->scroll_parent = scroll_parent; - scroll_parent->test_properties()->scroll_children = - std::make_unique<std::set<LayerImpl*>>(); - scroll_parent->test_properties()->scroll_children->insert(scroll_child); scroll_parent_border->test_properties()->scroll_parent = scroll_grandparent; - scroll_grandparent->test_properties()->scroll_children = - std::make_unique<std::set<LayerImpl*>>(); - scroll_grandparent->test_properties()->scroll_children->insert( - scroll_parent_border); root->SetBounds(gfx::Size(50, 50)); scroll_grandparent_border->SetBounds(gfx::Size(40, 40)); @@ -5957,15 +5941,8 @@ scroll_grandparent_clip->SetMasksToBounds(true); scroll_child->test_properties()->scroll_parent = scroll_parent; - scroll_parent->test_properties()->scroll_children = - std::make_unique<std::set<LayerImpl*>>(); - scroll_parent->test_properties()->scroll_children->insert(scroll_child); scroll_parent_border->test_properties()->scroll_parent = scroll_grandparent; - scroll_grandparent->test_properties()->scroll_children = - std::make_unique<std::set<LayerImpl*>>(); - scroll_grandparent->test_properties()->scroll_children->insert( - scroll_parent_border); root->SetBounds(gfx::Size(50, 50)); scroll_grandparent_border->SetBounds(gfx::Size(40, 40)); @@ -8593,9 +8570,6 @@ scroll_parent->SetDrawsContent(true); scroll_child->test_properties()->scroll_parent = scroll_parent; - scroll_parent->test_properties()->scroll_children = - std::make_unique<std::set<LayerImpl*>>(); - scroll_parent->test_properties()->scroll_children->insert(scroll_child); ExecuteCalculateDrawProperties(root); EXPECT_EQ(gfx::Rect(25, 25), scroll_child->visible_layer_rect()); @@ -9668,9 +9642,6 @@ LayerImpl* scroll_parent = AddChild<LayerImpl>(scroll_clip); scroll_child->test_properties()->scroll_parent = scroll_parent; - scroll_parent->test_properties()->scroll_children = - std::make_unique<std::set<LayerImpl*>>(); - scroll_parent->test_properties()->scroll_children->insert(scroll_child); scroll_parent->SetDrawsContent(true); scroll_child->SetDrawsContent(true); @@ -10427,5 +10398,51 @@ EXPECT_EQ(gfx::Rect(20, 20), cache_surface->visible_layer_rect()); } +TEST_F(LayerTreeHostCommonTest, BuildPropertyNodesForScrollChildrenInOrder) { + // This test is intended to test against a bug that scroll children were + // visited in unspecified order, which can cause data dependency to fail + // while resolving clip parent. + + // Try multiple times because in the original bug the probability to fail + // was 50%, depends on the hash values. + int trial = 10; + while (trial--) { + scoped_refptr<Layer> root = Layer::Create(); + scoped_refptr<Layer> scroller = Layer::Create(); + scoped_refptr<Layer> scroll_sibling_1 = Layer::Create(); + scoped_refptr<Layer> scroll_sibling_2 = Layer::Create(); + scoped_refptr<Layer> clip_escaper = Layer::Create(); + + root->SetBounds(gfx::Size(100, 100)); + scroll_sibling_1->SetBounds(gfx::Size(10, 20)); + scroll_sibling_1->SetMasksToBounds(true); + scroll_sibling_2->SetBounds(gfx::Size(20, 10)); + scroll_sibling_2->SetMasksToBounds(true); + clip_escaper->SetBounds(gfx::Size(30, 30)); + clip_escaper->SetIsDrawable(true); + + host()->SetRootLayer(root); + root->AddChild(scroller.get()); + root->AddChild(scroll_sibling_1.get()); + root->AddChild(scroll_sibling_2.get()); + scroll_sibling_2->AddChild(clip_escaper.get()); + + // Also randomize scroll children insertion order. + if (trial & 1) { + scroll_sibling_1->SetScrollParent(scroller.get()); + scroll_sibling_2->SetScrollParent(scroller.get()); + } else { + scroll_sibling_2->SetScrollParent(scroller.get()); + scroll_sibling_1->SetScrollParent(scroller.get()); + } + clip_escaper->SetClipParent(scroll_sibling_1.get()); + + ExecuteCalculateDrawProperties(root.get()); + + EXPECT_EQ(scroll_sibling_1->clip_tree_index(), + clip_escaper->clip_tree_index()); + } +} + } // namespace } // namespace cc
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc index c384d0c..e3dc44b 100644 --- a/cc/trees/layer_tree_host_impl_unittest.cc +++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -2388,10 +2388,6 @@ viewport_scroll->test_properties()->AddChild(std::move(scroll_child_clip)); child_clip->test_properties()->scroll_parent = parent; - std::unique_ptr<std::set<LayerImpl*>> scroll_children( - new std::set<LayerImpl*>); - scroll_children->insert(child_clip); - parent->test_properties()->scroll_children = std::move(scroll_children); host_impl_->active_tree()->BuildPropertyTreesForTesting(); DrawFrame();
diff --git a/cc/trees/layer_tree_host_unittest.cc b/cc/trees/layer_tree_host_unittest.cc index 4b9e1b2..ad27600 100644 --- a/cc/trees/layer_tree_host_unittest.cc +++ b/cc/trees/layer_tree_host_unittest.cc
@@ -5358,6 +5358,63 @@ int* set_needs_commit_count_; }; +class LayerTreeHostTestSwapPromiseDuringCommit : public LayerTreeHostTest { + protected: + LayerTreeHostTestSwapPromiseDuringCommit() {} + + void WillBeginMainFrame() override { + if (TestEnded()) + return; + + std::unique_ptr<SwapPromise> swap_promise( + new TestSwapPromise(&swap_promise_result_[0])); + int set_needs_commit_count = 0; + int set_needs_redraw_count = 0; + + { + std::unique_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor( + new SimpleSwapPromiseMonitor(layer_tree_host(), NULL, + &set_needs_commit_count, + &set_needs_redraw_count)); + layer_tree_host()->QueueSwapPromise(std::move(swap_promise)); + // Queueing a swap promise from WillBeginMainFrame should not cause + // another commit to be scheduled. + EXPECT_EQ(0, set_needs_commit_count); + } + } + + void BeginTest() override { PostSetNeedsCommitToMainThread(); } + + void DidBeginMainFrame() override { + if (TestEnded()) + return; + + std::unique_ptr<SwapPromise> swap_promise( + new TestSwapPromise(&swap_promise_result_[1])); + int set_needs_commit_count = 0; + int set_needs_redraw_count = 0; + + { + std::unique_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor( + new SimpleSwapPromiseMonitor(layer_tree_host(), NULL, + &set_needs_commit_count, + &set_needs_redraw_count)); + layer_tree_host()->QueueSwapPromise(std::move(swap_promise)); + // Queueing a swap promise from DidBeginMainFrame should cause a + // subsequent main frame to be scheduled. + EXPECT_EQ(1, set_needs_commit_count); + } + + EndTest(); + } + + void AfterTest() override {} + + TestSwapPromiseResult swap_promise_result_[2]; +}; + +MULTI_THREAD_TEST_F(LayerTreeHostTestSwapPromiseDuringCommit); + class LayerTreeHostTestSimpleSwapPromiseMonitor : public LayerTreeHostTest { public: void BeginTest() override { PostSetNeedsCommitToMainThread(); }
diff --git a/cc/trees/layer_tree_impl.cc b/cc/trees/layer_tree_impl.cc index aba6d6b..d0d582e 100644 --- a/cc/trees/layer_tree_impl.cc +++ b/cc/trees/layer_tree_impl.cc
@@ -658,52 +658,52 @@ if (layer_list_.empty()) return; + // Note we lazily delete element ids from the |element_id_to_xxx| + // maps below if we find they have no node present in their + // respective tree. This can be the case if the layer associated + // with that element id has been removed. + auto element_id_to_opacity = element_id_to_opacity_animations_.begin(); while (element_id_to_opacity != element_id_to_opacity_animations_.end()) { const ElementId id = element_id_to_opacity->first; - if (EffectNode* node = - property_trees_.effect_tree.FindNodeFromElementId(id)) { - if (!node->is_currently_animating_opacity || - node->opacity == element_id_to_opacity->second) { - element_id_to_opacity_animations_.erase(element_id_to_opacity++); - continue; - } - node->opacity = element_id_to_opacity->second; - property_trees_.effect_tree.set_needs_update(true); + EffectNode* node = property_trees_.effect_tree.FindNodeFromElementId(id); + if (!node || !node->is_currently_animating_opacity || + node->opacity == element_id_to_opacity->second) { + element_id_to_opacity_animations_.erase(element_id_to_opacity++); + continue; } + node->opacity = element_id_to_opacity->second; + property_trees_.effect_tree.set_needs_update(true); ++element_id_to_opacity; } auto element_id_to_filter = element_id_to_filter_animations_.begin(); while (element_id_to_filter != element_id_to_filter_animations_.end()) { const ElementId id = element_id_to_filter->first; - if (EffectNode* node = - property_trees_.effect_tree.FindNodeFromElementId(id)) { - if (!node->is_currently_animating_filter || - node->filters == element_id_to_filter->second) { - element_id_to_filter_animations_.erase(element_id_to_filter++); - continue; - } - node->filters = element_id_to_filter->second; - property_trees_.effect_tree.set_needs_update(true); + EffectNode* node = property_trees_.effect_tree.FindNodeFromElementId(id); + if (!node || !node->is_currently_animating_filter || + node->filters == element_id_to_filter->second) { + element_id_to_filter_animations_.erase(element_id_to_filter++); + continue; } + node->filters = element_id_to_filter->second; + property_trees_.effect_tree.set_needs_update(true); ++element_id_to_filter; } auto element_id_to_transform = element_id_to_transform_animations_.begin(); while (element_id_to_transform != element_id_to_transform_animations_.end()) { const ElementId id = element_id_to_transform->first; - if (TransformNode* node = - property_trees_.transform_tree.FindNodeFromElementId(id)) { - if (!node->is_currently_animating || - node->local == element_id_to_transform->second) { - element_id_to_transform_animations_.erase(element_id_to_transform++); - continue; - } - node->local = element_id_to_transform->second; - node->needs_local_transform_update = true; - property_trees_.transform_tree.set_needs_update(true); + TransformNode* node = + property_trees_.transform_tree.FindNodeFromElementId(id); + if (!node || !node->is_currently_animating || + node->local == element_id_to_transform->second) { + element_id_to_transform_animations_.erase(element_id_to_transform++); + continue; } + node->local = element_id_to_transform->second; + node->needs_local_transform_update = true; + property_trees_.transform_tree.set_needs_update(true); ++element_id_to_transform; } @@ -1229,9 +1229,6 @@ void LayerTreeImpl::UnregisterLayer(LayerImpl* layer) { DCHECK(LayerById(layer->id())); layers_that_should_push_properties_.erase(layer); - element_id_to_transform_animations_.erase(layer->element_id()); - element_id_to_opacity_animations_.erase(layer->element_id()); - element_id_to_filter_animations_.erase(layer->element_id()); layer_id_map_.erase(layer->id()); }
diff --git a/cc/trees/layer_tree_impl_unittest.cc b/cc/trees/layer_tree_impl_unittest.cc index 656ba60..b68556a 100644 --- a/cc/trees/layer_tree_impl_unittest.cc +++ b/cc/trees/layer_tree_impl_unittest.cc
@@ -1065,9 +1065,6 @@ // This should cause scroll child and its descendants to be affected by // |child|'s clip. scroll_child->test_properties()->scroll_parent = child.get(); - child->test_properties()->scroll_children = - std::make_unique<std::set<LayerImpl*>>(); - child->test_properties()->scroll_children->insert(scroll_child.get()); grand_child->SetBounds(gfx::Size(200, 200)); grand_child->SetDrawsContent(true);
diff --git a/cc/trees/property_tree_builder.cc b/cc/trees/property_tree_builder.cc index 9a57979..089eaa4 100644 --- a/cc/trees/property_tree_builder.cc +++ b/cc/trees/property_tree_builder.cc
@@ -53,29 +53,34 @@ template <typename LayerType> class PropertyTreeBuilderContext { public: - PropertyTreeBuilderContext(const LayerType* page_scale_layer, + PropertyTreeBuilderContext(LayerType* root_layer, + const LayerType* page_scale_layer, const LayerType* inner_viewport_scroll_layer, const LayerType* outer_viewport_scroll_layer, const LayerType* overscroll_elasticity_layer, const gfx::Vector2dF& elastic_overscroll, float page_scale_factor, const gfx::Transform& device_transform, - PropertyTrees& property_trees) - : page_scale_layer_(page_scale_layer), + PropertyTrees* property_trees) + : root_layer_(root_layer), + page_scale_layer_(page_scale_layer), inner_viewport_scroll_layer_(inner_viewport_scroll_layer), outer_viewport_scroll_layer_(outer_viewport_scroll_layer), overscroll_elasticity_layer_(overscroll_elasticity_layer), elastic_overscroll_(elastic_overscroll), page_scale_factor_(page_scale_factor), device_transform_(device_transform), - property_trees_(property_trees), - transform_tree_(property_trees.transform_tree), - clip_tree_(property_trees.clip_tree), - effect_tree_(property_trees.effect_tree), - scroll_tree_(property_trees.scroll_tree) {} + property_trees_(*property_trees), + transform_tree_(property_trees->transform_tree), + clip_tree_(property_trees->clip_tree), + effect_tree_(property_trees->effect_tree), + scroll_tree_(property_trees->scroll_tree) { + InitializeScrollChildrenMap(); + } - void BuildPropertyTrees(LayerType* root_layer, - float device_scale_factor, + void InitializeScrollChildrenMap(); + + void BuildPropertyTrees(float device_scale_factor, const gfx::Rect& viewport, SkColor root_background_color) const; @@ -106,6 +111,7 @@ LayerType* layer, DataForRecursion<LayerType>* data_for_children) const; + LayerType* root_layer_; const LayerType* page_scale_layer_; const LayerType* inner_viewport_scroll_layer_; const LayerType* outer_viewport_scroll_layer_; @@ -118,6 +124,7 @@ ClipTree& clip_tree_; EffectTree& effect_tree_; ScrollTree& scroll_tree_; + std::multimap<const LayerType*, LayerType*> scroll_children_map_; }; static LayerPositionConstraint PositionConstraint(Layer* layer) { @@ -161,14 +168,6 @@ return layer->test_properties()->scroll_parent; } -static std::set<Layer*>* ScrollChildren(Layer* layer) { - return layer->scroll_children(); -} - -static std::set<LayerImpl*>* ScrollChildren(LayerImpl* layer) { - return layer->test_properties()->scroll_children.get(); -} - static Layer* ClipParent(Layer* layer) { return layer->clip_parent(); } @@ -1213,21 +1212,18 @@ SetLayerPropertyChangedForChild(layer, current_child); if (!ScrollParent(current_child)) { BuildPropertyTreesInternal(current_child, data_for_children); - } else { - // The child should be included in its scroll parent's list of scroll - // children. - DCHECK(ScrollChildren(ScrollParent(current_child))->count(current_child)); } } - if (ScrollChildren(layer)) { - for (LayerType* scroll_child : *ScrollChildren(layer)) { - DCHECK_EQ(ScrollParent(scroll_child), layer); - DCHECK(Parent(scroll_child)); - data_for_children.effect_tree_parent = - Parent(scroll_child)->effect_tree_index(); - BuildPropertyTreesInternal(scroll_child, data_for_children); - } + auto scroll_children_range = scroll_children_map_.equal_range(layer); + for (auto it = scroll_children_range.first; + it != scroll_children_range.second; ++it) { + LayerType* scroll_child = it->second; + DCHECK_EQ(ScrollParent(scroll_child), layer); + DCHECK(Parent(scroll_child)); + data_for_children.effect_tree_parent = + Parent(scroll_child)->effect_tree_index(); + BuildPropertyTreesInternal(scroll_child, data_for_children); } if (MaskLayer(layer)) { @@ -1242,6 +1238,13 @@ } } +const LayerTreeHost& AllLayerRange(const Layer* root_layer) { + return *root_layer->layer_tree_host(); +} +const LayerTreeImpl& AllLayerRange(const LayerImpl* root_layer) { + return *root_layer->layer_tree_impl(); +} + } // namespace Layer* PropertyTreeBuilder::FindFirstScrollableLayer(Layer* layer) { @@ -1262,7 +1265,6 @@ template <typename LayerType> void PropertyTreeBuilderContext<LayerType>::BuildPropertyTrees( - LayerType* root_layer, float device_scale_factor, const gfx::Rect& viewport, SkColor root_background_color) const { @@ -1274,10 +1276,10 @@ &property_trees_, overscroll_elasticity_layer_, elastic_overscroll_); clip_tree_.SetViewportClip(gfx::RectF(viewport)); float page_scale_factor_for_root = - page_scale_layer_ == root_layer ? page_scale_factor_ : 1.f; + page_scale_layer_ == root_layer_ ? page_scale_factor_ : 1.f; transform_tree_.SetRootTransformsAndScales( device_scale_factor, page_scale_factor_for_root, device_transform_, - root_layer->position()); + root_layer_->position()); return; } @@ -1313,7 +1315,7 @@ data_for_recursion.clip_tree_parent = clip_tree_.Insert(root_clip, ClipTree::kRootNodeId); - BuildPropertyTreesInternal(root_layer, data_for_recursion); + BuildPropertyTreesInternal(root_layer_, data_for_recursion); property_trees_.needs_rebuild = false; // The transform tree is kept up to date as it is built, but the @@ -1326,17 +1328,20 @@ } #if DCHECK_IS_ON() -static void CheckScrollAndClipPointersForLayer(Layer* layer) { +template <typename LayerType> +static void CheckDanglingScrollParent(LayerType* root_layer) { + std::unordered_set<const LayerType*> layers; + for (const auto* layer : AllLayerRange(root_layer)) + layers.insert(layer); + for (auto* layer : AllLayerRange(root_layer)) + DCHECK(!ScrollParent(layer) || + layers.find(ScrollParent(layer)) != layers.end()); +} + +static void CheckClipPointersForLayer(Layer* layer) { if (!layer) return; - if (layer->scroll_children()) { - for (std::set<Layer*>::iterator it = layer->scroll_children()->begin(); - it != layer->scroll_children()->end(); ++it) { - DCHECK_EQ((*it)->scroll_parent(), layer); - } - } - if (layer->clip_children()) { for (std::set<Layer*>::iterator it = layer->clip_children()->begin(); it != layer->clip_children()->end(); ++it) { @@ -1346,6 +1351,17 @@ } #endif +template <typename LayerType> +void PropertyTreeBuilderContext<LayerType>::InitializeScrollChildrenMap() { +#if DCHECK_IS_ON() + CheckDanglingScrollParent(root_layer_); +#endif + for (auto* layer : AllLayerRange(root_layer_)) { + if (ScrollParent(layer)) + scroll_children_map_.emplace(ScrollParent(layer), layer); + } +} + void PropertyTreeBuilder::BuildPropertyTrees( Layer* root_layer, const Layer* page_scale_layer, @@ -1366,13 +1382,13 @@ if (root_layer->layer_tree_host()->has_copy_request()) UpdateSubtreeHasCopyRequestRecursive(root_layer); PropertyTreeBuilderContext<Layer>( - page_scale_layer, inner_viewport_scroll_layer, + root_layer, page_scale_layer, inner_viewport_scroll_layer, outer_viewport_scroll_layer, overscroll_elasticity_layer, - elastic_overscroll, page_scale_factor, device_transform, *property_trees) - .BuildPropertyTrees(root_layer, device_scale_factor, viewport, color); + elastic_overscroll, page_scale_factor, device_transform, property_trees) + .BuildPropertyTrees(device_scale_factor, viewport, color); #if DCHECK_IS_ON() - for (auto* layer : *root_layer->layer_tree_host()) - CheckScrollAndClipPointersForLayer(layer); + for (auto* layer : AllLayerRange(root_layer)) + CheckClipPointersForLayer(layer); #endif property_trees->ResetCachedData(); // During building property trees, all copy requests are moved from layers to @@ -1405,10 +1421,10 @@ UpdateSubtreeHasCopyRequestRecursive(root_layer); PropertyTreeBuilderContext<LayerImpl>( - page_scale_layer, inner_viewport_scroll_layer, + root_layer, page_scale_layer, inner_viewport_scroll_layer, outer_viewport_scroll_layer, overscroll_elasticity_layer, - elastic_overscroll, page_scale_factor, device_transform, *property_trees) - .BuildPropertyTrees(root_layer, device_scale_factor, viewport, color); + elastic_overscroll, page_scale_factor, device_transform, property_trees) + .BuildPropertyTrees(device_scale_factor, viewport, color); property_trees->effect_tree.CreateOrReuseRenderSurfaces( &render_surfaces, root_layer->layer_tree_impl()); property_trees->ResetCachedData();
diff --git a/cc/trees/tree_synchronizer_unittest.cc b/cc/trees/tree_synchronizer_unittest.cc index 1afd24a..f7e7e9f9 100644 --- a/cc/trees/tree_synchronizer_unittest.cc +++ b/cc/trees/tree_synchronizer_unittest.cc
@@ -117,13 +117,6 @@ effect_tree.Node(layer_impl->effect_tree_index())->mask_layer_id); } - const Layer* layer_scroll_parent = layer->scroll_parent(); - - if (layer_scroll_parent) { - ASSERT_TRUE(layer_scroll_parent->scroll_children()->find(layer) != - layer_scroll_parent->scroll_children()->end()); - } - const Layer* layer_clip_parent = layer->clip_parent(); if (layer_clip_parent) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/StackLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/StackLayout.java index 7a19f00..b643dfc 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/StackLayout.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/StackLayout.java
@@ -89,8 +89,6 @@ /** Rectangles that defines the area where each stack need to be laid out. */ private final RectF[] mStackRects; - private final RectF mCachedRect = new RectF(); - private int mStackAnimationCount; private float mFlingSpeed; // pixel/ms @@ -876,6 +874,7 @@ } float getTopHeightOffset() { + if (FeatureUtilities.isChromeHomeModernEnabled()) return MODERN_TOP_MARGIN_DP; if (FeatureUtilities.isChromeHomeEnabled()) return 0; return (StackLayout.this.getHeight() - getHeightMinusBrowserControls()) * mStackOffsetYPercent; @@ -1334,16 +1333,12 @@ resourceManager, fullscreenManager); // If the browser controls are at the bottom make sure to use theme colors for this layout // specifically. - mCachedRect.set(viewport); if (fullscreenManager.areBrowserControlsAtBottom() && mLayoutTabs != null) { for (LayoutTab t : mLayoutTabs) t.setForceDefaultThemeColor(false); - if (FeatureUtilities.isChromeHomeModernEnabled()) { - mCachedRect.offset(0, MODERN_TOP_MARGIN_DP * mDpToPx); - } } assert mSceneLayer != null; - mSceneLayer.pushLayers(getContext(), mCachedRect, contentViewport, this, layerTitleCache, + mSceneLayer.pushLayers(getContext(), viewport, contentViewport, this, layerTitleCache, tabContentManager, resourceManager, fullscreenManager); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/metrics/UmaSessionStats.java b/chrome/android/java/src/org/chromium/chrome/browser/metrics/UmaSessionStats.java index ab2d197e..7e51bd5 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/metrics/UmaSessionStats.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/metrics/UmaSessionStats.java
@@ -143,10 +143,6 @@ .apply(); } - public static void logRendererCrash() { - nativeLogRendererCrash(); - } - /** * Updates the metrics services based on a change of consent. This can happen during first-run * flow, and when the user changes their preferences. @@ -205,7 +201,6 @@ private static native void nativeUpdateMetricsServiceState(boolean mayUpload); private native void nativeUmaResumeSession(long nativeUmaSessionStats); private native void nativeUmaEndSession(long nativeUmaSessionStats); - private static native void nativeLogRendererCrash(); private static native void nativeRegisterExternalExperiment( String studyName, int[] experimentIds); private static native void nativeRegisterSyntheticFieldTrial(
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabWebContentsObserver.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabWebContentsObserver.java index b2b2d68..34c9e9fa 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabWebContentsObserver.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabWebContentsObserver.java
@@ -17,7 +17,6 @@ import org.chromium.chrome.browser.AppHooks; import org.chromium.chrome.browser.fullscreen.FullscreenManager; import org.chromium.chrome.browser.media.MediaCaptureNotificationService; -import org.chromium.chrome.browser.metrics.UmaSessionStats; import org.chromium.chrome.browser.metrics.UmaUtils; import org.chromium.chrome.browser.policy.PolicyAuditor; import org.chromium.chrome.browser.policy.PolicyAuditor.AuditEvent; @@ -125,7 +124,7 @@ rendererCrashStatus = TAB_RENDERER_CRASH_STATUS_SHOWN_IN_FOREGROUND_APP; mTab.showSadTab(); // This is necessary to correlate histogram data with stability counts. - UmaSessionStats.logRendererCrash(); + RecordHistogram.recordBooleanHistogram("Stability.Android.RendererCrash", true); } RecordHistogram.recordEnumeratedHistogram( "Tab.RendererCrashStatus", rendererCrashStatus, TAB_RENDERER_CRASH_STATUS_MAX);
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 4b9d900..847759f 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -1693,6 +1693,7 @@ "//crypto:platform", "//device/base", "//device/bluetooth:mojo", + "//device/hid", "//device/usb/mojo", "//device/usb/public/interfaces", "//device/vr/features",
diff --git a/chrome/browser/android/metrics/uma_session_stats.cc b/chrome/browser/android/metrics/uma_session_stats.cc index f2a557f1..d4b229ce 100644 --- a/chrome/browser/android/metrics/uma_session_stats.cc +++ b/chrome/browser/android/metrics/uma_session_stats.cc
@@ -143,18 +143,6 @@ may_upload); } -// Renderer process crashed in the foreground. -static void LogRendererCrash(JNIEnv*, const JavaParamRef<jclass>&) { - DCHECK(g_browser_process); - // Increment the renderer crash count in stability metrics. - PrefService* pref = g_browser_process->local_state(); - DCHECK(pref); - int value = pref->GetInteger(metrics::prefs::kStabilityRendererCrashCount); - pref->SetInteger(metrics::prefs::kStabilityRendererCrashCount, value + 1); - // Migrate proto to histogram to repurpose proto count. - UMA_HISTOGRAM_BOOLEAN("Stability.Android.RendererCrash", true); -} - static void RegisterExternalExperiment( JNIEnv* env, const JavaParamRef<jclass>& clazz,
diff --git a/chrome/browser/android/vr_shell/gl_browser_interface.h b/chrome/browser/android/vr_shell/gl_browser_interface.h index dd0abb8..0942b937 100644 --- a/chrome/browser/android/vr_shell/gl_browser_interface.h +++ b/chrome/browser/android/vr_shell/gl_browser_interface.h
@@ -43,6 +43,7 @@ virtual void ToggleCardboardGamepad(bool enabled) = 0; virtual void OnGlInitialized(unsigned int content_texture_id) = 0; virtual void OnWebVrFrameAvailable() = 0; + virtual void OnWebVrTimedOut() = 0; virtual void OnProjMatrixChanged(const gfx::Transform& proj_matrix) = 0; };
diff --git a/chrome/browser/android/vr_shell/vr_gl_thread.cc b/chrome/browser/android/vr_shell/vr_gl_thread.cc index 49073a6..5d77c9a5 100644 --- a/chrome/browser/android/vr_shell/vr_gl_thread.cc +++ b/chrome/browser/android/vr_shell/vr_gl_thread.cc
@@ -255,6 +255,11 @@ scene_manager_->OnWebVrFrameAvailable(); } +void VrGLThread::OnWebVrTimedOut() { + DCHECK(task_runner()->BelongsToCurrentThread()); + scene_manager_->OnWebVrTimedOut(); +} + void VrGLThread::OnProjMatrixChanged(const gfx::Transform& proj_matrix) { DCHECK(task_runner()->BelongsToCurrentThread()); scene_manager_->OnProjMatrixChanged(proj_matrix);
diff --git a/chrome/browser/android/vr_shell/vr_gl_thread.h b/chrome/browser/android/vr_shell/vr_gl_thread.h index 27767352..6d7c4e7 100644 --- a/chrome/browser/android/vr_shell/vr_gl_thread.h +++ b/chrome/browser/android/vr_shell/vr_gl_thread.h
@@ -60,6 +60,7 @@ void ToggleCardboardGamepad(bool enabled) override; void OnGlInitialized(unsigned int content_texture_id) override; void OnWebVrFrameAvailable() override; + void OnWebVrTimedOut() override; void OnProjMatrixChanged(const gfx::Transform& proj_matrix) override; // vr::UiBrowserInterface implementation (UI calling to VrShell).
diff --git a/chrome/browser/android/vr_shell/vr_shell_gl.cc b/chrome/browser/android/vr_shell/vr_shell_gl.cc index a44a6e0..dd51bf9 100644 --- a/chrome/browser/android/vr_shell/vr_shell_gl.cc +++ b/chrome/browser/android/vr_shell/vr_shell_gl.cc
@@ -87,6 +87,8 @@ static constexpr base::TimeDelta kWebVRFenceCheckTimeout = base::TimeDelta::FromMicroseconds(2000); +static constexpr int kWebVrInitialFrameTimeoutSeconds = 5; + // Provides the direction the head is looking towards as a 3x1 unit vector. gfx::Vector3dF GetForwardVector(const gfx::Transform& head_pose) { // Same as multiplying the inverse of the rotation component of the matrix by @@ -368,6 +370,7 @@ closePresentationBindings(); submit_client_.Bind(std::move(submit_client_info)); binding_.Bind(std::move(request)); + ScheduleWebVrFrameTimeout(); } void VrShellGl::OnContentFrameAvailable() { @@ -393,6 +396,31 @@ browser_->OnWebVrFrameAvailable(); DrawFrame(frame_index); + if (web_vr_mode_) { + ++webvr_frames_received_; + ScheduleWebVrFrameTimeout(); + } else { + webvr_frame_timeout_.Cancel(); + } +} + +void VrShellGl::ScheduleWebVrFrameTimeout() { + // TODO(mthiesse): We should also timeout after the initial frame to prevent + // bad experiences, but we have to be careful to handle things like splash + // screens correctly. For now just ensure we receive a first frame. + if (webvr_frames_received_ > 0) { + webvr_frame_timeout_.Cancel(); + return; + } + webvr_frame_timeout_.Reset( + base::Bind(&VrShellGl::OnWebVrFrameTimedOut, base::Unretained(this))); + task_runner_->PostDelayedTask( + FROM_HERE, webvr_frame_timeout_.callback(), + base::TimeDelta::FromSeconds(kWebVrInitialFrameTimeoutSeconds)); +} + +void VrShellGl::OnWebVrFrameTimedOut() { + browser_->OnWebVrTimedOut(); } void VrShellGl::GvrInit(gvr_context* gvr_api) { @@ -1049,26 +1077,36 @@ vsync_helper_.CancelVSyncRequest(); controller_->OnPause(); gvr_api_->PauseTracking(); + webvr_frame_timeout_.Cancel(); } void VrShellGl::OnResume() { gvr_api_->RefreshViewerProfile(); gvr_api_->ResumeTracking(); controller_->OnResume(); - if (ready_to_draw_) { - vsync_helper_.CancelVSyncRequest(); - OnVSync(base::TimeTicks::Now()); - } + if (!ready_to_draw_) + return; + vsync_helper_.CancelVSyncRequest(); + OnVSync(base::TimeTicks::Now()); + if (web_vr_mode_ && submit_client_) + ScheduleWebVrFrameTimeout(); } void VrShellGl::SetWebVrMode(bool enabled) { web_vr_mode_ = enabled; + if (web_vr_mode_ && submit_client_) { + ScheduleWebVrFrameTimeout(); + } else { + webvr_frame_timeout_.Cancel(); + webvr_frames_received_ = 0; + } + if (cardboard_) { browser_->ToggleCardboardGamepad(enabled); } - if (!enabled) { + if (!web_vr_mode_) { closePresentationBindings(); } } @@ -1242,6 +1280,7 @@ } void VrShellGl::closePresentationBindings() { + webvr_frame_timeout_.Cancel(); submit_client_.reset(); if (!callback_.is_null()) { // When this Presentation provider is going away we have to respond to
diff --git a/chrome/browser/android/vr_shell/vr_shell_gl.h b/chrome/browser/android/vr_shell/vr_shell_gl.h index 0d6fd66..a55c259 100644 --- a/chrome/browser/android/vr_shell/vr_shell_gl.h +++ b/chrome/browser/android/vr_shell/vr_shell_gl.h
@@ -158,8 +158,12 @@ const gfx::Vector3dF& controller_direction); void SendGestureToContent(std::unique_ptr<blink::WebInputEvent> event); void CreateUiSurface(); + void OnContentFrameAvailable(); void OnWebVRFrameAvailable(); + void ScheduleWebVrFrameTimeout(); + void OnWebVrFrameTimedOut(); + int64_t GetPredictedFrameTimeNanos(); void OnVSync(base::TimeTicks frame_time); @@ -256,6 +260,8 @@ // Larger than frame_index_ so it can be initialized out-of-band. uint16_t last_frame_index_ = -1; + uint64_t webvr_frames_received_ = 0; + // Attributes for gesture detection while holding app button. gfx::Vector3dF controller_start_direction_; @@ -275,6 +281,8 @@ AndroidVSyncHelper vsync_helper_; + base::CancelableCallback<void()> webvr_frame_timeout_; + base::WeakPtrFactory<VrShellGl> weak_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(VrShellGl);
diff --git a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc index d8f5c8a..ee63812 100644 --- a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc +++ b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc
@@ -698,6 +698,11 @@ content::BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB)) { base::RecordAction(UserMetricsAction("ClearBrowsingData_Cookies")); + HostContentSettingsMapFactory::GetForProfile(profile_) + ->ClearSettingsForOneTypeWithPredicate( + CONTENT_SETTINGS_TYPE_CLIENT_HINTS, base::Time(), + base::Bind(&WebsiteSettingsFilterAdapter, filter)); + // Clear the safebrowsing cookies only if time period is for "all time". It // doesn't make sense to apply the time period of deleting in the last X // hours/days to the safebrowsing cookies since they aren't the result of
diff --git a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc index c74e620..b167729 100644 --- a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc +++ b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc
@@ -1756,6 +1756,106 @@ EXPECT_EQ(CONTENT_SETTING_ALLOW, host_settings[0].GetContentSetting()); } +TEST_F(ChromeBrowsingDataRemoverDelegateTest, RemoveSelectedClientHints) { + // Add our settings. + HostContentSettingsMap* host_content_settings_map = + HostContentSettingsMapFactory::GetForProfile(GetProfile()); + + std::unique_ptr<base::ListValue> expiration_times_list = + base::MakeUnique<base::ListValue>(); + expiration_times_list->AppendInteger(0); + expiration_times_list->AppendInteger(2); + + double expiration_time = + (base::Time::Now() + base::TimeDelta::FromHours(24)).ToDoubleT(); + + auto expiration_times_dictionary = std::make_unique<base::DictionaryValue>(); + expiration_times_dictionary->SetList("client_hints", + std::move(expiration_times_list)); + expiration_times_dictionary->SetDouble("expiration_time", expiration_time); + + host_content_settings_map->SetWebsiteSettingDefaultScope( + kOrigin1, GURL(), CONTENT_SETTINGS_TYPE_CLIENT_HINTS, std::string(), + expiration_times_dictionary->CreateDeepCopy()); + host_content_settings_map->SetWebsiteSettingDefaultScope( + kOrigin2, GURL(), CONTENT_SETTINGS_TYPE_CLIENT_HINTS, std::string(), + expiration_times_dictionary->CreateDeepCopy()); + + host_content_settings_map->SetWebsiteSettingDefaultScope( + kOrigin3, GURL(), CONTENT_SETTINGS_TYPE_CLIENT_HINTS, std::string(), + expiration_times_dictionary->CreateDeepCopy()); + + // Clear all except for origin1 and origin3. + std::unique_ptr<BrowsingDataFilterBuilder> filter( + BrowsingDataFilterBuilder::Create(BrowsingDataFilterBuilder::BLACKLIST)); + filter->AddRegisterableDomain(kTestRegisterableDomain1); + filter->AddRegisterableDomain(kTestRegisterableDomain3); + BlockUntilOriginDataRemoved(AnHourAgo(), base::Time::Max(), + content::BrowsingDataRemover::DATA_TYPE_COOKIES, + std::move(filter)); + + ContentSettingsForOneType host_settings; + host_content_settings_map->GetSettingsForOneType( + CONTENT_SETTINGS_TYPE_CLIENT_HINTS, std::string(), &host_settings); + + ASSERT_EQ(2u, host_settings.size()); + + EXPECT_EQ(ContentSettingsPattern::FromURLNoWildcard(kOrigin1), + host_settings[0].primary_pattern) + << host_settings[0].primary_pattern.ToString(); + + EXPECT_EQ(ContentSettingsPattern::FromURLNoWildcard(kOrigin3), + host_settings[1].primary_pattern) + << host_settings[1].primary_pattern.ToString(); + + for (size_t i = 0; i < host_settings.size(); ++i) { + EXPECT_EQ(ContentSettingsPattern::Wildcard(), + host_settings.at(i).secondary_pattern); + EXPECT_EQ(*expiration_times_dictionary, *host_settings.at(i).setting_value); + } +} + +TEST_F(ChromeBrowsingDataRemoverDelegateTest, RemoveAllClientHints) { + // Add our settings. + HostContentSettingsMap* host_content_settings_map = + HostContentSettingsMapFactory::GetForProfile(GetProfile()); + + std::unique_ptr<base::ListValue> expiration_times_list = + base::MakeUnique<base::ListValue>(); + expiration_times_list->AppendInteger(0); + expiration_times_list->AppendInteger(2); + + double expiration_time = + (base::Time::Now() + base::TimeDelta::FromHours(24)).ToDoubleT(); + + auto expiration_times_dictionary = std::make_unique<base::DictionaryValue>(); + expiration_times_dictionary->SetList("client_hints", + std::move(expiration_times_list)); + expiration_times_dictionary->SetDouble("expiration_time", expiration_time); + + host_content_settings_map->SetWebsiteSettingDefaultScope( + kOrigin1, GURL(), CONTENT_SETTINGS_TYPE_CLIENT_HINTS, std::string(), + expiration_times_dictionary->CreateDeepCopy()); + host_content_settings_map->SetWebsiteSettingDefaultScope( + kOrigin2, GURL(), CONTENT_SETTINGS_TYPE_CLIENT_HINTS, std::string(), + expiration_times_dictionary->CreateDeepCopy()); + + host_content_settings_map->SetWebsiteSettingDefaultScope( + kOrigin3, GURL(), CONTENT_SETTINGS_TYPE_CLIENT_HINTS, std::string(), + expiration_times_dictionary->CreateDeepCopy()); + + // Clear all. + BlockUntilBrowsingDataRemoved(AnHourAgo(), base::Time::Max(), + content::BrowsingDataRemover::DATA_TYPE_COOKIES, + false); + + ContentSettingsForOneType host_settings; + host_content_settings_map->GetSettingsForOneType( + CONTENT_SETTINGS_TYPE_CLIENT_HINTS, std::string(), &host_settings); + + ASSERT_EQ(0u, host_settings.size()); +} + TEST_F(ChromeBrowsingDataRemoverDelegateTest, RemoveDurablePermission) { // Add our settings. HostContentSettingsMap* host_content_settings_map =
diff --git a/chrome/browser/chrome_browser_main_android.cc b/chrome/browser/chrome_browser_main_android.cc index 4bf799d3..c5fac0c 100644 --- a/chrome/browser/chrome_browser_main_android.cc +++ b/chrome/browser/chrome_browser_main_android.cc
@@ -21,6 +21,7 @@ #include "components/crash/content/app/breakpad_linux.h" #include "components/crash/content/browser/child_process_crash_observer_android.h" #include "components/crash/content/browser/crash_dump_observer_android.h" +#include "components/metrics/stability_metrics_helper.h" #include "components/signin/core/browser/signin_manager.h" #include "content/public/browser/android/compositor.h" #include "content/public/browser/browser_thread.h" @@ -67,7 +68,10 @@ PathService::Get(chrome::DIR_CRASH_DUMPS, &crash_dump_dir); breakpad::CrashDumpObserver::GetInstance()->RegisterClient( base::MakeUnique<breakpad::ChildProcessCrashObserver>( - crash_dump_dir, kAndroidMinidumpDescriptor)); + crash_dump_dir, kAndroidMinidumpDescriptor, + base::Bind( + &metrics::StabilityMetricsHelper::IncreaseRendererCrashCount, + g_browser_process->local_state()))); } // Auto-detect based on en-US whether secondary locale .pak files exist.
diff --git a/chrome/browser/chromeos/tether/tether_service.cc b/chrome/browser/chromeos/tether/tether_service.cc index 0c3df9c7..4064a35 100644 --- a/chrome/browser/chromeos/tether/tether_service.cc +++ b/chrome/browser/chromeos/tether/tether_service.cc
@@ -18,12 +18,13 @@ #include "chrome/common/chrome_features.h" #include "chrome/common/pref_names.h" #include "chromeos/chromeos_switches.h" -#include "chromeos/components/tether/initializer.h" +#include "chromeos/components/tether/initializer_impl.h" #include "chromeos/network/network_connect.h" #include "chromeos/network/network_type_pattern.h" #include "components/cryptauth/cryptauth_service.h" #include "components/prefs/pref_registry_simple.h" #include "components/prefs/pref_service.h" +#include "components/proximity_auth/logging/logging.h" #include "device/bluetooth/bluetooth_adapter_factory.h" #include "ui/message_center/message_center.h" @@ -62,7 +63,7 @@ registry->RegisterBooleanPref(prefs::kInstantTetheringBleAdvertisingSupported, true); - chromeos::tether::Initializer::RegisterProfilePrefs(registry); + chromeos::tether::InitializerImpl::RegisterProfilePrefs(registry); } // static @@ -70,28 +71,6 @@ return base::FeatureList::IsEnabled(features::kInstantTethering); } -void TetherService::InitializerDelegate::InitializeTether( - cryptauth::CryptAuthService* cryptauth_service, - chromeos::tether::NotificationPresenter* notification_presenter, - PrefService* pref_service, - ProfileOAuth2TokenService* token_service, - chromeos::NetworkStateHandler* network_state_handler, - chromeos::ManagedNetworkConfigurationHandler* - managed_network_configuration_handler, - chromeos::NetworkConnect* network_connect, - chromeos::NetworkConnectionHandler* network_connection_handler, - scoped_refptr<device::BluetoothAdapter> adapter) { - chromeos::tether::Initializer::Init( - cryptauth_service, std::move(notification_presenter), pref_service, - token_service, network_state_handler, - managed_network_configuration_handler, network_connect, - network_connection_handler, adapter); -} - -void TetherService::InitializerDelegate::ShutdownTether() { - chromeos::tether::Initializer::Shutdown(); -} - TetherService::TetherService( Profile* profile, chromeos::PowerManagerClient* power_manager_client, @@ -103,7 +82,6 @@ session_manager_client_(session_manager_client), cryptauth_service_(cryptauth_service), network_state_handler_(network_state_handler), - initializer_delegate_(base::MakeUnique<InitializerDelegate>()), notification_presenter_( base::MakeUnique<chromeos::tether::TetherNotificationPresenter>( profile_, @@ -132,7 +110,10 @@ weak_ptr_factory_.GetWeakPtr()))); } -TetherService::~TetherService() {} +TetherService::~TetherService() { + if (initializer_) + initializer_->RemoveObserver(this); +} void TetherService::StartTetherIfPossible() { if (GetTetherTechnologyState() != @@ -140,7 +121,12 @@ return; } - initializer_delegate_->InitializeTether( + // Do not initialize the Tether component if it already exists. + if (initializer_) + return; + + PA_LOG(INFO) << "Starting up Tether component."; + initializer_ = chromeos::tether::InitializerImpl::Factory::NewInstance( cryptauth_service_, notification_presenter_.get(), profile_->GetPrefs(), ProfileOAuth2TokenServiceFactory::GetForProfile(profile_), network_state_handler_, @@ -150,7 +136,13 @@ } void TetherService::StopTetherIfNecessary() { - initializer_delegate_->ShutdownTether(); + if (!initializer_) + return; + + PA_LOG(INFO) << "Shutting down Tether component."; + + initializer_->AddObserver(this); + initializer_->RequestShutdown(); } void TetherService::Shutdown() { @@ -269,6 +261,20 @@ UpdateTetherTechnologyState(); } +void TetherService::OnShutdownComplete() { + DCHECK(initializer_->status() == + chromeos::tether::Initializer::Status::SHUT_DOWN); + initializer_->RemoveObserver(this); + initializer_.reset(); + PA_LOG(INFO) << "Tether component was shut down."; + + // It is possible that the Tether TechnologyState was set to ENABLED while the + // previous Initializer instance was shutting down. If that was the case, + // restart the Tether component. + if (!shut_down_) + StartTetherIfPossible(); +} + void TetherService::OnPrefsChanged() { UpdateTetherTechnologyState(); } @@ -494,11 +500,6 @@ TetherFeatureState::TETHER_FEATURE_STATE_MAX); } -void TetherService::SetInitializerDelegateForTest( - std::unique_ptr<InitializerDelegate> initializer_delegate) { - initializer_delegate_ = std::move(initializer_delegate); -} - void TetherService::SetNotificationPresenterForTest( std::unique_ptr<chromeos::tether::NotificationPresenter> notification_presenter) {
diff --git a/chrome/browser/chromeos/tether/tether_service.h b/chrome/browser/chromeos/tether/tether_service.h index 0e1d536..1fb0716 100644 --- a/chrome/browser/chromeos/tether/tether_service.h +++ b/chrome/browser/chromeos/tether/tether_service.h
@@ -10,6 +10,7 @@ #include "base/gtest_prod_util.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" +#include "chromeos/components/tether/initializer.h" #include "chromeos/dbus/power_manager_client.h" #include "chromeos/dbus/session_manager_client.h" #include "chromeos/network/network_state_handler.h" @@ -21,9 +22,6 @@ namespace chromeos { class NetworkStateHandler; -class ManagedNetworkConfigurationHandler; -class NetworkConnect; -class NetworkConnectionHandler; namespace tether { class NotificationPresenter; } // namespace tether @@ -35,14 +33,14 @@ class PrefRegistrySimple; class Profile; -class ProfileOAuth2TokenService; class TetherService : public KeyedService, public chromeos::PowerManagerClient::Observer, public chromeos::SessionManagerClient::Observer, public cryptauth::CryptAuthDeviceManager::Observer, public device::BluetoothAdapter::Observer, - public chromeos::NetworkStateHandlerObserver { + public chromeos::NetworkStateHandlerObserver, + public chromeos::tether::Initializer::Observer { public: TetherService(Profile* profile, chromeos::PowerManagerClient* power_manager_client, @@ -65,24 +63,6 @@ // Should only be called once a user is logged in. virtual void StartTetherIfPossible(); - // Delegate used to call the static functions of Initializer. Injected to - // aid in testing. - class InitializerDelegate { - public: - virtual void InitializeTether( - cryptauth::CryptAuthService* cryptauth_service, - chromeos::tether::NotificationPresenter* notification_presenter, - PrefService* pref_service, - ProfileOAuth2TokenService* token_service, - chromeos::NetworkStateHandler* network_state_handler, - chromeos::ManagedNetworkConfigurationHandler* - managed_network_configuration_handler, - chromeos::NetworkConnect* network_connect, - chromeos::NetworkConnectionHandler* network_connection_handler, - scoped_refptr<device::BluetoothAdapter> adapter); - virtual void ShutdownTether(); - }; - protected: // KeyedService: void Shutdown() override; @@ -109,6 +89,9 @@ const chromeos::NetworkState* network) override; void DeviceListChanged() override; + // chromeos::tether::Initializer::Observer: + void OnShutdownComplete() override; + // Callback when the controlling pref changes. void OnPrefsChanged(); @@ -203,8 +186,6 @@ // Record to UMA Tether's current feature state. void RecordTetherFeatureState(); - void SetInitializerDelegateForTest( - std::unique_ptr<InitializerDelegate> initializer_delegate); void SetNotificationPresenterForTest( std::unique_ptr<chromeos::tether::NotificationPresenter> notification_presenter); @@ -223,9 +204,9 @@ chromeos::SessionManagerClient* session_manager_client_; cryptauth::CryptAuthService* cryptauth_service_; chromeos::NetworkStateHandler* network_state_handler_; - std::unique_ptr<InitializerDelegate> initializer_delegate_; std::unique_ptr<chromeos::tether::NotificationPresenter> notification_presenter_; + std::unique_ptr<chromeos::tether::Initializer> initializer_; PrefChangeRegistrar registrar_; scoped_refptr<device::BluetoothAdapter> adapter_;
diff --git a/chrome/browser/chromeos/tether/tether_service_unittest.cc b/chrome/browser/chromeos/tether/tether_service_unittest.cc index 2171bb3..d65f4c3b 100644 --- a/chrome/browser/chromeos/tether/tether_service_unittest.cc +++ b/chrome/browser/chromeos/tether/tether_service_unittest.cc
@@ -6,6 +6,7 @@ #include <memory> +#include "base/bind.h" #include "base/command_line.h" #include "base/memory/ptr_util.h" #include "base/message_loop/message_loop.h" @@ -18,7 +19,9 @@ #include "chrome/common/pref_names.h" #include "chrome/test/base/testing_profile.h" #include "chromeos/chromeos_switches.h" +#include "chromeos/components/tether/fake_initializer.h" #include "chromeos/components/tether/fake_notification_presenter.h" +#include "chromeos/components/tether/initializer_impl.h" #include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/dbus/fake_power_manager_client.h" #include "chromeos/dbus/fake_session_manager_client.h" @@ -122,12 +125,35 @@ int updated_technology_state_count_ = 0; }; -class TestInitializerDelegate : public TetherService::InitializerDelegate { +class FakeInitializerWithDestructorCallback + : public chromeos::tether::FakeInitializer { public: - bool is_tether_running() { return is_tether_running_; } + FakeInitializerWithDestructorCallback( + const base::Closure& destructor_callback) + : FakeInitializer(false /* has_asynchronous_shutdown */), + destructor_callback_(destructor_callback) {} - // TetherService::InitializerDelegate: - void InitializeTether( + ~FakeInitializerWithDestructorCallback() override { + destructor_callback_.Run(); + } + + private: + base::Closure destructor_callback_; +}; + +class TestInitializerFactory + : public chromeos::tether::InitializerImpl::Factory { + public: + TestInitializerFactory() {} + + // Returns nullptr if no Initializer has been created or if the last one that + // was created has already been deleted. + FakeInitializerWithDestructorCallback* active_initializer() { + return active_initializer_; + } + + // chromeos::tether::InitializerImpl::Factory: + std::unique_ptr<chromeos::tether::Initializer> BuildInstance( cryptauth::CryptAuthService* cryptauth_service, chromeos::tether::NotificationPresenter* notification_presenter, PrefService* pref_service, @@ -138,13 +164,16 @@ chromeos::NetworkConnect* network_connect, chromeos::NetworkConnectionHandler* network_connection_handler, scoped_refptr<device::BluetoothAdapter> adapter) override { - is_tether_running_ = true; + active_initializer_ = new FakeInitializerWithDestructorCallback( + base::Bind(&TestInitializerFactory::OnActiveInitializerDeleted, + base::Unretained(this))); + return base::WrapUnique(active_initializer_); } - void ShutdownTether() override { is_tether_running_ = false; } - private: - bool is_tether_running_ = false; + void OnActiveInitializerDeleted() { active_initializer_ = nullptr; } + + FakeInitializerWithDestructorCallback* active_initializer_ = nullptr; }; } // namespace @@ -191,6 +220,10 @@ ON_CALL(*mock_adapter_, IsPowered()) .WillByDefault(Invoke(this, &TetherServiceTest::IsBluetoothPowered)); device::BluetoothAdapterFactory::SetAdapterForTesting(mock_adapter_); + + test_initializer_factory_ = base::WrapUnique(new TestInitializerFactory()); + chromeos::tether::InitializerImpl::Factory::SetInstanceForTesting( + test_initializer_factory_.get()); } void TearDown() override { @@ -211,10 +244,6 @@ fake_session_manager_client_.get(), fake_cryptauth_service_.get(), network_state_handler())); - test_initializer_delegate_ = new TestInitializerDelegate(); - tether_service_->SetInitializerDelegateForTest( - base::WrapUnique(test_initializer_delegate_)); - fake_notification_presenter_ = new chromeos::tether::FakeNotificationPresenter(); tether_service_->SetNotificationPresenterForTest( @@ -226,7 +255,7 @@ chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_UNAVAILABLE, network_state_handler()->GetTechnologyState( chromeos::NetworkTypePattern::Tether())); - EXPECT_FALSE(test_initializer_delegate_->is_tether_running()); + VerifyTetherActiveStatus(false /* expected_active */); base::RunLoop().RunUntilIdle(); } @@ -287,6 +316,11 @@ 1); } + void VerifyTetherActiveStatus(bool expected_active) { + EXPECT_EQ(expected_active, + test_initializer_factory_->active_initializer() != nullptr); + } + const content::TestBrowserThreadBundle thread_bundle_; std::unique_ptr<TestingProfile> profile_; @@ -296,7 +330,7 @@ std::unique_ptr<TestingPrefServiceSimple> test_pref_service_; std::unique_ptr<NiceMock<MockCryptAuthDeviceManager>> mock_cryptauth_device_manager_; - TestInitializerDelegate* test_initializer_delegate_; + std::unique_ptr<TestInitializerFactory> test_initializer_factory_; chromeos::tether::FakeNotificationPresenter* fake_notification_presenter_; std::unique_ptr<cryptauth::FakeCryptAuthService> fake_cryptauth_service_; @@ -314,7 +348,7 @@ TEST_F(TetherServiceTest, TestShutdown) { CreateTetherService(); - EXPECT_TRUE(test_initializer_delegate_->is_tether_running()); + VerifyTetherActiveStatus(true /* expected_active */); ShutdownTetherService(); @@ -324,12 +358,46 @@ EXPECT_EQ(chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_ENABLED, network_state_handler()->GetTechnologyState( chromeos::NetworkTypePattern::Tether())); - EXPECT_FALSE(test_initializer_delegate_->is_tether_running()); + VerifyTetherActiveStatus(false /* expected_active */); +} + +TEST_F(TetherServiceTest, TestAsyncTetherShutdown) { + CreateTetherService(); + + // Tether should be ENABLED, and there should be no AsyncShutdownTask. + EXPECT_EQ(chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_ENABLED, + network_state_handler()->GetTechnologyState( + chromeos::NetworkTypePattern::Tether())); + VerifyTetherActiveStatus(true /* expected_active */); + + // Use an asynchronous shutdown. + test_initializer_factory_->active_initializer() + ->set_has_asynchronous_shutdown(true); + + // Disable the Tether preference. This should trigger the asynchrnous + // shutdown. + SetTetherTechnologyStateEnabled(false); + + // Tether should be active, but shutting down. + VerifyTetherActiveStatus(true /* expected_active */); + EXPECT_EQ(chromeos::tether::Initializer::Status::SHUTTING_DOWN, + test_initializer_factory_->active_initializer()->status()); + + // Tether should be AVAILABLE. + EXPECT_EQ( + chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_AVAILABLE, + network_state_handler()->GetTechnologyState( + chromeos::NetworkTypePattern::Tether())); + + // Complete the shutdown process; TetherService should delete its + // Initializer instance. + test_initializer_factory_->active_initializer()->FinishAsynchronousShutdown(); + VerifyTetherActiveStatus(false /* expected_active */); } TEST_F(TetherServiceTest, TestSuspend) { CreateTetherService(); - EXPECT_TRUE(test_initializer_delegate_->is_tether_running()); + VerifyTetherActiveStatus(true /* expected_active */); fake_power_manager_client_->SendSuspendImminent(); @@ -337,14 +405,14 @@ chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_UNAVAILABLE, network_state_handler()->GetTechnologyState( chromeos::NetworkTypePattern::Tether())); - EXPECT_FALSE(test_initializer_delegate_->is_tether_running()); + VerifyTetherActiveStatus(false /* expected_active */); fake_power_manager_client_->SendSuspendDone(); EXPECT_EQ(chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_ENABLED, network_state_handler()->GetTechnologyState( chromeos::NetworkTypePattern::Tether())); - EXPECT_TRUE(test_initializer_delegate_->is_tether_running()); + VerifyTetherActiveStatus(true /* expected_active */); fake_power_manager_client_->SendSuspendImminent(); @@ -361,7 +429,7 @@ chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_UNAVAILABLE, network_state_handler()->GetTechnologyState( chromeos::NetworkTypePattern::Tether())); - EXPECT_FALSE(test_initializer_delegate_->is_tether_running()); + VerifyTetherActiveStatus(false /* expected_active */); ShutdownAndVerifyFinalTetherFeatureState( TetherService::TetherFeatureState::BLE_ADVERTISING_NOT_SUPPORTED); @@ -381,7 +449,7 @@ chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_UNINITIALIZED, network_state_handler()->GetTechnologyState( chromeos::NetworkTypePattern::Tether())); - EXPECT_FALSE(test_initializer_delegate_->is_tether_running()); + VerifyTetherActiveStatus(false /* expected_active */); EXPECT_TRUE(profile_->GetPrefs()->GetBoolean( prefs::kInstantTetheringBleAdvertisingSupported)); @@ -391,7 +459,7 @@ chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_UNAVAILABLE, network_state_handler()->GetTechnologyState( chromeos::NetworkTypePattern::Tether())); - EXPECT_FALSE(test_initializer_delegate_->is_tether_running()); + VerifyTetherActiveStatus(false /* expected_active */); EXPECT_FALSE(profile_->GetPrefs()->GetBoolean( prefs::kInstantTetheringBleAdvertisingSupported)); @@ -416,7 +484,7 @@ chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_UNAVAILABLE, network_state_handler()->GetTechnologyState( chromeos::NetworkTypePattern::Tether())); - EXPECT_FALSE(test_initializer_delegate_->is_tether_running()); + VerifyTetherActiveStatus(false /* expected_active */); SetIsBluetoothPowered(true); @@ -424,7 +492,7 @@ chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_UNAVAILABLE, network_state_handler()->GetTechnologyState( chromeos::NetworkTypePattern::Tether())); - EXPECT_FALSE(test_initializer_delegate_->is_tether_running()); + VerifyTetherActiveStatus(false /* expected_active */); ShutdownAndVerifyFinalTetherFeatureState( TetherService::TetherFeatureState::BLE_ADVERTISING_NOT_SUPPORTED); @@ -443,7 +511,7 @@ EXPECT_EQ(chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_ENABLED, network_state_handler()->GetTechnologyState( chromeos::NetworkTypePattern::Tether())); - EXPECT_TRUE(test_initializer_delegate_->is_tether_running()); + VerifyTetherActiveStatus(true /* expected_active */); EXPECT_TRUE(profile_->GetPrefs()->GetBoolean( prefs::kInstantTetheringBleAdvertisingSupported)); @@ -453,7 +521,7 @@ TEST_F(TetherServiceTest, TestScreenLock) { CreateTetherService(); - EXPECT_TRUE(test_initializer_delegate_->is_tether_running()); + VerifyTetherActiveStatus(true /* expected_active */); SetIsScreenLocked(true); @@ -461,14 +529,14 @@ chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_UNAVAILABLE, network_state_handler()->GetTechnologyState( chromeos::NetworkTypePattern::Tether())); - EXPECT_FALSE(test_initializer_delegate_->is_tether_running()); + VerifyTetherActiveStatus(false /* expected_active */); SetIsScreenLocked(false); EXPECT_EQ(chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_ENABLED, network_state_handler()->GetTechnologyState( chromeos::NetworkTypePattern::Tether())); - EXPECT_TRUE(test_initializer_delegate_->is_tether_running()); + VerifyTetherActiveStatus(true /* expected_active */); SetIsScreenLocked(true); @@ -501,7 +569,7 @@ chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_UNAVAILABLE, network_state_handler()->GetTechnologyState( chromeos::NetworkTypePattern::Tether())); - EXPECT_FALSE(test_initializer_delegate_->is_tether_running()); + VerifyTetherActiveStatus(false /* expected_active */); ShutdownAndVerifyFinalTetherFeatureState( TetherService::TetherFeatureState::NO_AVAILABLE_HOSTS); @@ -516,7 +584,7 @@ chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_PROHIBITED, network_state_handler()->GetTechnologyState( chromeos::NetworkTypePattern::Tether())); - EXPECT_FALSE(test_initializer_delegate_->is_tether_running()); + VerifyTetherActiveStatus(false /* expected_active */); ShutdownAndVerifyFinalTetherFeatureState( TetherService::TetherFeatureState::PROHIBITED); @@ -545,14 +613,14 @@ chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_UNINITIALIZED, network_state_handler()->GetTechnologyState( chromeos::NetworkTypePattern::Tether())); - EXPECT_FALSE(test_initializer_delegate_->is_tether_running()); + VerifyTetherActiveStatus(false /* expected_active */); SetIsBluetoothPowered(true); EXPECT_EQ(chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_ENABLED, network_state_handler()->GetTechnologyState( chromeos::NetworkTypePattern::Tether())); - EXPECT_TRUE(test_initializer_delegate_->is_tether_running()); + VerifyTetherActiveStatus(true /* expected_active */); SetIsBluetoothPowered(false); @@ -560,7 +628,7 @@ chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_UNINITIALIZED, network_state_handler()->GetTechnologyState( chromeos::NetworkTypePattern::Tether())); - EXPECT_FALSE(test_initializer_delegate_->is_tether_running()); + VerifyTetherActiveStatus(false /* expected_active */); ShutdownAndVerifyFinalTetherFeatureState( TetherService::TetherFeatureState::BLUETOOTH_DISABLED); @@ -580,13 +648,13 @@ chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_AVAILABLE, network_state_handler()->GetTechnologyState( chromeos::NetworkTypePattern::Tether())); - EXPECT_FALSE(test_initializer_delegate_->is_tether_running()); + VerifyTetherActiveStatus(false /* expected_active */); SetTetherTechnologyStateEnabled(true); EXPECT_EQ(chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_ENABLED, network_state_handler()->GetTechnologyState( chromeos::NetworkTypePattern::Tether())); - EXPECT_TRUE(test_initializer_delegate_->is_tether_running()); + VerifyTetherActiveStatus(true /* expected_active */); ShutdownAndVerifyFinalTetherFeatureState( TetherService::TetherFeatureState::ENABLED); @@ -606,41 +674,41 @@ chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_AVAILABLE, network_state_handler()->GetTechnologyState( chromeos::NetworkTypePattern::Cellular())); - EXPECT_FALSE(test_initializer_delegate_->is_tether_running()); + VerifyTetherActiveStatus(false /* expected_active */); SetTetherTechnologyStateEnabled(false); EXPECT_EQ( chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_UNAVAILABLE, network_state_handler()->GetTechnologyState( chromeos::NetworkTypePattern::Tether())); - EXPECT_FALSE(test_initializer_delegate_->is_tether_running()); + VerifyTetherActiveStatus(false /* expected_active */); SetTetherTechnologyStateEnabled(true); EXPECT_EQ( chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_UNAVAILABLE, network_state_handler()->GetTechnologyState( chromeos::NetworkTypePattern::Tether())); - EXPECT_FALSE(test_initializer_delegate_->is_tether_running()); + VerifyTetherActiveStatus(false /* expected_active */); // Cellular enabled SetCellularTechnologyStateEnabled(true); ASSERT_EQ(chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_ENABLED, network_state_handler()->GetTechnologyState( chromeos::NetworkTypePattern::Cellular())); - EXPECT_TRUE(test_initializer_delegate_->is_tether_running()); + VerifyTetherActiveStatus(true /* expected_active */); SetTetherTechnologyStateEnabled(false); EXPECT_EQ( chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_AVAILABLE, network_state_handler()->GetTechnologyState( chromeos::NetworkTypePattern::Tether())); - EXPECT_FALSE(test_initializer_delegate_->is_tether_running()); + VerifyTetherActiveStatus(false /* expected_active */); SetTetherTechnologyStateEnabled(true); EXPECT_EQ(chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_ENABLED, network_state_handler()->GetTechnologyState( chromeos::NetworkTypePattern::Tether())); - EXPECT_TRUE(test_initializer_delegate_->is_tether_running()); + VerifyTetherActiveStatus(true /* expected_active */); SetCellularTechnologyStateEnabled(false); @@ -659,7 +727,7 @@ chromeos::NetworkTypePattern::Tether())); EXPECT_FALSE( profile_->GetPrefs()->GetBoolean(prefs::kInstantTetheringEnabled)); - EXPECT_FALSE(test_initializer_delegate_->is_tether_running()); + VerifyTetherActiveStatus(false /* expected_active */); ShutdownAndVerifyFinalTetherFeatureState( TetherService::TetherFeatureState::USER_PREFERENCE_DISABLED); @@ -671,7 +739,7 @@ EXPECT_EQ(chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_ENABLED, network_state_handler()->GetTechnologyState( chromeos::NetworkTypePattern::Tether())); - EXPECT_TRUE(test_initializer_delegate_->is_tether_running()); + VerifyTetherActiveStatus(true /* expected_active */); SetTetherTechnologyStateEnabled(false); EXPECT_EQ( @@ -680,7 +748,7 @@ chromeos::NetworkTypePattern::Tether())); EXPECT_FALSE( profile_->GetPrefs()->GetBoolean(prefs::kInstantTetheringEnabled)); - EXPECT_FALSE(test_initializer_delegate_->is_tether_running()); + VerifyTetherActiveStatus(false /* expected_active */); SetTetherTechnologyStateEnabled(true); EXPECT_EQ(chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_ENABLED, @@ -688,7 +756,7 @@ chromeos::NetworkTypePattern::Tether())); EXPECT_TRUE( profile_->GetPrefs()->GetBoolean(prefs::kInstantTetheringEnabled)); - EXPECT_TRUE(test_initializer_delegate_->is_tether_running()); + VerifyTetherActiveStatus(true /* expected_active */); ShutdownAndVerifyFinalTetherFeatureState( TetherService::TetherFeatureState::ENABLED); @@ -700,6 +768,7 @@ // state than the user preference. TEST_F(TetherServiceTest, TestEnabledMultipleChanges) { CreateTetherService(); + // CreateTetherService calls RunUntilIdle() so UpdateTetherTechnologyState() // may be called multiple times in the initialization process. int updated_technology_state_count =
diff --git a/chrome/browser/extensions/api/device_permissions_manager_unittest.cc b/chrome/browser/extensions/api/device_permissions_manager_unittest.cc index 8654a2c2..c3345f1 100644 --- a/chrome/browser/extensions/api/device_permissions_manager_unittest.cc +++ b/chrome/browser/extensions/api/device_permissions_manager_unittest.cc
@@ -13,6 +13,7 @@ #include "device/base/mock_device_client.h" #include "device/hid/hid_device_info.h" #include "device/hid/mock_hid_service.h" +#include "device/hid/public/interfaces/hid.mojom.h" #include "device/usb/mock_usb_device.h" #include "device/usb/mock_usb_service.h" #include "extensions/browser/api/device_permissions_manager.h" @@ -70,21 +71,21 @@ device2_ = new MockUsbDevice(0, 0, "Test Manufacturer", "Test Product", "12345"); device3_ = new MockUsbDevice(0, 0, "Test Manufacturer", "Test Product", ""); - device4_ = - new HidDeviceInfo(kTestDeviceIds[0], 0, 0, "Test HID Device", "abcde", - device::kHIDBusTypeUSB, std::vector<uint8_t>()); + device4_ = new HidDeviceInfo( + kTestDeviceIds[0], 0, 0, "Test HID Device", "abcde", + device::mojom::HidBusType::kHIDBusTypeUSB, std::vector<uint8_t>()); device_client_.hid_service()->AddDevice(device4_); - device5_ = - new HidDeviceInfo(kTestDeviceIds[1], 0, 0, "Test HID Device", "", - device::kHIDBusTypeUSB, std::vector<uint8_t>()); + device5_ = new HidDeviceInfo(kTestDeviceIds[1], 0, 0, "Test HID Device", "", + device::mojom::HidBusType::kHIDBusTypeUSB, + std::vector<uint8_t>()); device_client_.hid_service()->AddDevice(device5_); - device6_ = - new HidDeviceInfo(kTestDeviceIds[2], 0, 0, "Test HID Device", "67890", - device::kHIDBusTypeUSB, std::vector<uint8_t>()); + device6_ = new HidDeviceInfo( + kTestDeviceIds[2], 0, 0, "Test HID Device", "67890", + device::mojom::HidBusType::kHIDBusTypeUSB, std::vector<uint8_t>()); device_client_.hid_service()->AddDevice(device6_); - device7_ = - new HidDeviceInfo(kTestDeviceIds[3], 0, 0, "Test HID Device", "", - device::kHIDBusTypeUSB, std::vector<uint8_t>()); + device7_ = new HidDeviceInfo(kTestDeviceIds[3], 0, 0, "Test HID Device", "", + device::mojom::HidBusType::kHIDBusTypeUSB, + std::vector<uint8_t>()); device_client_.hid_service()->AddDevice(device7_); device_client_.hid_service()->FirstEnumerationComplete(); } @@ -109,8 +110,8 @@ DevicePermissionsManager::Get(env_->profile()); manager->AllowUsbDevice(extension_->id(), device0_); manager->AllowUsbDevice(extension_->id(), device1_); - manager->AllowHidDevice(extension_->id(), device4_); - manager->AllowHidDevice(extension_->id(), device5_); + manager->AllowHidDevice(extension_->id(), *device4_->device()); + manager->AllowHidDevice(extension_->id(), *device5_->device()); DevicePermissions* device_permissions = manager->GetForExtension(extension_->id()); @@ -123,13 +124,15 @@ EXPECT_FALSE(device_permissions->FindUsbDeviceEntry(device2_).get()); EXPECT_FALSE(device_permissions->FindUsbDeviceEntry(device3_).get()); scoped_refptr<DevicePermissionEntry> device4_entry = - device_permissions->FindHidDeviceEntry(device4_); + device_permissions->FindHidDeviceEntry(*device4_->device()); ASSERT_TRUE(device4_entry.get()); scoped_refptr<DevicePermissionEntry> device5_entry = - device_permissions->FindHidDeviceEntry(device5_); + device_permissions->FindHidDeviceEntry(*device5_->device()); ASSERT_TRUE(device5_entry.get()); - EXPECT_FALSE(device_permissions->FindHidDeviceEntry(device6_).get()); - EXPECT_FALSE(device_permissions->FindHidDeviceEntry(device7_).get()); + EXPECT_FALSE( + device_permissions->FindHidDeviceEntry(*device6_->device()).get()); + EXPECT_FALSE( + device_permissions->FindHidDeviceEntry(*device7_->device()).get()); EXPECT_EQ(4U, device_permissions->entries().size()); EXPECT_EQ(base::ASCIIToUTF16( @@ -150,26 +153,34 @@ EXPECT_FALSE(device_permissions->FindUsbDeviceEntry(device1_).get()); EXPECT_FALSE(device_permissions->FindUsbDeviceEntry(device2_).get()); EXPECT_FALSE(device_permissions->FindUsbDeviceEntry(device3_).get()); - EXPECT_FALSE(device_permissions->FindHidDeviceEntry(device4_).get()); - EXPECT_FALSE(device_permissions->FindHidDeviceEntry(device5_).get()); - EXPECT_FALSE(device_permissions->FindHidDeviceEntry(device6_).get()); - EXPECT_FALSE(device_permissions->FindHidDeviceEntry(device7_).get()); + EXPECT_FALSE( + device_permissions->FindHidDeviceEntry(*device4_->device()).get()); + EXPECT_FALSE( + device_permissions->FindHidDeviceEntry(*device5_->device()).get()); + EXPECT_FALSE( + device_permissions->FindHidDeviceEntry(*device6_->device()).get()); + EXPECT_FALSE( + device_permissions->FindHidDeviceEntry(*device7_->device()).get()); EXPECT_EQ(0U, device_permissions->entries().size()); // After clearing device it should be possible to grant permission again. manager->AllowUsbDevice(extension_->id(), device0_); manager->AllowUsbDevice(extension_->id(), device1_); - manager->AllowHidDevice(extension_->id(), device4_); - manager->AllowHidDevice(extension_->id(), device5_); + manager->AllowHidDevice(extension_->id(), *device4_->device()); + manager->AllowHidDevice(extension_->id(), *device5_->device()); EXPECT_TRUE(device_permissions->FindUsbDeviceEntry(device0_).get()); EXPECT_TRUE(device_permissions->FindUsbDeviceEntry(device1_).get()); EXPECT_FALSE(device_permissions->FindUsbDeviceEntry(device2_).get()); EXPECT_FALSE(device_permissions->FindUsbDeviceEntry(device3_).get()); - EXPECT_TRUE(device_permissions->FindHidDeviceEntry(device4_).get()); - EXPECT_TRUE(device_permissions->FindHidDeviceEntry(device5_).get()); - EXPECT_FALSE(device_permissions->FindHidDeviceEntry(device6_).get()); - EXPECT_FALSE(device_permissions->FindHidDeviceEntry(device7_).get()); + EXPECT_TRUE( + device_permissions->FindHidDeviceEntry(*device4_->device()).get()); + EXPECT_TRUE( + device_permissions->FindHidDeviceEntry(*device5_->device()).get()); + EXPECT_FALSE( + device_permissions->FindHidDeviceEntry(*device6_->device()).get()); + EXPECT_FALSE( + device_permissions->FindHidDeviceEntry(*device7_->device()).get()); } TEST_F(DevicePermissionsManagerTest, DisconnectDevice) { @@ -177,8 +188,8 @@ DevicePermissionsManager::Get(env_->profile()); manager->AllowUsbDevice(extension_->id(), device0_); manager->AllowUsbDevice(extension_->id(), device1_); - manager->AllowHidDevice(extension_->id(), device4_); - manager->AllowHidDevice(extension_->id(), device5_); + manager->AllowHidDevice(extension_->id(), *device4_->device()); + manager->AllowHidDevice(extension_->id(), *device5_->device()); DevicePermissions* device_permissions = manager->GetForExtension(extension_->id()); @@ -186,10 +197,14 @@ EXPECT_TRUE(device_permissions->FindUsbDeviceEntry(device1_).get()); EXPECT_FALSE(device_permissions->FindUsbDeviceEntry(device2_).get()); EXPECT_FALSE(device_permissions->FindUsbDeviceEntry(device3_).get()); - EXPECT_TRUE(device_permissions->FindHidDeviceEntry(device4_).get()); - EXPECT_TRUE(device_permissions->FindHidDeviceEntry(device5_).get()); - EXPECT_FALSE(device_permissions->FindHidDeviceEntry(device6_).get()); - EXPECT_FALSE(device_permissions->FindHidDeviceEntry(device7_).get()); + EXPECT_TRUE( + device_permissions->FindHidDeviceEntry(*device4_->device()).get()); + EXPECT_TRUE( + device_permissions->FindHidDeviceEntry(*device5_->device()).get()); + EXPECT_FALSE( + device_permissions->FindHidDeviceEntry(*device6_->device()).get()); + EXPECT_FALSE( + device_permissions->FindHidDeviceEntry(*device7_->device()).get()); device_client_.usb_service()->RemoveDevice(device0_); device_client_.usb_service()->RemoveDevice(device1_); @@ -210,11 +225,15 @@ EXPECT_FALSE(device_permissions->FindUsbDeviceEntry(device2_).get()); EXPECT_FALSE(device_permissions->FindUsbDeviceEntry(device3_).get()); // Device 4 is like device 0, but HID. - EXPECT_TRUE(device_permissions->FindHidDeviceEntry(device4_).get()); + EXPECT_TRUE( + device_permissions->FindHidDeviceEntry(*device4_->device()).get()); // Device 5 is like device 1, but HID. - EXPECT_FALSE(device_permissions->FindHidDeviceEntry(device5_).get()); - EXPECT_FALSE(device_permissions->FindHidDeviceEntry(device6_).get()); - EXPECT_FALSE(device_permissions->FindHidDeviceEntry(device7_).get()); + EXPECT_FALSE( + device_permissions->FindHidDeviceEntry(*device5_->device()).get()); + EXPECT_FALSE( + device_permissions->FindHidDeviceEntry(*device6_->device()).get()); + EXPECT_FALSE( + device_permissions->FindHidDeviceEntry(*device7_->device()).get()); } TEST_F(DevicePermissionsManagerTest, RevokeAndRegrantAccess) { @@ -222,8 +241,8 @@ DevicePermissionsManager::Get(env_->profile()); manager->AllowUsbDevice(extension_->id(), device0_); manager->AllowUsbDevice(extension_->id(), device1_); - manager->AllowHidDevice(extension_->id(), device4_); - manager->AllowHidDevice(extension_->id(), device5_); + manager->AllowHidDevice(extension_->id(), *device4_->device()); + manager->AllowHidDevice(extension_->id(), *device5_->device()); DevicePermissions* device_permissions = manager->GetForExtension(extension_->id()); @@ -234,10 +253,10 @@ device_permissions->FindUsbDeviceEntry(device1_); ASSERT_TRUE(device1_entry.get()); scoped_refptr<DevicePermissionEntry> device4_entry = - device_permissions->FindHidDeviceEntry(device4_); + device_permissions->FindHidDeviceEntry(*device4_->device()); ASSERT_TRUE(device4_entry.get()); scoped_refptr<DevicePermissionEntry> device5_entry = - device_permissions->FindHidDeviceEntry(device5_); + device_permissions->FindHidDeviceEntry(*device5_->device()); ASSERT_TRUE(device5_entry.get()); manager->RemoveEntry(extension_->id(), device0_entry); @@ -257,27 +276,35 @@ EXPECT_TRUE(device_permissions->FindUsbDeviceEntry(device1_).get()); manager->RemoveEntry(extension_->id(), device4_entry); - EXPECT_FALSE(device_permissions->FindHidDeviceEntry(device4_).get()); - EXPECT_TRUE(device_permissions->FindHidDeviceEntry(device5_).get()); + EXPECT_FALSE( + device_permissions->FindHidDeviceEntry(*device4_->device()).get()); + EXPECT_TRUE( + device_permissions->FindHidDeviceEntry(*device5_->device()).get()); - manager->AllowHidDevice(extension_->id(), device4_); - EXPECT_TRUE(device_permissions->FindHidDeviceEntry(device4_).get()); - EXPECT_TRUE(device_permissions->FindHidDeviceEntry(device5_).get()); + manager->AllowHidDevice(extension_->id(), *device4_->device()); + EXPECT_TRUE( + device_permissions->FindHidDeviceEntry(*device4_->device()).get()); + EXPECT_TRUE( + device_permissions->FindHidDeviceEntry(*device5_->device()).get()); manager->RemoveEntry(extension_->id(), device5_entry); - EXPECT_TRUE(device_permissions->FindHidDeviceEntry(device4_).get()); - EXPECT_FALSE(device_permissions->FindHidDeviceEntry(device5_).get()); + EXPECT_TRUE( + device_permissions->FindHidDeviceEntry(*device4_->device()).get()); + EXPECT_FALSE( + device_permissions->FindHidDeviceEntry(*device5_->device()).get()); - manager->AllowHidDevice(extension_->id(), device5_); - EXPECT_TRUE(device_permissions->FindHidDeviceEntry(device4_).get()); - EXPECT_TRUE(device_permissions->FindHidDeviceEntry(device5_).get()); + manager->AllowHidDevice(extension_->id(), *device5_->device()); + EXPECT_TRUE( + device_permissions->FindHidDeviceEntry(*device4_->device()).get()); + EXPECT_TRUE( + device_permissions->FindHidDeviceEntry(*device5_->device()).get()); } TEST_F(DevicePermissionsManagerTest, UpdateLastUsed) { DevicePermissionsManager* manager = DevicePermissionsManager::Get(env_->profile()); manager->AllowUsbDevice(extension_->id(), device0_); - manager->AllowHidDevice(extension_->id(), device4_); + manager->AllowHidDevice(extension_->id(), *device4_->device()); DevicePermissions* device_permissions = manager->GetForExtension(extension_->id()); @@ -285,7 +312,7 @@ device_permissions->FindUsbDeviceEntry(device0_); EXPECT_TRUE(device0_entry->last_used().is_null()); scoped_refptr<DevicePermissionEntry> device4_entry = - device_permissions->FindHidDeviceEntry(device4_); + device_permissions->FindHidDeviceEntry(*device4_->device()); EXPECT_TRUE(device4_entry->last_used().is_null()); manager->UpdateLastUsed(extension_->id(), device0_entry); @@ -327,11 +354,14 @@ EXPECT_FALSE(device_permissions->FindUsbDeviceEntry(device2_).get()); EXPECT_FALSE(device_permissions->FindUsbDeviceEntry(device3_).get()); scoped_refptr<DevicePermissionEntry> device4_entry = - device_permissions->FindHidDeviceEntry(device4_); + device_permissions->FindHidDeviceEntry(*device4_->device()); ASSERT_TRUE(device4_entry.get()); - EXPECT_FALSE(device_permissions->FindHidDeviceEntry(device5_).get()); - EXPECT_FALSE(device_permissions->FindHidDeviceEntry(device6_).get()); - EXPECT_FALSE(device_permissions->FindHidDeviceEntry(device7_).get()); + EXPECT_FALSE( + device_permissions->FindHidDeviceEntry(*device5_->device()).get()); + EXPECT_FALSE( + device_permissions->FindHidDeviceEntry(*device6_->device()).get()); + EXPECT_FALSE( + device_permissions->FindHidDeviceEntry(*device7_->device()).get()); EXPECT_EQ(base::ASCIIToUTF16( "Test Product from Test Manufacturer (serial number ABCDE)"),
diff --git a/chrome/browser/metrics/chrome_stability_metrics_provider_unittest.cc b/chrome/browser/metrics/chrome_stability_metrics_provider_unittest.cc index 528e2f9..f098331 100644 --- a/chrome/browser/metrics/chrome_stability_metrics_provider_unittest.cc +++ b/chrome/browser/metrics/chrome_stability_metrics_provider_unittest.cc
@@ -5,6 +5,8 @@ #include "chrome/browser/metrics/chrome_stability_metrics_provider.h" #include "base/macros.h" +#include "base/test/histogram_tester.h" +#include "build/build_config.h" #include "chrome/test/base/testing_browser_process.h" #include "chrome/test/base/testing_profile.h" #include "chrome/test/base/testing_profile_manager.h" @@ -69,6 +71,7 @@ } TEST_F(ChromeStabilityMetricsProviderTest, NotificationObserver) { + base::HistogramTester histogram_tester; ChromeStabilityMetricsProvider provider(prefs()); std::unique_ptr<TestingProfileManager> profile_manager( new TestingProfileManager(TestingBrowserProcess::GetGlobal())); @@ -128,7 +131,13 @@ // be executed immediately. provider.ProvideStabilityMetrics(&system_profile); +#if defined(OS_ANDROID) + EXPECT_EQ( + 2u, + histogram_tester.GetAllSamples("Stability.Android.RendererCrash").size()); +#else EXPECT_EQ(2, system_profile.stability().renderer_crash_count()); +#endif EXPECT_EQ(1, system_profile.stability().renderer_failed_launch_count()); EXPECT_EQ(0, system_profile.stability().extension_renderer_crash_count());
diff --git a/chrome/browser/net/network_context_configuration_browsertest.cc b/chrome/browser/net/network_context_configuration_browsertest.cc index 1e0bd755..b350fb5a 100644 --- a/chrome/browser/net/network_context_configuration_browsertest.cc +++ b/chrome/browser/net/network_context_configuration_browsertest.cc
@@ -26,9 +26,11 @@ #include "content/public/common/network_service.mojom.h" #include "content/public/common/resource_response.h" #include "content/public/common/resource_response_info.h" +#include "content/public/common/simple_url_loader.h" #include "content/public/common/url_constants.h" #include "content/public/common/url_loader.mojom.h" #include "content/public/common/url_loader_factory.mojom.h" +#include "content/public/test/simple_url_loader_test_helper.h" #include "content/public/test/test_url_loader_client.h" #include "mojo/common/data_pipe_utils.h" #include "net/base/filename_util.h" @@ -132,56 +134,42 @@ }; IN_PROC_BROWSER_TEST_P(NetworkContextConfigurationBrowserTest, BasicRequest) { - content::mojom::URLLoaderPtr loader; + content::SimpleURLLoaderTestHelper simple_loader_helper; + std::unique_ptr<content::SimpleURLLoader> simple_loader = + content::SimpleURLLoader::Create(); + content::ResourceRequest request; - content::TestURLLoaderClient client; request.url = embedded_test_server()->GetURL("/echo"); - request.method = "GET"; - request.request_initiator = url::Origin(); - loader_factory()->CreateLoaderAndStart( - mojo::MakeRequest(&loader), 2, 1, content::mojom::kURLLoadOptionNone, - request, client.CreateInterfacePtr(), - net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS)); - client.RunUntilResponseReceived(); - ASSERT_TRUE(client.response_head().headers); - EXPECT_EQ(200, client.response_head().headers->response_code()); + simple_loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie( + request, loader_factory(), TRAFFIC_ANNOTATION_FOR_TESTS, + simple_loader_helper.GetCallback()); + simple_loader_helper.WaitForCallback(); - client.RunUntilResponseBodyArrived(); - // TODO(mmenke): Is blocking the UI Thread while reading the response really - // the best way to test requests in a browser test? - std::string response_body; - EXPECT_TRUE(mojo::common::BlockingCopyToString(client.response_body_release(), - &response_body)); - EXPECT_EQ("Echo", response_body); - - client.RunUntilComplete(); - EXPECT_EQ(net::OK, client.completion_status().error_code); + ASSERT_TRUE(simple_loader->ResponseInfo()); + ASSERT_TRUE(simple_loader->ResponseInfo()->headers); + EXPECT_EQ(200, simple_loader->ResponseInfo()->headers->response_code()); + ASSERT_TRUE(simple_loader_helper.response_body()); + EXPECT_EQ("Echo", *simple_loader_helper.response_body()); } IN_PROC_BROWSER_TEST_P(NetworkContextConfigurationBrowserTest, DataURL) { - content::mojom::URLLoaderPtr loader; + content::SimpleURLLoaderTestHelper simple_loader_helper; + std::unique_ptr<content::SimpleURLLoader> simple_loader = + content::SimpleURLLoader::Create(); + content::ResourceRequest request; - content::TestURLLoaderClient client; request.url = GURL("data:text/plain,foo"); - request.method = "GET"; - request.request_initiator = url::Origin(); - loader_factory()->CreateLoaderAndStart( - mojo::MakeRequest(&loader), 2, 1, content::mojom::kURLLoadOptionNone, - request, client.CreateInterfacePtr(), - net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS)); - client.RunUntilResponseReceived(); + simple_loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie( + request, loader_factory(), TRAFFIC_ANNOTATION_FOR_TESTS, + simple_loader_helper.GetCallback()); + simple_loader_helper.WaitForCallback(); + + ASSERT_TRUE(simple_loader->ResponseInfo()); // Data URLs don't have headers. - EXPECT_FALSE(client.response_head().headers); - EXPECT_EQ("text/plain", client.response_head().mime_type); - - client.RunUntilResponseBodyArrived(); - std::string response_body; - EXPECT_TRUE(mojo::common::BlockingCopyToString(client.response_body_release(), - &response_body)); - EXPECT_EQ("foo", response_body); - - client.RunUntilComplete(); - EXPECT_EQ(net::OK, client.completion_status().error_code); + EXPECT_FALSE(simple_loader->ResponseInfo()->headers); + EXPECT_EQ("text/plain", simple_loader->ResponseInfo()->mime_type); + ASSERT_TRUE(simple_loader_helper.response_body()); + EXPECT_EQ("foo", *simple_loader_helper.response_body()); } IN_PROC_BROWSER_TEST_P(NetworkContextConfigurationBrowserTest, FileURL) { @@ -194,84 +182,64 @@ ASSERT_EQ(static_cast<int>(strlen(kFileContents)), base::WriteFile(file_path, kFileContents, strlen(kFileContents))); - content::mojom::URLLoaderPtr loader; + content::SimpleURLLoaderTestHelper simple_loader_helper; + std::unique_ptr<content::SimpleURLLoader> simple_loader = + content::SimpleURLLoader::Create(); + content::ResourceRequest request; - content::TestURLLoaderClient client; request.url = net::FilePathToFileURL(file_path); - request.method = "GET"; - request.request_initiator = url::Origin(); - loader_factory()->CreateLoaderAndStart( - mojo::MakeRequest(&loader), 2, 1, content::mojom::kURLLoadOptionNone, - request, client.CreateInterfacePtr(), - net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS)); - client.RunUntilResponseReceived(); + simple_loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie( + request, loader_factory(), TRAFFIC_ANNOTATION_FOR_TESTS, + simple_loader_helper.GetCallback()); + simple_loader_helper.WaitForCallback(); + + ASSERT_TRUE(simple_loader->ResponseInfo()); // File URLs don't have headers. - EXPECT_FALSE(client.response_head().headers); - - client.RunUntilResponseBodyArrived(); - std::string response_body; - EXPECT_TRUE(mojo::common::BlockingCopyToString(client.response_body_release(), - &response_body)); - EXPECT_EQ(kFileContents, response_body); - - client.RunUntilComplete(); - EXPECT_EQ(net::OK, client.completion_status().error_code); + EXPECT_FALSE(simple_loader->ResponseInfo()->headers); + ASSERT_TRUE(simple_loader_helper.response_body()); + EXPECT_EQ(kFileContents, *simple_loader_helper.response_body()); } // Make sure a cache is used when expected. IN_PROC_BROWSER_TEST_P(NetworkContextConfigurationBrowserTest, Cache) { + content::SimpleURLLoaderTestHelper simple_loader_helper; + std::unique_ptr<content::SimpleURLLoader> simple_loader = + content::SimpleURLLoader::Create(); + // Make a request whose response should be cached. - content::mojom::URLLoaderPtr loader; content::ResourceRequest request; - content::TestURLLoaderClient client; request.url = embedded_test_server()->GetURL("/cachetime"); - request.method = "GET"; - loader_factory()->CreateLoaderAndStart( - mojo::MakeRequest(&loader), 2, 1, content::mojom::kURLLoadOptionNone, - request, client.CreateInterfacePtr(), - net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS)); - client.RunUntilResponseReceived(); - ASSERT_TRUE(client.response_head().headers); - EXPECT_EQ(200, client.response_head().headers->response_code()); - client.RunUntilResponseBodyArrived(); - std::string response_body; - EXPECT_TRUE(mojo::common::BlockingCopyToString(client.response_body_release(), - &response_body)); - EXPECT_GE(response_body.size(), 0u); - client.RunUntilComplete(); - EXPECT_EQ(net::OK, client.completion_status().error_code); - EXPECT_FALSE(client.completion_status().exists_in_cache); + simple_loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie( + request, loader_factory(), TRAFFIC_ANNOTATION_FOR_TESTS, + simple_loader_helper.GetCallback()); + simple_loader_helper.WaitForCallback(); + + ASSERT_TRUE(simple_loader_helper.response_body()); + EXPECT_GT(simple_loader_helper.response_body()->size(), 0u); // Stop the server. ASSERT_TRUE(embedded_test_server()->ShutdownAndWaitUntilComplete()); // Make the request again, and make sure it's cached or not, according to // expectations. Reuse the content::ResourceRequest, but nothing else. - content::mojom::URLLoaderPtr loader2; - content::TestURLLoaderClient client2; - loader_factory()->CreateLoaderAndStart( - mojo::MakeRequest(&loader2), 3, 2, content::mojom::kURLLoadOptionNone, - request, client2.CreateInterfacePtr(), - net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS)); + content::SimpleURLLoaderTestHelper simple_loader_helper2; + std::unique_ptr<content::SimpleURLLoader> simple_loader2 = + content::SimpleURLLoader::Create(); + simple_loader2->DownloadToStringOfUnboundedSizeUntilCrashAndDie( + request, loader_factory(), TRAFFIC_ANNOTATION_FOR_TESTS, + simple_loader_helper2.GetCallback()); + simple_loader_helper2.WaitForCallback(); if (GetHttpCacheType() == StorageType::kNone) { - client2.RunUntilComplete(); - // If there's no cache, and not server running, the request should fail. - EXPECT_EQ(net::ERR_CONNECTION_REFUSED, - client2.completion_status().error_code); + // If there's no cache, and not server running, the request should have + // failed. + EXPECT_FALSE(simple_loader_helper2.response_body()); + EXPECT_EQ(net::ERR_CONNECTION_REFUSED, simple_loader2->NetError()); } else { - // Otherwise, the request should succeed, and return the same result as - // before. - client2.RunUntilResponseReceived(); - ASSERT_TRUE(client2.response_head().headers); - EXPECT_EQ(200, client2.response_head().headers->response_code()); - client2.RunUntilResponseBodyArrived(); - std::string response_body2; - EXPECT_TRUE(mojo::common::BlockingCopyToString( - client2.response_body_release(), &response_body2)); - EXPECT_EQ(response_body, response_body2); - client2.RunUntilComplete(); - EXPECT_EQ(net::OK, client2.completion_status().error_code); - EXPECT_TRUE(client2.completion_status().exists_in_cache); + // Otherwise, the request should have succeeded, and returned the same + // result as before. + ASSERT_TRUE(simple_loader_helper2.response_body()); + EXPECT_EQ(*simple_loader_helper.response_body(), + *simple_loader_helper2.response_body()); } } @@ -291,28 +259,22 @@ base::WriteFile(save_url_file_path, test_url.spec().c_str(), test_url.spec().length())); + content::SimpleURLLoaderTestHelper simple_loader_helper; + std::unique_ptr<content::SimpleURLLoader> simple_loader = + content::SimpleURLLoader::Create(); + // Make a request whose response should be cached. - content::mojom::URLLoaderPtr loader; content::ResourceRequest request; - content::TestURLLoaderClient client; request.url = test_url; - request.method = "GET"; request.headers = "foo: foopity foo\r\n\r\n"; - loader_factory()->CreateLoaderAndStart( - mojo::MakeRequest(&loader), 2, 1, content::mojom::kURLLoadOptionNone, - request, client.CreateInterfacePtr(), - net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS)); - client.RunUntilResponseReceived(); - ASSERT_TRUE(client.response_head().headers); - EXPECT_EQ(200, client.response_head().headers->response_code()); - client.RunUntilResponseBodyArrived(); - std::string response_body; - EXPECT_TRUE(mojo::common::BlockingCopyToString(client.response_body_release(), - &response_body)); - EXPECT_EQ("foopity foo", response_body); - client.RunUntilComplete(); - EXPECT_EQ(net::OK, client.completion_status().error_code); - EXPECT_FALSE(client.completion_status().exists_in_cache); + simple_loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie( + request, loader_factory(), TRAFFIC_ANNOTATION_FOR_TESTS, + simple_loader_helper.GetCallback()); + simple_loader_helper.WaitForCallback(); + + EXPECT_EQ(net::OK, simple_loader->NetError()); + ASSERT_TRUE(simple_loader_helper.response_body()); + EXPECT_EQ(*simple_loader_helper.response_body(), "foopity foo"); } // Check if the URL loaded in PRE_DiskCache is still in the cache, across a @@ -373,77 +335,52 @@ // respected. IN_PROC_BROWSER_TEST_P(NetworkContextConfigurationFixedPortBrowserTest, TestingFixedPort) { - content::mojom::URLLoaderPtr loader; + content::SimpleURLLoaderTestHelper simple_loader_helper; + std::unique_ptr<content::SimpleURLLoader> simple_loader = + content::SimpleURLLoader::Create(); + content::ResourceRequest request; - content::TestURLLoaderClient client; // This URL does not use the port the embedded test server is using. The // command line switch should make it result in the request being directed to // the test server anyways. request.url = GURL("http://127.0.0.1/echo"); - loader_factory()->CreateLoaderAndStart( - mojo::MakeRequest(&loader), 0, 0, content::mojom::kURLLoadOptionNone, - request, client.CreateInterfacePtr(), - net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS)); - client.RunUntilResponseReceived(); - ASSERT_TRUE(client.response_head().headers); - EXPECT_EQ(200, client.response_head().headers->response_code()); + simple_loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie( + request, loader_factory(), TRAFFIC_ANNOTATION_FOR_TESTS, + simple_loader_helper.GetCallback()); + simple_loader_helper.WaitForCallback(); - client.RunUntilResponseBodyArrived(); - std::string response_body; - EXPECT_TRUE(mojo::common::BlockingCopyToString(client.response_body_release(), - &response_body)); - EXPECT_EQ("Echo", response_body); - - client.RunUntilComplete(); - EXPECT_EQ(net::OK, client.completion_status().error_code); + EXPECT_EQ(net::OK, simple_loader->NetError()); + ASSERT_TRUE(simple_loader_helper.response_body()); + EXPECT_EQ(*simple_loader_helper.response_body(), "Echo"); } -INSTANTIATE_TEST_CASE_P( - SystemNetworkContext, - NetworkContextConfigurationBrowserTest, - ::testing::Values(TestCase({NetworkServiceState::kDisabled, - NetworkContextType::kSystem}), - TestCase({NetworkServiceState::kEnabled, - NetworkContextType::kSystem}))); +// Instiates tests with a prefix indicating which NetworkContext is being +// tested, and a suffix of "/0" if the network service is disabled and "/1" if +// it's enabled. +#define INSTANTIATE_TEST_CASES_FOR_TEST_FIXTURE(TestFixture) \ + INSTANTIATE_TEST_CASE_P( \ + SystemNetworkContext, TestFixture, \ + ::testing::Values(TestCase({NetworkServiceState::kDisabled, \ + NetworkContextType::kSystem}), \ + TestCase({NetworkServiceState::kEnabled, \ + NetworkContextType::kSystem}))); \ + \ + INSTANTIATE_TEST_CASE_P( \ + ProfileMainNetworkContext, TestFixture, \ + ::testing::Values(TestCase({NetworkServiceState::kDisabled, \ + NetworkContextType::kProfile}), \ + TestCase({NetworkServiceState::kEnabled, \ + NetworkContextType::kProfile}))); \ + \ + INSTANTIATE_TEST_CASE_P( \ + IncognitoProfileMainNetworkContext, TestFixture, \ + ::testing::Values(TestCase({NetworkServiceState::kDisabled, \ + NetworkContextType::kIncognitoProfile}), \ + TestCase({NetworkServiceState::kEnabled, \ + NetworkContextType::kIncognitoProfile}))) -INSTANTIATE_TEST_CASE_P( - ProfileMainNetworkContext, - NetworkContextConfigurationBrowserTest, - ::testing::Values(TestCase({NetworkServiceState::kDisabled, - NetworkContextType::kProfile}), - TestCase({NetworkServiceState::kEnabled, - NetworkContextType::kProfile}))); - -INSTANTIATE_TEST_CASE_P( - IncognitoProfileMainNetworkContext, - NetworkContextConfigurationBrowserTest, - ::testing::Values(TestCase({NetworkServiceState::kDisabled, - NetworkContextType::kIncognitoProfile}), - TestCase({NetworkServiceState::kEnabled, - NetworkContextType::kIncognitoProfile}))); - -INSTANTIATE_TEST_CASE_P( - SystemNetworkContext, - NetworkContextConfigurationFixedPortBrowserTest, - ::testing::Values(TestCase({NetworkServiceState::kDisabled, - NetworkContextType::kSystem}), - TestCase({NetworkServiceState::kEnabled, - NetworkContextType::kSystem}))); - -INSTANTIATE_TEST_CASE_P( - ProfileMainNetworkContext, - NetworkContextConfigurationFixedPortBrowserTest, - ::testing::Values(TestCase({NetworkServiceState::kDisabled, - NetworkContextType::kProfile}), - TestCase({NetworkServiceState::kEnabled, - NetworkContextType::kProfile}))); - -INSTANTIATE_TEST_CASE_P( - IncognitoProfileMainNetworkContext, - NetworkContextConfigurationFixedPortBrowserTest, - ::testing::Values(TestCase({NetworkServiceState::kDisabled, - NetworkContextType::kIncognitoProfile}), - TestCase({NetworkServiceState::kEnabled, - NetworkContextType::kIncognitoProfile}))); +INSTANTIATE_TEST_CASES_FOR_TEST_FIXTURE(NetworkContextConfigurationBrowserTest); +INSTANTIATE_TEST_CASES_FOR_TEST_FIXTURE( + NetworkContextConfigurationFixedPortBrowserTest); } // namespace
diff --git a/chrome/browser/net/predictor.cc b/chrome/browser/net/predictor.cc index 81c7794..ef77df0 100644 --- a/chrome/browser/net/predictor.cc +++ b/chrome/browser/net/predictor.cc
@@ -961,18 +961,16 @@ void Predictor::LookupFinished(const GURL& url, bool found) { DCHECK_CURRENTLY_ON(BrowserThread::IO); - auto info_it = results_.find(url); - UrlInfo* info = &info_it->second; + UrlInfo* info = &results_[url]; DCHECK(info->HasUrl(url)); - bool is_marked_to_delete = info->is_marked_to_delete(); - - if (found) - info->SetFoundState(); - else - info->SetNoSuchNameState(); - - if (is_marked_to_delete) - results_.erase(info_it); + if (info->is_marked_to_delete()) { + results_.erase(url); + } else { + if (found) + info->SetFoundState(); + else + info->SetNoSuchNameState(); + } } bool Predictor::WouldLikelyProxyURL(const GURL& url) {
diff --git a/chrome/browser/net/profile_network_context_service_browsertest.cc b/chrome/browser/net/profile_network_context_service_browsertest.cc index f9bdff4e..a749986 100644 --- a/chrome/browser/net/profile_network_context_service_browsertest.cc +++ b/chrome/browser/net/profile_network_context_service_browsertest.cc
@@ -23,11 +23,8 @@ #include "content/public/browser/storage_partition.h" #include "content/public/common/content_features.h" #include "content/public/common/network_service.mojom.h" -#include "content/public/common/resource_response.h" -#include "content/public/common/resource_response_info.h" -#include "content/public/common/url_loader.mojom.h" #include "content/public/common/url_loader_factory.mojom.h" -#include "content/public/test/test_url_loader_client.h" +#include "content/public/test/simple_url_loader_test_helper.h" #include "net/traffic_annotation/network_traffic_annotation_test_helper.h" #include "testing/gtest/include/gtest/gtest.h" @@ -73,21 +70,18 @@ IN_PROC_BROWSER_TEST_P(ProfileNetworkContextServiceBrowsertest, DiskCacheLocation) { - // Start a request, to give the network service time to create a cache - // directory. - content::mojom::URLLoaderPtr loader; + // Run a request that caches the response, to give the network service time to + // create a cache directory. + content::SimpleURLLoaderTestHelper simple_loader_helper; + std::unique_ptr<content::SimpleURLLoader> simple_loader = + content::SimpleURLLoader::Create(); content::ResourceRequest request; - content::TestURLLoaderClient client; request.url = embedded_test_server()->GetURL("/cachetime"); - request.method = "GET"; - loader_factory()->CreateLoaderAndStart( - mojo::MakeRequest(&loader), 2, 1, content::mojom::kURLLoadOptionNone, - request, client.CreateInterfacePtr(), - net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS)); - client.RunUntilResponseReceived(); - ASSERT_TRUE(client.response_head().headers); - EXPECT_EQ(200, client.response_head().headers->response_code()); - client.RunUntilResponseBodyArrived(); + simple_loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie( + request, loader_factory(), TRAFFIC_ANNOTATION_FOR_TESTS, + simple_loader_helper.GetCallback()); + simple_loader_helper.WaitForCallback(); + ASSERT_TRUE(simple_loader_helper.response_body()); base::FilePath expected_cache_path; chrome::GetUserCacheDirectory(browser()->profile()->GetPath(), @@ -126,21 +120,18 @@ ASSERT_EQ(TempPath(), browser()->profile()->GetPrefs()->GetFilePath( prefs::kDiskCacheDir)); - // Start a request, to give the network service time to create a cache - // directory. - content::mojom::URLLoaderPtr loader; + // Run a request that caches the response, to give the network service time to + // create a cache directory. + content::SimpleURLLoaderTestHelper simple_loader_helper; + std::unique_ptr<content::SimpleURLLoader> simple_loader = + content::SimpleURLLoader::Create(); content::ResourceRequest request; - content::TestURLLoaderClient client; request.url = embedded_test_server()->GetURL("/cachetime"); - request.method = "GET"; - loader_factory()->CreateLoaderAndStart( - mojo::MakeRequest(&loader), 2, 1, content::mojom::kURLLoadOptionNone, - request, client.CreateInterfacePtr(), - net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS)); - client.RunUntilResponseReceived(); - ASSERT_TRUE(client.response_head().headers); - EXPECT_EQ(200, client.response_head().headers->response_code()); - client.RunUntilResponseBodyArrived(); + simple_loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie( + request, loader_factory(), TRAFFIC_ANNOTATION_FOR_TESTS, + simple_loader_helper.GetCallback()); + simple_loader_helper.WaitForCallback(); + ASSERT_TRUE(simple_loader_helper.response_body()); // Cache directory should now exist. base::FilePath expected_cache_path =
diff --git a/chrome/browser/net/url_info.cc b/chrome/browser/net/url_info.cc index 83a8ae3..e46eaf555 100644 --- a/chrome/browser/net/url_info.cc +++ b/chrome/browser/net/url_info.cc
@@ -159,7 +159,7 @@ } void UrlInfo::SetFoundState() { - DCHECK(ASSIGNED == state_ || ASSIGNED_BUT_MARKED == state_); + DCHECK(ASSIGNED == state_); state_ = FOUND; resolve_duration_ = GetDuration(); const TimeDelta max_duration = MaxNonNetworkDnsLookupDuration(); @@ -172,7 +172,7 @@ } void UrlInfo::SetNoSuchNameState() { - DCHECK(ASSIGNED == state_ || ASSIGNED_BUT_MARKED == state_); + DCHECK(ASSIGNED == state_); state_ = NO_SUCH_NAME; resolve_duration_ = GetDuration(); #ifndef NDEBUG
diff --git a/chrome/browser/ssl/ssl_browser_tests.cc b/chrome/browser/ssl/ssl_browser_tests.cc index 6dd8d3a..01b975c 100644 --- a/chrome/browser/ssl/ssl_browser_tests.cc +++ b/chrome/browser/ssl/ssl_browser_tests.cc
@@ -4028,7 +4028,7 @@ } // Tests that if the timeout expires before the network time fetch -// returns, then a normal SSL intersitial is shown. +// returns, then a normal SSL interstitial is shown. IN_PROC_BROWSER_TEST_F(SSLNetworkTimeBrowserTest, TimeoutExpiresBeforeFetchCompletes) { ASSERT_TRUE(https_server_expired_.Start());
diff --git a/chrome/browser/ui/webui/print_preview/extension_printer_handler.cc b/chrome/browser/ui/webui/print_preview/extension_printer_handler.cc index 89e929ff..b584ae7 100644 --- a/chrome/browser/ui/webui/print_preview/extension_printer_handler.cc +++ b/chrome/browser/ui/webui/print_preview/extension_printer_handler.cc
@@ -184,8 +184,7 @@ const gfx::Size& page_size, const scoped_refptr<base::RefCountedBytes>& print_data, const PrinterHandler::PrintCallback& callback) { - std::unique_ptr<extensions::PrinterProviderPrintJob> print_job( - new extensions::PrinterProviderPrintJob()); + auto print_job = base::MakeUnique<extensions::PrinterProviderPrintJob>(); print_job->printer_id = destination_id; print_job->job_title = job_title; print_job->ticket_json = ticket_json;
diff --git a/chrome/browser/ui/webui/print_preview/extension_printer_handler_unittest.cc b/chrome/browser/ui/webui/print_preview/extension_printer_handler_unittest.cc index bbe4197..b45c0b7 100644 --- a/chrome/browser/ui/webui/print_preview/extension_printer_handler_unittest.cc +++ b/chrome/browser/ui/webui/print_preview/extension_printer_handler_unittest.cc
@@ -10,6 +10,7 @@ #include <memory> #include <queue> #include <string> +#include <utility> #include "base/bind.h" #include "base/files/file_util.h" @@ -457,18 +458,19 @@ class ExtensionPrinterHandlerTest : public testing::Test { public: - ExtensionPrinterHandlerTest() : pwg_raster_converter_(NULL) {} + ExtensionPrinterHandlerTest() = default; ~ExtensionPrinterHandlerTest() override = default; void SetUp() override { extensions::PrinterProviderAPIFactory::GetInstance()->SetTestingFactory( env_.profile(), &BuildTestingPrinterProviderAPI); - extension_printer_handler_.reset( - new ExtensionPrinterHandler(env_.profile())); + extension_printer_handler_ = + base::MakeUnique<ExtensionPrinterHandler>(env_.profile()); - pwg_raster_converter_ = new FakePWGRasterConverter(); + auto pwg_raster_converter = base::MakeUnique<FakePWGRasterConverter>(); + pwg_raster_converter_ = pwg_raster_converter.get(); extension_printer_handler_->SetPWGRasterConverterForTesting( - std::unique_ptr<PWGRasterConverter>(pwg_raster_converter_)); + std::move(pwg_raster_converter)); } protected: @@ -486,7 +488,8 @@ TestExtensionEnvironment env_; std::unique_ptr<ExtensionPrinterHandler> extension_printer_handler_; - FakePWGRasterConverter* pwg_raster_converter_; + // Owned by |extension_printer_handler_|. + FakePWGRasterConverter* pwg_raster_converter_ = nullptr; private: DISALLOW_COPY_AND_ASSIGN(ExtensionPrinterHandlerTest); @@ -545,11 +548,11 @@ } TEST_F(ExtensionPrinterHandlerTest, GetUsbPrinters) { - scoped_refptr<MockUsbDevice> device0 = - new MockUsbDevice(0, 0, "Google", "USB Printer", ""); + auto device0 = + base::MakeRefCounted<MockUsbDevice>(0, 0, "Google", "USB Printer", ""); usb_service().AddDevice(device0); - scoped_refptr<MockUsbDevice> device1 = - new MockUsbDevice(0, 1, "Google", "USB Printer", ""); + auto device1 = + base::MakeRefCounted<MockUsbDevice>(0, 1, "Google", "USB Printer", ""); usb_service().AddDevice(device1); const Extension* extension_1 = env_.MakeExtension( @@ -666,8 +669,8 @@ bool success = false; std::string status; - scoped_refptr<base::RefCountedBytes> print_data( - new base::RefCountedBytes(kPrintData, kPrintDataLength)); + auto print_data = + base::MakeRefCounted<base::RefCountedBytes>(kPrintData, kPrintDataLength); base::string16 title = base::ASCIIToUTF16("Title"); extension_printer_handler_->StartPrint( @@ -704,8 +707,8 @@ bool success = false; std::string status; - scoped_refptr<base::RefCountedBytes> print_data( - new base::RefCountedBytes(kPrintData, kPrintDataLength)); + auto print_data = + base::MakeRefCounted<base::RefCountedBytes>(kPrintData, kPrintDataLength); base::string16 title = base::ASCIIToUTF16("Title"); extension_printer_handler_->StartPrint( @@ -730,8 +733,8 @@ bool success = false; std::string status; - scoped_refptr<base::RefCountedBytes> print_data( - new base::RefCountedBytes(kPrintData, kPrintDataLength)); + auto print_data = + base::MakeRefCounted<base::RefCountedBytes>(kPrintData, kPrintDataLength); base::string16 title = base::ASCIIToUTF16("Title"); extension_printer_handler_->StartPrint( @@ -769,8 +772,8 @@ bool success = false; std::string status; - scoped_refptr<base::RefCountedBytes> print_data( - new base::RefCountedBytes(kPrintData, kPrintDataLength)); + auto print_data = + base::MakeRefCounted<base::RefCountedBytes>(kPrintData, kPrintDataLength); base::string16 title = base::ASCIIToUTF16("Title"); extension_printer_handler_->StartPrint( @@ -822,8 +825,8 @@ bool success = false; std::string status; - scoped_refptr<base::RefCountedBytes> print_data( - new base::RefCountedBytes(kPrintData, kPrintDataLength)); + auto print_data = + base::MakeRefCounted<base::RefCountedBytes>(kPrintData, kPrintDataLength); base::string16 title = base::ASCIIToUTF16("Title"); extension_printer_handler_->StartPrint( @@ -875,8 +878,8 @@ bool success = false; std::string status; - scoped_refptr<base::RefCountedBytes> print_data( - new base::RefCountedBytes(kPrintData, kPrintDataLength)); + auto print_data = + base::MakeRefCounted<base::RefCountedBytes>(kPrintData, kPrintDataLength); base::string16 title = base::ASCIIToUTF16("Title"); extension_printer_handler_->StartPrint( @@ -904,8 +907,8 @@ bool success = false; std::string status; - scoped_refptr<base::RefCountedBytes> print_data( - new base::RefCountedBytes(kPrintData, kPrintDataLength)); + auto print_data = + base::MakeRefCounted<base::RefCountedBytes>(kPrintData, kPrintDataLength); base::string16 title = base::ASCIIToUTF16("Title"); extension_printer_handler_->StartPrint( @@ -926,8 +929,8 @@ pwg_raster_converter_->FailConversion(); - scoped_refptr<base::RefCountedBytes> print_data( - new base::RefCountedBytes(kPrintData, kPrintDataLength)); + auto print_data = + base::MakeRefCounted<base::RefCountedBytes>(kPrintData, kPrintDataLength); base::string16 title = base::ASCIIToUTF16("Title"); extension_printer_handler_->StartPrint( @@ -942,8 +945,8 @@ } TEST_F(ExtensionPrinterHandlerTest, GrantUsbPrinterAccess) { - scoped_refptr<MockUsbDevice> device = - new MockUsbDevice(0, 0, "Google", "USB Printer", ""); + auto device = + base::MakeRefCounted<MockUsbDevice>(0, 0, "Google", "USB Printer", ""); usb_service().AddDevice(device); size_t call_count = 0; @@ -974,8 +977,8 @@ } TEST_F(ExtensionPrinterHandlerTest, GrantUsbPrinterAccess_Reset) { - scoped_refptr<MockUsbDevice> device = - new MockUsbDevice(0, 0, "Google", "USB Printer", ""); + auto device = + base::MakeRefCounted<MockUsbDevice>(0, 0, "Google", "USB Printer", ""); usb_service().AddDevice(device); size_t call_count = 0;
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_ui.cc b/chrome/browser/ui/webui/print_preview/print_preview_ui.cc index 6805fd3..5b7b1b6 100644 --- a/chrome/browser/ui/webui/print_preview/print_preview_ui.cc +++ b/chrome/browser/ui/webui/print_preview/print_preview_ui.cc
@@ -158,7 +158,7 @@ return true; } // Invalid request. - scoped_refptr<base::RefCountedBytes> empty_bytes(new base::RefCountedBytes); + auto empty_bytes = base::MakeRefCounted<base::RefCountedBytes>(); callback.Run(empty_bytes.get()); return true; }
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_ui_unittest.cc b/chrome/browser/ui/webui/print_preview/print_preview_ui_unittest.cc index 12910fa..b374eda8 100644 --- a/chrome/browser/ui/webui/print_preview/print_preview_ui_unittest.cc +++ b/chrome/browser/ui/webui/print_preview/print_preview_ui_unittest.cc
@@ -28,11 +28,11 @@ namespace { -base::RefCountedBytes* CreateTestData() { +scoped_refptr<base::RefCountedBytes> CreateTestData() { const unsigned char blob1[] = "12346102356120394751634516591348710478123649165419234519234512349134"; std::vector<unsigned char> preview_data(blob1, blob1 + sizeof(blob1)); - return new base::RefCountedBytes(preview_data); + return base::MakeRefCounted<base::RefCountedBytes>(preview_data); } bool IsShowingWebContentsModalDialog(WebContents* tab) { @@ -105,7 +105,7 @@ EXPECT_EQ(dummy_data.get(), data.get()); // This should not cause any memory leaks. - dummy_data = new base::RefCountedBytes(); + dummy_data = base::MakeRefCounted<base::RefCountedBytes>(); preview_ui->SetPrintPreviewDataForIndex(printing::FIRST_PAGE_INDEX, dummy_data.get());
diff --git a/chrome/browser/ui/webui/print_preview/printer_capabilities_unittest.cc b/chrome/browser/ui/webui/print_preview/printer_capabilities_unittest.cc index f06e3f2..06de50c 100644 --- a/chrome/browser/ui/webui/print_preview/printer_capabilities_unittest.cc +++ b/chrome/browser/ui/webui/print_preview/printer_capabilities_unittest.cc
@@ -23,7 +23,7 @@ protected: void SetUp() override { - test_backend_ = new TestPrintBackend(); + test_backend_ = base::MakeRefCounted<TestPrintBackend>(); PrintBackend::SetPrintBackendForTesting(test_backend_.get()); }
diff --git a/chrome/browser/ui/webui/print_preview/sticky_settings.cc b/chrome/browser/ui/webui/print_preview/sticky_settings.cc index b2507188..222469e 100644 --- a/chrome/browser/ui/webui/print_preview/sticky_settings.cc +++ b/chrome/browser/ui/webui/print_preview/sticky_settings.cc
@@ -4,6 +4,7 @@ #include "chrome/browser/ui/webui/print_preview/sticky_settings.h" +#include "base/memory/ptr_util.h" #include "base/values.h" #include "chrome/browser/profiles/profile.h" #include "chrome/common/pref_names.h" @@ -22,14 +23,18 @@ StickySettings::~StickySettings() {} -void StickySettings::StoreAppState(const std::string& data) { - printer_app_state_.reset(new std::string(data)); +const std::string* StickySettings::printer_app_state() const { + return printer_app_state_ ? &printer_app_state_.value() : nullptr; } -void StickySettings::SaveInPrefs(PrefService* prefs) { - std::unique_ptr<base::DictionaryValue> value(new base::DictionaryValue); +void StickySettings::StoreAppState(const std::string& data) { + printer_app_state_ = base::make_optional(data); +} + +void StickySettings::SaveInPrefs(PrefService* prefs) const { + auto value = base::MakeUnique<base::DictionaryValue>(); if (printer_app_state_) - value->SetString(kSettingAppState, *printer_app_state_); + value->SetString(kSettingAppState, printer_app_state_.value()); prefs->Set(prefs::kPrintPreviewStickySettings, *value); } @@ -41,13 +46,10 @@ StoreAppState(buffer); } +// static void StickySettings::RegisterProfilePrefs( user_prefs::PrefRegistrySyncable* registry) { registry->RegisterDictionaryPref(prefs::kPrintPreviewStickySettings); } -std::string* StickySettings::printer_app_state() { - return printer_app_state_.get(); -} - } // namespace printing
diff --git a/chrome/browser/ui/webui/print_preview/sticky_settings.h b/chrome/browser/ui/webui/print_preview/sticky_settings.h index ddc142b..e2a10d5c 100644 --- a/chrome/browser/ui/webui/print_preview/sticky_settings.h +++ b/chrome/browser/ui/webui/print_preview/sticky_settings.h
@@ -5,9 +5,9 @@ #ifndef CHROME_BROWSER_UI_WEBUI_PRINT_PREVIEW_STICKY_SETTINGS_H_ #define CHROME_BROWSER_UI_WEBUI_PRINT_PREVIEW_STICKY_SETTINGS_H_ -#include <memory> #include <string> +#include "base/optional.h" #include "printing/print_job_constants.h" class PrefService; @@ -26,17 +26,18 @@ StickySettings(); ~StickySettings(); - std::string* printer_app_state(); + const std::string* printer_app_state() const; // Stores app state for the last used printer. void StoreAppState(const std::string& app_state); - void SaveInPrefs(PrefService* profile); + void SaveInPrefs(PrefService* profile) const; void RestoreFromPrefs(PrefService* profile); + static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry); private: - std::unique_ptr<std::string> printer_app_state_; + base::Optional<std::string> printer_app_state_; }; } // namespace printing
diff --git a/chrome/browser/vr/ui_scene_manager.cc b/chrome/browser/vr/ui_scene_manager.cc index c7b9c26..406854c 100644 --- a/chrome/browser/vr/ui_scene_manager.cc +++ b/chrome/browser/vr/ui_scene_manager.cc
@@ -682,6 +682,10 @@ ConfigureScene(); } +void UiSceneManager::OnWebVrTimedOut() { + browser_->ExitPresent(); +} + void UiSceneManager::OnProjMatrixChanged(const gfx::Transform& proj_matrix) { // Determine if the projected size of the content quad changed more than a // given threshold. If so, propagate this info so that the content's
diff --git a/chrome/browser/vr/ui_scene_manager.h b/chrome/browser/vr/ui_scene_manager.h index 766ff5a..429a2b3 100644 --- a/chrome/browser/vr/ui_scene_manager.h +++ b/chrome/browser/vr/ui_scene_manager.h
@@ -64,6 +64,7 @@ void OnAppButtonClicked(); void OnAppButtonGesturePerformed(UiInterface::Direction direction); void OnWebVrFrameAvailable(); + void OnWebVrTimedOut(); void OnProjMatrixChanged(const gfx::Transform& proj_matrix); void SetExitVrPromptEnabled(bool enabled, UiUnsupportedMode reason);
diff --git a/chrome/common/stack_sampling_configuration.cc b/chrome/common/stack_sampling_configuration.cc index e28d59d9..b27023c 100644 --- a/chrome/common/stack_sampling_configuration.cc +++ b/chrome/common/stack_sampling_configuration.cc
@@ -215,9 +215,9 @@ case version_info::Channel::CANARY: return ChooseConfiguration({{PROFILE_BROWSER_PROCESS, 0}, {PROFILE_GPU_PROCESS, 0}, - {PROFILE_BROWSER_AND_GPU_PROCESS, 10}, - {PROFILE_CONTROL, 10}, - {PROFILE_DISABLED, 80}}); + {PROFILE_BROWSER_AND_GPU_PROCESS, 50}, + {PROFILE_CONTROL, 50}, + {PROFILE_DISABLED, 0}}); #endif default:
diff --git a/chrome/installer/linux/debian/dist-package-versions.json b/chrome/installer/linux/debian/dist-package-versions.json new file mode 100644 index 0000000..8537de3 --- /dev/null +++ b/chrome/installer/linux/debian/dist-package-versions.json
@@ -0,0 +1,240 @@ +{ + "Debian 10 (Buster)": { + "gconf-service": "3.2.6-4+b1", + "libasound2": "1.1.3-5", + "libatk1.0-0": "2.24.0-1", + "libc6": "2.24-14", + "libcairo2": "1.14.10-1", + "libcups2": "2.2.4-3", + "libdbus-1-3": "1.11.16+really1.10.22-1", + "libexpat1": "2.2.3-1", + "libfontconfig1": "2.12.3-0.2", + "libgcc1": "1:7.2.0-1", + "libgconf-2-4": "3.2.6-4+b1", + "libgdk-pixbuf2.0-0": "2.36.5-2", + "libglib2.0-0": "2.53.4-3", + "libgtk-3-0": "3.22.18-1", + "libnspr4": "2:4.16-1", + "libnss3": "2:3.31-1", + "libpango-1.0-0": "1.40.6-1", + "libpangocairo-1.0-0": "1.40.6-1", + "libstdc++6": "7.2.0-1", + "libx11-6": "2:1.6.4-3", + "libx11-xcb1": "2:1.6.4-3", + "libxcb1": "1.12-1", + "libxcomposite1": "1:0.4.4-2", + "libxcursor1": "1:1.1.14-1+b4", + "libxdamage1": "1:1.1.4-3", + "libxext6": "2:1.3.3-1+b2", + "libxfixes3": "1:5.0.3-1", + "libxi6": "2:1.7.9-1", + "libxrandr2": "2:1.5.1-1", + "libxrender1": "1:0.9.10-1", + "libxss1": "1:1.2.2-1+b2", + "libxtst6": "2:1.2.3-1" + }, + "Debian 8 (Jessie)": { + "gconf-service": "3.2.6-3", + "libasound2": "1.0.28-1", + "libatk1.0-0": "2.14.0-1", + "libc6": "2.19-18+deb8u10", + "libcairo2": "1.14.0-2.1+deb8u2", + "libcups2": "1.7.5-11+deb8u1", + "libdbus-1-3": "1.8.22-0+deb8u1", + "libexpat1": "2.1.0-6+deb8u4", + "libfontconfig1": "2.11.0-6.3+deb8u1", + "libgcc1": "1:4.9.2-10", + "libgconf-2-4": "3.2.6-3", + "libgdk-pixbuf2.0-0": "2.31.1-2+deb8u5", + "libglib2.0-0": "2.42.1-1+b1", + "libgtk-3-0": "3.14.5-1+deb8u1", + "libnspr4": "2:4.12-1+debu8u1", + "libnss3": "2:3.26-1+debu8u2", + "libpango-1.0-0": "1.36.8-3", + "libpangocairo-1.0-0": "1.36.8-3", + "libstdc++6": "4.9.2-10", + "libx11-6": "2:1.6.2-3", + "libx11-xcb1": "2:1.6.2-3", + "libxcb1": "1.10-3+b1", + "libxcomposite1": "1:0.4.4-1", + "libxcursor1": "1:1.1.14-1+b1", + "libxdamage1": "1:1.1.4-2+b1", + "libxext6": "2:1.3.3-1", + "libxfixes3": "1:5.0.1-2+b2", + "libxi6": "2:1.7.4-1+b2", + "libxrandr2": "2:1.4.2-1+b1", + "libxrender1": "1:0.9.8-1+b1", + "libxss1": "1:1.2.2-1", + "libxtst6": "2:1.2.2-1+b1" + }, + "Debian 9 (Stretch)": { + "gconf-service": "3.2.6-4+b1", + "libasound2": "1.1.3-5", + "libatk1.0-0": "2.22.0-1", + "libc6": "2.24-11+deb9u1", + "libcairo2": "1.14.8-1", + "libcups2": "2.2.1-8", + "libdbus-1-3": "1.10.18-1", + "libexpat1": "2.2.0-2+deb9u1", + "libfontconfig1": "2.11.0-6.7+b1", + "libgcc1": "1:6.3.0-18", + "libgconf-2-4": "3.2.6-4+b1", + "libgdk-pixbuf2.0-0": "2.36.5-2", + "libglib2.0-0": "2.50.3-2", + "libgtk-3-0": "3.22.11-1", + "libnspr4": "2:4.12-6", + "libnss3": "2:3.26.2-1.1", + "libpango-1.0-0": "1.40.5-1", + "libpangocairo-1.0-0": "1.40.5-1", + "libstdc++6": "6.3.0-18", + "libx11-6": "2:1.6.4-3", + "libx11-xcb1": "2:1.6.4-3", + "libxcb1": "1.12-1", + "libxcomposite1": "1:0.4.4-2", + "libxcursor1": "1:1.1.14-1+b4", + "libxdamage1": "1:1.1.4-2+b3", + "libxext6": "2:1.3.3-1+b2", + "libxfixes3": "1:5.0.3-1", + "libxi6": "2:1.7.9-1", + "libxrandr2": "2:1.5.1-1", + "libxrender1": "1:0.9.10-1", + "libxss1": "1:1.2.2-1", + "libxtst6": "2:1.2.3-1" + }, + "Ubuntu 14.04 (Trusty)": { + "gconf-service": "3.2.6-0ubuntu2", + "libasound2": "1.0.27.2-3ubuntu7", + "libatk1.0-0": "2.10.0-2ubuntu2", + "libc6": "2.19-0ubuntu6.13", + "libcairo2": "1.13.0~20140204-0ubuntu1.1", + "libcups2": "1.7.2-0ubuntu1.7", + "libdbus-1-3": "1.6.18-0ubuntu4.4", + "libexpat1": "2.1.0-4ubuntu1.4", + "libfontconfig1": "2.11.0-0ubuntu4.2", + "libgcc1": "1:4.9.3-0ubuntu4", + "libgconf-2-4": "3.2.6-0ubuntu2", + "libgdk-pixbuf2.0-0": "2.30.7-0ubuntu1.6", + "libglib2.0-0": "2.40.2-0ubuntu1", + "libgtk-3-0": "3.10.8-0ubuntu1.4", + "libnspr4": "2:4.13.1-0ubuntu0.14.04.1", + "libnss3": "2:3.28.4-0ubuntu0.14.04.2", + "libpango-1.0-0": "1.36.3-1ubuntu1.1", + "libpangocairo-1.0-0": "1.36.3-1ubuntu1.1", + "libstdc++6": "4.8.4-2ubuntu1~14.04.3", + "libx11-6": "2:1.6.2-1ubuntu2", + "libx11-xcb1": "2:1.6.2-1ubuntu2", + "libxcb1": "1.10-2ubuntu1", + "libxcomposite1": "1:0.4.4-1", + "libxcursor1": "1:1.1.14-1", + "libxdamage1": "1:1.1.4-1ubuntu1", + "libxext6": "2:1.3.2-1ubuntu0.0.14.04.1", + "libxfixes3": "1:5.0.1-1ubuntu1.1", + "libxi6": "2:1.7.1.901-1ubuntu1.1", + "libxrandr2": "2:1.5.0-1~trusty1", + "libxrender1": "1:0.9.8-1build0.14.04.1", + "libxss1": "1:1.2.2-1", + "libxtst6": "2:1.2.2-1" + }, + "Ubuntu 16.04 (Xenial)": { + "gconf-service": "3.2.6-3ubuntu6", + "libasound2": "1.1.0-0ubuntu1", + "libatk1.0-0": "2.18.0-1", + "libc6": "2.23-0ubuntu9", + "libcairo2": "1.14.6-1", + "libcups2": "2.1.3-4", + "libdbus-1-3": "1.10.6-1ubuntu3.1", + "libexpat1": "2.1.0-7ubuntu0.16.04.3", + "libfontconfig1": "2.11.94-0ubuntu1.1", + "libgcc1": "1:6.0.1-0ubuntu1", + "libgconf-2-4": "3.2.6-3ubuntu6", + "libgdk-pixbuf2.0-0": "2.32.2-1ubuntu1.2", + "libglib2.0-0": "2.48.2-0ubuntu1", + "libgtk-3-0": "3.18.9-1ubuntu3.3", + "libnspr4": "2:4.13.1-0ubuntu0.16.04.1", + "libnss3": "2:3.28.4-0ubuntu0.16.04.2", + "libpango-1.0-0": "1.38.1-1", + "libpangocairo-1.0-0": "1.38.1-1", + "libstdc++6": "5.4.0-6ubuntu1~16.04.4", + "libx11-6": "2:1.6.3-1ubuntu2", + "libx11-xcb1": "2:1.6.3-1ubuntu2", + "libxcb1": "1.11.1-1ubuntu1", + "libxcomposite1": "1:0.4.4-1", + "libxcursor1": "1:1.1.14-1", + "libxdamage1": "1:1.1.4-2", + "libxext6": "2:1.3.3-1", + "libxfixes3": "1:5.0.1-2", + "libxi6": "2:1.7.6-1", + "libxrandr2": "2:1.5.0-1", + "libxrender1": "1:0.9.9-0ubuntu1", + "libxss1": "1:1.2.2-1", + "libxtst6": "2:1.2.2-1" + }, + "Ubuntu 17.04 (Zesty)": { + "gconf-service": "3.2.6-3ubuntu7", + "libasound2": "1.1.3-5", + "libatk1.0-0": "2.22.0-1", + "libc6": "2.24-9ubuntu2.2", + "libcairo2": "1.14.8-1", + "libcups2": "2.2.2-1ubuntu1", + "libdbus-1-3": "1.10.10-1ubuntu2", + "libexpat1": "2.2.0-2ubuntu0.1", + "libfontconfig1": "2.11.94-0ubuntu2", + "libgcc1": "1:6.3.0-12ubuntu2", + "libgconf-2-4": "3.2.6-3ubuntu7", + "libgdk-pixbuf2.0-0": "2.36.5-3", + "libglib2.0-0": "2.52.0-1", + "libgtk-3-0": "3.22.11-0ubuntu3", + "libnspr4": "2:4.13.1-0ubuntu0.17.04.1", + "libnss3": "2:3.28.4-0ubuntu0.17.04.2", + "libpango-1.0-0": "1.40.4-1", + "libpangocairo-1.0-0": "1.40.4-1", + "libstdc++6": "6.3.0-12ubuntu2", + "libx11-6": "2:1.6.4-3", + "libx11-xcb1": "2:1.6.4-3", + "libxcb1": "1.11.1-1ubuntu1", + "libxcomposite1": "1:0.4.4-2", + "libxcursor1": "1:1.1.14-1", + "libxdamage1": "1:1.1.4-2", + "libxext6": "2:1.3.3-1", + "libxfixes3": "1:5.0.3-1", + "libxi6": "2:1.7.9-1", + "libxrandr2": "2:1.5.1-1", + "libxrender1": "1:0.9.10-1", + "libxss1": "1:1.2.2-1", + "libxtst6": "2:1.2.3-1" + }, + "Ubuntu 17.10 (Artful)": { + "gconf-service": "3.2.6-4ubuntu1", + "libasound2": "1.1.3-5", + "libatk1.0-0": "2.25.90-0ubuntu1", + "libc6": "2.24-12ubuntu1", + "libcairo2": "1.14.10-1", + "libcups2": "2.2.4-5", + "libdbus-1-3": "1.10.22-1ubuntu1", + "libexpat1": "2.2.3-1", + "libfontconfig1": "2.11.94-0ubuntu2", + "libgcc1": "1:7.2.0-1ubuntu2", + "libgconf-2-4": "3.2.6-4ubuntu1", + "libgdk-pixbuf2.0-0": "2.36.5-3", + "libglib2.0-0": "2.53.6-1ubuntu1", + "libgtk-3-0": "3.22.19-0ubuntu1", + "libnspr4": "2:4.16-1ubuntu1", + "libnss3": "2:3.32-1ubuntu2", + "libpango-1.0-0": "1.40.11-1", + "libpangocairo-1.0-0": "1.40.11-1", + "libstdc++6": "7.2.0-1ubuntu2", + "libx11-6": "2:1.6.4-3", + "libx11-xcb1": "2:1.6.4-3", + "libxcb1": "1.11.1-1ubuntu1", + "libxcomposite1": "1:0.4.4-2", + "libxcursor1": "1:1.1.14-3", + "libxdamage1": "1:1.1.4-3", + "libxext6": "2:1.3.3-1", + "libxfixes3": "1:5.0.3-1", + "libxi6": "2:1.7.9-1", + "libxrandr2": "2:1.5.1-1", + "libxrender1": "1:0.9.10-1", + "libxss1": "1:1.2.2-1", + "libxtst6": "2:1.2.3-1" + } +}
diff --git a/chrome/installer/linux/debian/download-repo-signing-keys.sh b/chrome/installer/linux/debian/download-repo-signing-keys.sh new file mode 100755 index 0000000..d8c2596d --- /dev/null +++ b/chrome/installer/linux/debian/download-repo-signing-keys.sh
@@ -0,0 +1,29 @@ +#!/bin/bash +# 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. + +set -o nounset +set -o errexit + +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +KEY_FINGERS=( + # Debian Archive Automatic Signing Key (7.0/wheezy) + "A1BD8E9D78F7FE5C3E65D8AF8B48AD6246925553" + # Debian Archive Automatic Signing Key (8/jessie) + "126C0D24BD8A2942CC7DF8AC7638D0442B90D010" + # Debian Security Archive Automatic Signing Key (8/jessie) + "D21169141CECD440F2EB8DDA9D6D8F6BC857C906" + # Jessie Stable Release Key + "75DDC3C4A499F1A18CB5F3C8CBF8D6FD518E17E1" + # Debian Stable Release Key (9/stretch) + "067E3C456BAE240ACEE88F6FEF0F382A1A7B6500" + # Ubuntu Archive Automatic Signing Key + "630239CC130E1A7FD81A27B140976EAF437D05B5" + # Ubuntu Archive Automatic Signing Key (2012) + "790BC7277767219C42C86F933B4FE6ACC0B21F32" +) + +gpg --keyserver pgp.mit.edu --recv-keys ${KEY_FINGERS[@]} +gpg --output "${SCRIPT_DIR}/repo_signing_keys.gpg" --export ${KEY_FINGERS[@]}
diff --git a/chrome/installer/linux/debian/repo_signing_keys.gpg b/chrome/installer/linux/debian/repo_signing_keys.gpg new file mode 100644 index 0000000..9cf5e93 --- /dev/null +++ b/chrome/installer/linux/debian/repo_signing_keys.gpg Binary files differ
diff --git a/chrome/installer/linux/debian/update-dist-package-versions.py b/chrome/installer/linux/debian/update-dist-package-versions.py new file mode 100755 index 0000000..7d49b6f --- /dev/null +++ b/chrome/installer/linux/debian/update-dist-package-versions.py
@@ -0,0 +1,154 @@ +#!/usr/bin/env python +# 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. + +"""Downloads package lists and records package versions into +dist-package-versions.json. +""" + +import binascii +import cStringIO +import gzip +import hashlib +import json +import os +import re +import subprocess +import sys +import tempfile +import urllib2 + +SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__)) + +SUPPORTED_DEBIAN_RELEASES = { + 'Debian 8 (Jessie)': 'jessie', + 'Debian 9 (Stretch)': 'stretch', + 'Debian 10 (Buster)': 'buster', +} + +SUPPORTED_UBUNTU_RELEASES = { + 'Ubuntu 14.04 (Trusty)': 'trusty', + 'Ubuntu 16.04 (Xenial)': 'xenial', + 'Ubuntu 17.04 (Zesty)': 'zesty', + 'Ubuntu 17.10 (Artful)': 'artful', +} + +PACKAGE_FILTER = set([ + "gconf-service", + "libasound2", + "libatk1.0-0", + "libc6", + "libcairo2", + "libcups2", + "libdbus-1-3", + "libexpat1", + "libfontconfig1", + "libgcc1", + "libgconf-2-4", + "libgdk-pixbuf2.0-0", + "libglib2.0-0", + "libgtk-3-0", + "libnspr4", + "libnss3", + "libpango-1.0-0", + "libpangocairo-1.0-0", + "libstdc++6", + "libx11-6", + "libx11-xcb1", + "libxcb1", + "libxcomposite1", + "libxcursor1", + "libxdamage1", + "libxext6", + "libxfixes3", + "libxi6", + "libxrandr2", + "libxrender1", + "libxss1", + "libxtst6", +]) + +def create_temp_file_from_data(data): + file = tempfile.NamedTemporaryFile() + file.write(data) + file.flush() + return file + +if sys.platform != 'linux2': + print >> sys.stderr, "Only supported on Linux." + sys.exit(1) + +deb_sources = {} +for release in SUPPORTED_DEBIAN_RELEASES: + codename = SUPPORTED_DEBIAN_RELEASES[release] + deb_sources[release] = [ + { + "base_url": url, + "packages": [ "main/binary-amd64/Packages.gz" ] + } for url in [ + "http://ftp.us.debian.org/debian/dists/%s" % codename, + "http://ftp.us.debian.org/debian/dists/%s-updates" % codename, + "http://security.debian.org/dists/%s/updates" % codename, + ] + ] +for release in SUPPORTED_UBUNTU_RELEASES: + codename = SUPPORTED_UBUNTU_RELEASES[release] + repos = ['main', 'universe'] + deb_sources[release] = [ + { + "base_url": url, + "packages": [ + "%s/binary-amd64/Packages.gz" % repo for repo in repos + ], + } for url in [ + "http://us.archive.ubuntu.com/ubuntu/dists/%s" % codename, + "http://us.archive.ubuntu.com/ubuntu/dists/%s-updates" % codename, + "http://security.ubuntu.com/ubuntu/dists/%s-security" % codename, + ] + ] + +distro_package_versions = {} +package_regex = re.compile('^Package: (.*)$') +version_regex = re.compile('^Version: (.*)$') +for distro in deb_sources: + package_versions = {} + for source in deb_sources[distro]: + base_url = source["base_url"] + release = urllib2.urlopen("%s/Release" % base_url).read() + release_gpg = urllib2.urlopen("%s/Release.gpg" % base_url).read() + keyring = os.path.join(SCRIPT_DIR, 'repo_signing_keys.gpg') + release_file = create_temp_file_from_data(release) + release_gpg_file = create_temp_file_from_data(release_gpg) + subprocess.check_output(['gpgv', '--quiet', '--keyring', keyring, + release_gpg_file.name, release_file.name]) + for packages_gz in source["packages"]: + gz_data = urllib2.urlopen("%s/%s" % (base_url, packages_gz)).read() + + sha = hashlib.sha256() + sha.update(gz_data) + digest = binascii.hexlify(sha.digest()) + matches = [line for line in release.split('\n') + if digest in line and packages_gz in line] + assert len(matches) == 1 + + zipped_file = cStringIO.StringIO() + zipped_file.write(gz_data) + zipped_file.seek(0) + contents = gzip.GzipFile(fileobj=zipped_file, mode='rb').read() + package = '' + for line in contents.split('\n'): + if line.startswith('Package: '): + match = re.search(package_regex, line) + package = match.group(1) + elif line.startswith('Version: '): + match = re.search(version_regex, line) + version = match.group(1) + if package in PACKAGE_FILTER: + package_versions[package] = version + distro_package_versions[distro] = package_versions + +with open(os.path.join(SCRIPT_DIR, 'dist-package-versions.json'), 'w') as f: + f.write(json.dumps(distro_package_versions, sort_keys=True, indent=4, + separators=(',', ': '))) + f.write('\n')
diff --git a/chrome/installer/linux/rpm/dist-package-provides.json b/chrome/installer/linux/rpm/dist-package-provides.json new file mode 100644 index 0000000..79ad0ed --- /dev/null +++ b/chrome/installer/linux/rpm/dist-package-provides.json
@@ -0,0 +1,1139 @@ +{ + "Fedora 25": [ + "ld-linux-x86-64.so.2()(64bit)", + "ld-linux-x86-64.so.2(GLIBC_2.2.5)(64bit)", + "ld-linux-x86-64.so.2(GLIBC_2.3)(64bit)", + "ld-linux-x86-64.so.2(GLIBC_2.4)(64bit)", + "libX11-xcb.so.1()(64bit)", + "libX11.so.6()(64bit)", + "libXcomposite.so.1()(64bit)", + "libXcursor.so.1()(64bit)", + "libXdamage.so.1()(64bit)", + "libXext.so.6()(64bit)", + "libXfixes.so.3()(64bit)", + "libXi.so.6()(64bit)", + "libXrandr.so.2()(64bit)", + "libXrender.so.1()(64bit)", + "libXss.so.1()(64bit)", + "libXtst.so.6()(64bit)", + "libasound.so.2()(64bit)", + "libasound.so.2(ALSA_0.9)(64bit)", + "libasound.so.2(ALSA_0.9.0)(64bit)", + "libasound.so.2(ALSA_0.9.0rc4)(64bit)", + "libasound.so.2(ALSA_0.9.0rc8)(64bit)", + "libasound.so.2(ALSA_0.9.3)(64bit)", + "libasound.so.2(ALSA_0.9.5)(64bit)", + "libasound.so.2(ALSA_0.9.7)(64bit)", + "libatk-1.0.so.0()(64bit)", + "libc.so.6()(64bit)", + "libc.so.6(GLIBC_2.10)(64bit)", + "libc.so.6(GLIBC_2.11)(64bit)", + "libc.so.6(GLIBC_2.12)(64bit)", + "libc.so.6(GLIBC_2.13)(64bit)", + "libc.so.6(GLIBC_2.14)(64bit)", + "libc.so.6(GLIBC_2.15)(64bit)", + "libc.so.6(GLIBC_2.16)(64bit)", + "libc.so.6(GLIBC_2.17)(64bit)", + "libc.so.6(GLIBC_2.18)(64bit)", + "libc.so.6(GLIBC_2.2.5)(64bit)", + "libc.so.6(GLIBC_2.2.6)(64bit)", + "libc.so.6(GLIBC_2.22)(64bit)", + "libc.so.6(GLIBC_2.23)(64bit)", + "libc.so.6(GLIBC_2.24)(64bit)", + "libc.so.6(GLIBC_2.3)(64bit)", + "libc.so.6(GLIBC_2.3.2)(64bit)", + "libc.so.6(GLIBC_2.3.3)(64bit)", + "libc.so.6(GLIBC_2.3.4)(64bit)", + "libc.so.6(GLIBC_2.4)(64bit)", + "libc.so.6(GLIBC_2.5)(64bit)", + "libc.so.6(GLIBC_2.6)(64bit)", + "libc.so.6(GLIBC_2.7)(64bit)", + "libc.so.6(GLIBC_2.8)(64bit)", + "libc.so.6(GLIBC_2.9)(64bit)", + "libcairo.so()(64bit)", + "libcairo.so.2()(64bit)", + "libcups.so.2()(64bit)", + "libdbus-1.so.3()(64bit)", + "libdbus-1.so.3(LIBDBUS_1_3)(64bit)", + "libdbus-1.so.3(LIBDBUS_PRIVATE_1.11.16)(64bit)", + "libdl.so.2()(64bit)", + "libdl.so.2(GLIBC_2.2.5)(64bit)", + "libdl.so.2(GLIBC_2.3.3)(64bit)", + "libdl.so.2(GLIBC_2.3.4)(64bit)", + "libexpat.so.0()(64bit)", + "libexpat.so.1()(64bit)", + "libfontconfig.so.1()(64bit)", + "libgcc_s.so.1()(64bit)", + "libgcc_s.so.1(GCC_3.0)(64bit)", + "libgcc_s.so.1(GCC_3.3)(64bit)", + "libgcc_s.so.1(GCC_3.3.1)(64bit)", + "libgcc_s.so.1(GCC_3.4)(64bit)", + "libgcc_s.so.1(GCC_3.4.2)(64bit)", + "libgcc_s.so.1(GCC_3.4.4)(64bit)", + "libgcc_s.so.1(GCC_4.0.0)(64bit)", + "libgcc_s.so.1(GCC_4.2.0)(64bit)", + "libgcc_s.so.1(GCC_4.3.0)(64bit)", + "libgcc_s.so.1(GCC_4.7.0)(64bit)", + "libgcc_s.so.1(GCC_4.8.0)(64bit)", + "libgconf-2.so.4()(64bit)", + "libgdk-3.so.0()(64bit)", + "libgdk_pixbuf-2.0.so.0()(64bit)", + "libgio-2.0.so.0()(64bit)", + "libglib-2.0.so.0()(64bit)", + "libgmodule-2.0.so.0()(64bit)", + "libgobject-2.0.so.0()(64bit)", + "libgtk-3.so.0()(64bit)", + "libm.so.6()(64bit)", + "libm.so.6(GLIBC_2.15)(64bit)", + "libm.so.6(GLIBC_2.18)(64bit)", + "libm.so.6(GLIBC_2.2.5)(64bit)", + "libm.so.6(GLIBC_2.23)(64bit)", + "libm.so.6(GLIBC_2.24)(64bit)", + "libm.so.6(GLIBC_2.4)(64bit)", + "libnspr4.so()(64bit)", + "libnss3.so()(64bit)", + "libnss3.so(NSS_3.10)(64bit)", + "libnss3.so(NSS_3.10.2)(64bit)", + "libnss3.so(NSS_3.11)(64bit)", + "libnss3.so(NSS_3.11.1)(64bit)", + "libnss3.so(NSS_3.11.2)(64bit)", + "libnss3.so(NSS_3.11.7)(64bit)", + "libnss3.so(NSS_3.11.9)(64bit)", + "libnss3.so(NSS_3.12)(64bit)", + "libnss3.so(NSS_3.12.1)(64bit)", + "libnss3.so(NSS_3.12.10)(64bit)", + "libnss3.so(NSS_3.12.3)(64bit)", + "libnss3.so(NSS_3.12.4)(64bit)", + "libnss3.so(NSS_3.12.5)(64bit)", + "libnss3.so(NSS_3.12.6)(64bit)", + "libnss3.so(NSS_3.12.7)(64bit)", + "libnss3.so(NSS_3.12.9)(64bit)", + "libnss3.so(NSS_3.13)(64bit)", + "libnss3.so(NSS_3.13.2)(64bit)", + "libnss3.so(NSS_3.14)(64bit)", + "libnss3.so(NSS_3.14.1)(64bit)", + "libnss3.so(NSS_3.14.3)(64bit)", + "libnss3.so(NSS_3.15)(64bit)", + "libnss3.so(NSS_3.15.4)(64bit)", + "libnss3.so(NSS_3.16.1)(64bit)", + "libnss3.so(NSS_3.16.2)(64bit)", + "libnss3.so(NSS_3.18)(64bit)", + "libnss3.so(NSS_3.19)(64bit)", + "libnss3.so(NSS_3.19.1)(64bit)", + "libnss3.so(NSS_3.2)(64bit)", + "libnss3.so(NSS_3.2.1)(64bit)", + "libnss3.so(NSS_3.21)(64bit)", + "libnss3.so(NSS_3.22)(64bit)", + "libnss3.so(NSS_3.3)(64bit)", + "libnss3.so(NSS_3.3.1)(64bit)", + "libnss3.so(NSS_3.30)(64bit)", + "libnss3.so(NSS_3.31)(64bit)", + "libnss3.so(NSS_3.4)(64bit)", + "libnss3.so(NSS_3.5)(64bit)", + "libnss3.so(NSS_3.6)(64bit)", + "libnss3.so(NSS_3.7)(64bit)", + "libnss3.so(NSS_3.7.1)(64bit)", + "libnss3.so(NSS_3.8)(64bit)", + "libnss3.so(NSS_3.9)(64bit)", + "libnss3.so(NSS_3.9.2)(64bit)", + "libnss3.so(NSS_3.9.3)(64bit)", + "libnssutil3.so()(64bit)", + "libnssutil3.so(NSSUTIL_3.12)(64bit)", + "libnssutil3.so(NSSUTIL_3.12.3)(64bit)", + "libnssutil3.so(NSSUTIL_3.12.5)(64bit)", + "libnssutil3.so(NSSUTIL_3.12.7)(64bit)", + "libnssutil3.so(NSSUTIL_3.13)(64bit)", + "libnssutil3.so(NSSUTIL_3.14)(64bit)", + "libnssutil3.so(NSSUTIL_3.15)(64bit)", + "libnssutil3.so(NSSUTIL_3.17.1)(64bit)", + "libnssutil3.so(NSSUTIL_3.21)(64bit)", + "libnssutil3.so(NSSUTIL_3.24)(64bit)", + "libnssutil3.so(NSSUTIL_3.25)(64bit)", + "libnssutil3.so(NSSUTIL_3.31)(64bit)", + "libpango-1.0.so.0()(64bit)", + "libpangocairo-1.0.so.0()(64bit)", + "libpthread.so.0()(64bit)", + "libpthread.so.0(GLIBC_2.11)(64bit)", + "libpthread.so.0(GLIBC_2.12)(64bit)", + "libpthread.so.0(GLIBC_2.18)(64bit)", + "libpthread.so.0(GLIBC_2.2.5)(64bit)", + "libpthread.so.0(GLIBC_2.2.6)(64bit)", + "libpthread.so.0(GLIBC_2.3.2)(64bit)", + "libpthread.so.0(GLIBC_2.3.3)(64bit)", + "libpthread.so.0(GLIBC_2.3.4)(64bit)", + "libpthread.so.0(GLIBC_2.4)(64bit)", + "librt.so.1()(64bit)", + "librt.so.1(GLIBC_2.2.5)(64bit)", + "librt.so.1(GLIBC_2.3.3)(64bit)", + "librt.so.1(GLIBC_2.3.4)(64bit)", + "librt.so.1(GLIBC_2.4)(64bit)", + "librt.so.1(GLIBC_2.7)(64bit)", + "libsmime3.so()(64bit)", + "libsmime3.so(NSS_3.10)(64bit)", + "libsmime3.so(NSS_3.12.10)(64bit)", + "libsmime3.so(NSS_3.12.2)(64bit)", + "libsmime3.so(NSS_3.13)(64bit)", + "libsmime3.so(NSS_3.15)(64bit)", + "libsmime3.so(NSS_3.16)(64bit)", + "libsmime3.so(NSS_3.18)(64bit)", + "libsmime3.so(NSS_3.2)(64bit)", + "libsmime3.so(NSS_3.2.1)(64bit)", + "libsmime3.so(NSS_3.3)(64bit)", + "libsmime3.so(NSS_3.4)(64bit)", + "libsmime3.so(NSS_3.4.1)(64bit)", + "libsmime3.so(NSS_3.6)(64bit)", + "libsmime3.so(NSS_3.7)(64bit)", + "libsmime3.so(NSS_3.7.2)(64bit)", + "libsmime3.so(NSS_3.8)(64bit)", + "libsmime3.so(NSS_3.9)(64bit)", + "libsmime3.so(NSS_3.9.3)(64bit)", + "libxcb.so.1()(64bit)" + ], + "Fedora 26": [ + "ld-linux-x86-64.so.2()(64bit)", + "ld-linux-x86-64.so.2(GLIBC_2.2.5)(64bit)", + "ld-linux-x86-64.so.2(GLIBC_2.3)(64bit)", + "ld-linux-x86-64.so.2(GLIBC_2.4)(64bit)", + "libX11-xcb.so.1()(64bit)", + "libX11.so.6()(64bit)", + "libXcomposite.so.1()(64bit)", + "libXcursor.so.1()(64bit)", + "libXdamage.so.1()(64bit)", + "libXext.so.6()(64bit)", + "libXfixes.so.3()(64bit)", + "libXi.so.6()(64bit)", + "libXrandr.so.2()(64bit)", + "libXrender.so.1()(64bit)", + "libXss.so.1()(64bit)", + "libXtst.so.6()(64bit)", + "libasound.so.2()(64bit)", + "libasound.so.2(ALSA_0.9)(64bit)", + "libasound.so.2(ALSA_0.9.0)(64bit)", + "libasound.so.2(ALSA_0.9.0rc4)(64bit)", + "libasound.so.2(ALSA_0.9.0rc8)(64bit)", + "libasound.so.2(ALSA_0.9.3)(64bit)", + "libasound.so.2(ALSA_0.9.5)(64bit)", + "libasound.so.2(ALSA_0.9.7)(64bit)", + "libatk-1.0.so.0()(64bit)", + "libc.so.6()(64bit)", + "libc.so.6(GLIBC_2.10)(64bit)", + "libc.so.6(GLIBC_2.11)(64bit)", + "libc.so.6(GLIBC_2.12)(64bit)", + "libc.so.6(GLIBC_2.13)(64bit)", + "libc.so.6(GLIBC_2.14)(64bit)", + "libc.so.6(GLIBC_2.15)(64bit)", + "libc.so.6(GLIBC_2.16)(64bit)", + "libc.so.6(GLIBC_2.17)(64bit)", + "libc.so.6(GLIBC_2.18)(64bit)", + "libc.so.6(GLIBC_2.2.5)(64bit)", + "libc.so.6(GLIBC_2.2.6)(64bit)", + "libc.so.6(GLIBC_2.22)(64bit)", + "libc.so.6(GLIBC_2.23)(64bit)", + "libc.so.6(GLIBC_2.24)(64bit)", + "libc.so.6(GLIBC_2.25)(64bit)", + "libc.so.6(GLIBC_2.3)(64bit)", + "libc.so.6(GLIBC_2.3.2)(64bit)", + "libc.so.6(GLIBC_2.3.3)(64bit)", + "libc.so.6(GLIBC_2.3.4)(64bit)", + "libc.so.6(GLIBC_2.4)(64bit)", + "libc.so.6(GLIBC_2.5)(64bit)", + "libc.so.6(GLIBC_2.6)(64bit)", + "libc.so.6(GLIBC_2.7)(64bit)", + "libc.so.6(GLIBC_2.8)(64bit)", + "libc.so.6(GLIBC_2.9)(64bit)", + "libcairo.so()(64bit)", + "libcairo.so.2()(64bit)", + "libcups.so.2()(64bit)", + "libdbus-1.so.3()(64bit)", + "libdbus-1.so.3(LIBDBUS_1_3)(64bit)", + "libdbus-1.so.3(LIBDBUS_PRIVATE_1.11.16)(64bit)", + "libdl.so.2()(64bit)", + "libdl.so.2(GLIBC_2.2.5)(64bit)", + "libdl.so.2(GLIBC_2.3.3)(64bit)", + "libdl.so.2(GLIBC_2.3.4)(64bit)", + "libexpat.so.0()(64bit)", + "libexpat.so.1()(64bit)", + "libfontconfig.so.1()(64bit)", + "libgcc_s.so.1()(64bit)", + "libgcc_s.so.1(GCC_3.0)(64bit)", + "libgcc_s.so.1(GCC_3.3)(64bit)", + "libgcc_s.so.1(GCC_3.3.1)(64bit)", + "libgcc_s.so.1(GCC_3.4)(64bit)", + "libgcc_s.so.1(GCC_3.4.2)(64bit)", + "libgcc_s.so.1(GCC_3.4.4)(64bit)", + "libgcc_s.so.1(GCC_4.0.0)(64bit)", + "libgcc_s.so.1(GCC_4.2.0)(64bit)", + "libgcc_s.so.1(GCC_4.3.0)(64bit)", + "libgcc_s.so.1(GCC_4.7.0)(64bit)", + "libgcc_s.so.1(GCC_4.8.0)(64bit)", + "libgcc_s.so.1(GCC_7.0.0)(64bit)", + "libgconf-2.so.4()(64bit)", + "libgdk-3.so.0()(64bit)", + "libgdk_pixbuf-2.0.so.0()(64bit)", + "libgio-2.0.so.0()(64bit)", + "libglib-2.0.so.0()(64bit)", + "libgmodule-2.0.so.0()(64bit)", + "libgobject-2.0.so.0()(64bit)", + "libgtk-3.so.0()(64bit)", + "libm.so.6()(64bit)", + "libm.so.6(GLIBC_2.15)(64bit)", + "libm.so.6(GLIBC_2.18)(64bit)", + "libm.so.6(GLIBC_2.2.5)(64bit)", + "libm.so.6(GLIBC_2.23)(64bit)", + "libm.so.6(GLIBC_2.24)(64bit)", + "libm.so.6(GLIBC_2.25)(64bit)", + "libm.so.6(GLIBC_2.4)(64bit)", + "libnspr4.so()(64bit)", + "libnss3.so()(64bit)", + "libnss3.so(NSS_3.10)(64bit)", + "libnss3.so(NSS_3.10.2)(64bit)", + "libnss3.so(NSS_3.11)(64bit)", + "libnss3.so(NSS_3.11.1)(64bit)", + "libnss3.so(NSS_3.11.2)(64bit)", + "libnss3.so(NSS_3.11.7)(64bit)", + "libnss3.so(NSS_3.11.9)(64bit)", + "libnss3.so(NSS_3.12)(64bit)", + "libnss3.so(NSS_3.12.1)(64bit)", + "libnss3.so(NSS_3.12.10)(64bit)", + "libnss3.so(NSS_3.12.3)(64bit)", + "libnss3.so(NSS_3.12.4)(64bit)", + "libnss3.so(NSS_3.12.5)(64bit)", + "libnss3.so(NSS_3.12.6)(64bit)", + "libnss3.so(NSS_3.12.7)(64bit)", + "libnss3.so(NSS_3.12.9)(64bit)", + "libnss3.so(NSS_3.13)(64bit)", + "libnss3.so(NSS_3.13.2)(64bit)", + "libnss3.so(NSS_3.14)(64bit)", + "libnss3.so(NSS_3.14.1)(64bit)", + "libnss3.so(NSS_3.14.3)(64bit)", + "libnss3.so(NSS_3.15)(64bit)", + "libnss3.so(NSS_3.15.4)(64bit)", + "libnss3.so(NSS_3.16.1)(64bit)", + "libnss3.so(NSS_3.16.2)(64bit)", + "libnss3.so(NSS_3.18)(64bit)", + "libnss3.so(NSS_3.19)(64bit)", + "libnss3.so(NSS_3.19.1)(64bit)", + "libnss3.so(NSS_3.2)(64bit)", + "libnss3.so(NSS_3.2.1)(64bit)", + "libnss3.so(NSS_3.21)(64bit)", + "libnss3.so(NSS_3.22)(64bit)", + "libnss3.so(NSS_3.3)(64bit)", + "libnss3.so(NSS_3.3.1)(64bit)", + "libnss3.so(NSS_3.30)(64bit)", + "libnss3.so(NSS_3.31)(64bit)", + "libnss3.so(NSS_3.4)(64bit)", + "libnss3.so(NSS_3.5)(64bit)", + "libnss3.so(NSS_3.6)(64bit)", + "libnss3.so(NSS_3.7)(64bit)", + "libnss3.so(NSS_3.7.1)(64bit)", + "libnss3.so(NSS_3.8)(64bit)", + "libnss3.so(NSS_3.9)(64bit)", + "libnss3.so(NSS_3.9.2)(64bit)", + "libnss3.so(NSS_3.9.3)(64bit)", + "libnssutil3.so()(64bit)", + "libnssutil3.so(NSSUTIL_3.12)(64bit)", + "libnssutil3.so(NSSUTIL_3.12.3)(64bit)", + "libnssutil3.so(NSSUTIL_3.12.5)(64bit)", + "libnssutil3.so(NSSUTIL_3.12.7)(64bit)", + "libnssutil3.so(NSSUTIL_3.13)(64bit)", + "libnssutil3.so(NSSUTIL_3.14)(64bit)", + "libnssutil3.so(NSSUTIL_3.15)(64bit)", + "libnssutil3.so(NSSUTIL_3.17.1)(64bit)", + "libnssutil3.so(NSSUTIL_3.21)(64bit)", + "libnssutil3.so(NSSUTIL_3.24)(64bit)", + "libnssutil3.so(NSSUTIL_3.25)(64bit)", + "libnssutil3.so(NSSUTIL_3.31)(64bit)", + "libpango-1.0.so.0()(64bit)", + "libpangocairo-1.0.so.0()(64bit)", + "libpthread.so.0()(64bit)", + "libpthread.so.0(GLIBC_2.11)(64bit)", + "libpthread.so.0(GLIBC_2.12)(64bit)", + "libpthread.so.0(GLIBC_2.18)(64bit)", + "libpthread.so.0(GLIBC_2.2.5)(64bit)", + "libpthread.so.0(GLIBC_2.2.6)(64bit)", + "libpthread.so.0(GLIBC_2.3.2)(64bit)", + "libpthread.so.0(GLIBC_2.3.3)(64bit)", + "libpthread.so.0(GLIBC_2.3.4)(64bit)", + "libpthread.so.0(GLIBC_2.4)(64bit)", + "librt.so.1()(64bit)", + "librt.so.1(GLIBC_2.2.5)(64bit)", + "librt.so.1(GLIBC_2.3.3)(64bit)", + "librt.so.1(GLIBC_2.3.4)(64bit)", + "librt.so.1(GLIBC_2.4)(64bit)", + "librt.so.1(GLIBC_2.7)(64bit)", + "libsmime3.so()(64bit)", + "libsmime3.so(NSS_3.10)(64bit)", + "libsmime3.so(NSS_3.12.10)(64bit)", + "libsmime3.so(NSS_3.12.2)(64bit)", + "libsmime3.so(NSS_3.13)(64bit)", + "libsmime3.so(NSS_3.15)(64bit)", + "libsmime3.so(NSS_3.16)(64bit)", + "libsmime3.so(NSS_3.18)(64bit)", + "libsmime3.so(NSS_3.2)(64bit)", + "libsmime3.so(NSS_3.2.1)(64bit)", + "libsmime3.so(NSS_3.3)(64bit)", + "libsmime3.so(NSS_3.4)(64bit)", + "libsmime3.so(NSS_3.4.1)(64bit)", + "libsmime3.so(NSS_3.6)(64bit)", + "libsmime3.so(NSS_3.7)(64bit)", + "libsmime3.so(NSS_3.7.2)(64bit)", + "libsmime3.so(NSS_3.8)(64bit)", + "libsmime3.so(NSS_3.9)(64bit)", + "libsmime3.so(NSS_3.9.3)(64bit)", + "libxcb.so.1()(64bit)" + ], + "openSUSE Leap 42.2": [ + "ld-linux-x86-64.so.2()(64bit)", + "ld-linux-x86-64.so.2(GLIBC_2.2.5)(64bit)", + "ld-linux-x86-64.so.2(GLIBC_2.3)(64bit)", + "ld-linux-x86-64.so.2(GLIBC_2.4)(64bit)", + "libX11-xcb.so.1", + "libX11-xcb.so.1()(64bit)", + "libX11.so.6", + "libX11.so.6()(64bit)", + "libXcomposite.so.1", + "libXcomposite.so.1()(64bit)", + "libXcursor.so.1", + "libXcursor.so.1()(64bit)", + "libXdamage.so.1", + "libXdamage.so.1()(64bit)", + "libXext.so.6", + "libXext.so.6()(64bit)", + "libXfixes.so.3", + "libXfixes.so.3()(64bit)", + "libXi.so.6", + "libXi.so.6()(64bit)", + "libXrandr.so.2", + "libXrandr.so.2()(64bit)", + "libXrender.so.1", + "libXrender.so.1()(64bit)", + "libXss.so.1", + "libXss.so.1()(64bit)", + "libXtst.so.6", + "libXtst.so.6()(64bit)", + "libasound.so.2", + "libasound.so.2()(64bit)", + "libasound.so.2(ALSA_0.9)", + "libasound.so.2(ALSA_0.9)(64bit)", + "libasound.so.2(ALSA_0.9.0)", + "libasound.so.2(ALSA_0.9.0)(64bit)", + "libasound.so.2(ALSA_0.9.0rc4)", + "libasound.so.2(ALSA_0.9.0rc4)(64bit)", + "libasound.so.2(ALSA_0.9.0rc8)", + "libasound.so.2(ALSA_0.9.0rc8)(64bit)", + "libasound.so.2(ALSA_0.9.3)", + "libasound.so.2(ALSA_0.9.3)(64bit)", + "libasound.so.2(ALSA_0.9.5)", + "libasound.so.2(ALSA_0.9.5)(64bit)", + "libasound.so.2(ALSA_0.9.7)", + "libasound.so.2(ALSA_0.9.7)(64bit)", + "libatk-1.0.so.0", + "libatk-1.0.so.0()(64bit)", + "libc.so.6", + "libc.so.6()(64bit)", + "libc.so.6(GCC_3.0)", + "libc.so.6(GLIBC_2.0)", + "libc.so.6(GLIBC_2.1)", + "libc.so.6(GLIBC_2.1.1)", + "libc.so.6(GLIBC_2.1.2)", + "libc.so.6(GLIBC_2.1.3)", + "libc.so.6(GLIBC_2.10)", + "libc.so.6(GLIBC_2.10)(64bit)", + "libc.so.6(GLIBC_2.11)", + "libc.so.6(GLIBC_2.11)(64bit)", + "libc.so.6(GLIBC_2.12)", + "libc.so.6(GLIBC_2.12)(64bit)", + "libc.so.6(GLIBC_2.13)", + "libc.so.6(GLIBC_2.13)(64bit)", + "libc.so.6(GLIBC_2.14)", + "libc.so.6(GLIBC_2.14)(64bit)", + "libc.so.6(GLIBC_2.15)", + "libc.so.6(GLIBC_2.15)(64bit)", + "libc.so.6(GLIBC_2.16)", + "libc.so.6(GLIBC_2.16)(64bit)", + "libc.so.6(GLIBC_2.17)", + "libc.so.6(GLIBC_2.17)(64bit)", + "libc.so.6(GLIBC_2.18)", + "libc.so.6(GLIBC_2.18)(64bit)", + "libc.so.6(GLIBC_2.2)", + "libc.so.6(GLIBC_2.2.1)", + "libc.so.6(GLIBC_2.2.2)", + "libc.so.6(GLIBC_2.2.3)", + "libc.so.6(GLIBC_2.2.4)", + "libc.so.6(GLIBC_2.2.5)(64bit)", + "libc.so.6(GLIBC_2.2.6)", + "libc.so.6(GLIBC_2.2.6)(64bit)", + "libc.so.6(GLIBC_2.22)", + "libc.so.6(GLIBC_2.22)(64bit)", + "libc.so.6(GLIBC_2.3)", + "libc.so.6(GLIBC_2.3)(64bit)", + "libc.so.6(GLIBC_2.3.2)", + "libc.so.6(GLIBC_2.3.2)(64bit)", + "libc.so.6(GLIBC_2.3.3)", + "libc.so.6(GLIBC_2.3.3)(64bit)", + "libc.so.6(GLIBC_2.3.4)", + "libc.so.6(GLIBC_2.3.4)(64bit)", + "libc.so.6(GLIBC_2.4)", + "libc.so.6(GLIBC_2.4)(64bit)", + "libc.so.6(GLIBC_2.5)", + "libc.so.6(GLIBC_2.5)(64bit)", + "libc.so.6(GLIBC_2.6)", + "libc.so.6(GLIBC_2.6)(64bit)", + "libc.so.6(GLIBC_2.7)", + "libc.so.6(GLIBC_2.7)(64bit)", + "libc.so.6(GLIBC_2.8)", + "libc.so.6(GLIBC_2.8)(64bit)", + "libc.so.6(GLIBC_2.9)", + "libc.so.6(GLIBC_2.9)(64bit)", + "libc.so.6(GLIBC_PRIVATE)", + "libcairo.so()(64bit)", + "libcairo.so.2", + "libcairo.so.2()(64bit)", + "libcups.so.2", + "libcups.so.2()(64bit)", + "libdbus-1.so.3", + "libdbus-1.so.3()(64bit)", + "libdl.so.2", + "libdl.so.2()(64bit)", + "libdl.so.2(GLIBC_2.0)", + "libdl.so.2(GLIBC_2.1)", + "libdl.so.2(GLIBC_2.2.5)(64bit)", + "libdl.so.2(GLIBC_2.3.3)", + "libdl.so.2(GLIBC_2.3.3)(64bit)", + "libdl.so.2(GLIBC_2.3.4)", + "libdl.so.2(GLIBC_2.3.4)(64bit)", + "libdl.so.2(GLIBC_PRIVATE)", + "libexpat.so.0", + "libexpat.so.0()(64bit)", + "libexpat.so.1", + "libexpat.so.1()(64bit)", + "libfontconfig.so.1", + "libfontconfig.so.1()(64bit)", + "libgcc_s.so.1", + "libgcc_s.so.1()(64bit)", + "libgcc_s.so.1(GCC_3.0)", + "libgcc_s.so.1(GCC_3.0)(64bit)", + "libgcc_s.so.1(GCC_3.3)", + "libgcc_s.so.1(GCC_3.3)(64bit)", + "libgcc_s.so.1(GCC_3.3.1)", + "libgcc_s.so.1(GCC_3.3.1)(64bit)", + "libgcc_s.so.1(GCC_3.4)", + "libgcc_s.so.1(GCC_3.4)(64bit)", + "libgcc_s.so.1(GCC_3.4.2)", + "libgcc_s.so.1(GCC_3.4.2)(64bit)", + "libgcc_s.so.1(GCC_3.4.4)(64bit)", + "libgcc_s.so.1(GCC_4.0.0)", + "libgcc_s.so.1(GCC_4.0.0)(64bit)", + "libgcc_s.so.1(GCC_4.2.0)", + "libgcc_s.so.1(GCC_4.2.0)(64bit)", + "libgcc_s.so.1(GCC_4.3.0)", + "libgcc_s.so.1(GCC_4.3.0)(64bit)", + "libgcc_s.so.1(GCC_4.4.0)", + "libgcc_s.so.1(GCC_4.5.0)", + "libgcc_s.so.1(GCC_4.7.0)", + "libgcc_s.so.1(GCC_4.7.0)(64bit)", + "libgcc_s.so.1(GCC_4.8.0)", + "libgcc_s.so.1(GCC_4.8.0)(64bit)", + "libgcc_s.so.1(GLIBC_2.0)", + "libgconf-2.so.4", + "libgconf-2.so.4()(64bit)", + "libgdk-3.so.0", + "libgdk-3.so.0()(64bit)", + "libgdk_pixbuf-2.0.so.0", + "libgdk_pixbuf-2.0.so.0()(64bit)", + "libgio-2.0.so.0", + "libgio-2.0.so.0()(64bit)", + "libglib-2.0.so.0", + "libglib-2.0.so.0()(64bit)", + "libgmodule-2.0.so.0", + "libgmodule-2.0.so.0()(64bit)", + "libgobject-2.0.so.0", + "libgobject-2.0.so.0()(64bit)", + "libgtk-3.so.0", + "libgtk-3.so.0()(64bit)", + "libm.so.6", + "libm.so.6()(64bit)", + "libm.so.6(GLIBC_2.0)", + "libm.so.6(GLIBC_2.1)", + "libm.so.6(GLIBC_2.15)", + "libm.so.6(GLIBC_2.15)(64bit)", + "libm.so.6(GLIBC_2.18)", + "libm.so.6(GLIBC_2.18)(64bit)", + "libm.so.6(GLIBC_2.2)", + "libm.so.6(GLIBC_2.2.5)(64bit)", + "libm.so.6(GLIBC_2.4)", + "libm.so.6(GLIBC_2.4)(64bit)", + "libnspr4.so", + "libnspr4.so()(64bit)", + "libnss3.so", + "libnss3.so()(64bit)", + "libnss3.so(NSS_3.10)", + "libnss3.so(NSS_3.10)(64bit)", + "libnss3.so(NSS_3.10.2)", + "libnss3.so(NSS_3.10.2)(64bit)", + "libnss3.so(NSS_3.11)", + "libnss3.so(NSS_3.11)(64bit)", + "libnss3.so(NSS_3.11.1)", + "libnss3.so(NSS_3.11.1)(64bit)", + "libnss3.so(NSS_3.11.2)", + "libnss3.so(NSS_3.11.2)(64bit)", + "libnss3.so(NSS_3.11.7)", + "libnss3.so(NSS_3.11.7)(64bit)", + "libnss3.so(NSS_3.11.9)", + "libnss3.so(NSS_3.11.9)(64bit)", + "libnss3.so(NSS_3.12)", + "libnss3.so(NSS_3.12)(64bit)", + "libnss3.so(NSS_3.12.1)", + "libnss3.so(NSS_3.12.1)(64bit)", + "libnss3.so(NSS_3.12.10)", + "libnss3.so(NSS_3.12.10)(64bit)", + "libnss3.so(NSS_3.12.3)", + "libnss3.so(NSS_3.12.3)(64bit)", + "libnss3.so(NSS_3.12.4)", + "libnss3.so(NSS_3.12.4)(64bit)", + "libnss3.so(NSS_3.12.5)", + "libnss3.so(NSS_3.12.5)(64bit)", + "libnss3.so(NSS_3.12.6)", + "libnss3.so(NSS_3.12.6)(64bit)", + "libnss3.so(NSS_3.12.7)", + "libnss3.so(NSS_3.12.7)(64bit)", + "libnss3.so(NSS_3.12.9)", + "libnss3.so(NSS_3.12.9)(64bit)", + "libnss3.so(NSS_3.13)", + "libnss3.so(NSS_3.13)(64bit)", + "libnss3.so(NSS_3.13.2)", + "libnss3.so(NSS_3.13.2)(64bit)", + "libnss3.so(NSS_3.14)", + "libnss3.so(NSS_3.14)(64bit)", + "libnss3.so(NSS_3.14.1)", + "libnss3.so(NSS_3.14.1)(64bit)", + "libnss3.so(NSS_3.14.3)", + "libnss3.so(NSS_3.14.3)(64bit)", + "libnss3.so(NSS_3.15)", + "libnss3.so(NSS_3.15)(64bit)", + "libnss3.so(NSS_3.15.4)", + "libnss3.so(NSS_3.15.4)(64bit)", + "libnss3.so(NSS_3.16.1)", + "libnss3.so(NSS_3.16.1)(64bit)", + "libnss3.so(NSS_3.16.2)", + "libnss3.so(NSS_3.16.2)(64bit)", + "libnss3.so(NSS_3.18)", + "libnss3.so(NSS_3.18)(64bit)", + "libnss3.so(NSS_3.19)", + "libnss3.so(NSS_3.19)(64bit)", + "libnss3.so(NSS_3.19.1)", + "libnss3.so(NSS_3.19.1)(64bit)", + "libnss3.so(NSS_3.2)", + "libnss3.so(NSS_3.2)(64bit)", + "libnss3.so(NSS_3.2.1)", + "libnss3.so(NSS_3.2.1)(64bit)", + "libnss3.so(NSS_3.21)", + "libnss3.so(NSS_3.21)(64bit)", + "libnss3.so(NSS_3.22)", + "libnss3.so(NSS_3.22)(64bit)", + "libnss3.so(NSS_3.3)", + "libnss3.so(NSS_3.3)(64bit)", + "libnss3.so(NSS_3.3.1)", + "libnss3.so(NSS_3.3.1)(64bit)", + "libnss3.so(NSS_3.4)", + "libnss3.so(NSS_3.4)(64bit)", + "libnss3.so(NSS_3.5)", + "libnss3.so(NSS_3.5)(64bit)", + "libnss3.so(NSS_3.6)", + "libnss3.so(NSS_3.6)(64bit)", + "libnss3.so(NSS_3.7)", + "libnss3.so(NSS_3.7)(64bit)", + "libnss3.so(NSS_3.7.1)", + "libnss3.so(NSS_3.7.1)(64bit)", + "libnss3.so(NSS_3.8)", + "libnss3.so(NSS_3.8)(64bit)", + "libnss3.so(NSS_3.9)", + "libnss3.so(NSS_3.9)(64bit)", + "libnss3.so(NSS_3.9.2)", + "libnss3.so(NSS_3.9.2)(64bit)", + "libnss3.so(NSS_3.9.3)", + "libnss3.so(NSS_3.9.3)(64bit)", + "libnssutil3.so", + "libnssutil3.so()(64bit)", + "libnssutil3.so(NSSUTIL_3.12)", + "libnssutil3.so(NSSUTIL_3.12)(64bit)", + "libnssutil3.so(NSSUTIL_3.12.3)", + "libnssutil3.so(NSSUTIL_3.12.3)(64bit)", + "libnssutil3.so(NSSUTIL_3.12.5)", + "libnssutil3.so(NSSUTIL_3.12.5)(64bit)", + "libnssutil3.so(NSSUTIL_3.12.7)", + "libnssutil3.so(NSSUTIL_3.12.7)(64bit)", + "libnssutil3.so(NSSUTIL_3.13)", + "libnssutil3.so(NSSUTIL_3.13)(64bit)", + "libnssutil3.so(NSSUTIL_3.14)", + "libnssutil3.so(NSSUTIL_3.14)(64bit)", + "libnssutil3.so(NSSUTIL_3.15)", + "libnssutil3.so(NSSUTIL_3.15)(64bit)", + "libnssutil3.so(NSSUTIL_3.17.1)", + "libnssutil3.so(NSSUTIL_3.17.1)(64bit)", + "libnssutil3.so(NSSUTIL_3.21)", + "libnssutil3.so(NSSUTIL_3.21)(64bit)", + "libnssutil3.so(NSSUTIL_3.24)", + "libnssutil3.so(NSSUTIL_3.24)(64bit)", + "libpango-1.0.so.0", + "libpango-1.0.so.0()(64bit)", + "libpangocairo-1.0.so.0", + "libpangocairo-1.0.so.0()(64bit)", + "libpthread.so.0", + "libpthread.so.0()(64bit)", + "libpthread.so.0(GLIBC_2.0)", + "libpthread.so.0(GLIBC_2.1)", + "libpthread.so.0(GLIBC_2.1.1)", + "libpthread.so.0(GLIBC_2.1.2)", + "libpthread.so.0(GLIBC_2.11)", + "libpthread.so.0(GLIBC_2.11)(64bit)", + "libpthread.so.0(GLIBC_2.12)", + "libpthread.so.0(GLIBC_2.12)(64bit)", + "libpthread.so.0(GLIBC_2.18)", + "libpthread.so.0(GLIBC_2.18)(64bit)", + "libpthread.so.0(GLIBC_2.2)", + "libpthread.so.0(GLIBC_2.2.3)", + "libpthread.so.0(GLIBC_2.2.5)(64bit)", + "libpthread.so.0(GLIBC_2.2.6)", + "libpthread.so.0(GLIBC_2.2.6)(64bit)", + "libpthread.so.0(GLIBC_2.3.2)", + "libpthread.so.0(GLIBC_2.3.2)(64bit)", + "libpthread.so.0(GLIBC_2.3.3)", + "libpthread.so.0(GLIBC_2.3.3)(64bit)", + "libpthread.so.0(GLIBC_2.3.4)", + "libpthread.so.0(GLIBC_2.3.4)(64bit)", + "libpthread.so.0(GLIBC_2.4)", + "libpthread.so.0(GLIBC_2.4)(64bit)", + "libpthread.so.0(GLIBC_PRIVATE)", + "librt.so.1", + "librt.so.1()(64bit)", + "librt.so.1(GLIBC_2.1)", + "librt.so.1(GLIBC_2.2)", + "librt.so.1(GLIBC_2.2.5)(64bit)", + "librt.so.1(GLIBC_2.3.3)(64bit)", + "librt.so.1(GLIBC_2.3.4)", + "librt.so.1(GLIBC_2.3.4)(64bit)", + "librt.so.1(GLIBC_2.4)", + "librt.so.1(GLIBC_2.4)(64bit)", + "librt.so.1(GLIBC_2.7)", + "librt.so.1(GLIBC_2.7)(64bit)", + "libsmime3.so", + "libsmime3.so()(64bit)", + "libsmime3.so(NSS_3.10)", + "libsmime3.so(NSS_3.10)(64bit)", + "libsmime3.so(NSS_3.12.10)", + "libsmime3.so(NSS_3.12.10)(64bit)", + "libsmime3.so(NSS_3.12.2)", + "libsmime3.so(NSS_3.12.2)(64bit)", + "libsmime3.so(NSS_3.13)", + "libsmime3.so(NSS_3.13)(64bit)", + "libsmime3.so(NSS_3.15)", + "libsmime3.so(NSS_3.15)(64bit)", + "libsmime3.so(NSS_3.16)", + "libsmime3.so(NSS_3.16)(64bit)", + "libsmime3.so(NSS_3.18)", + "libsmime3.so(NSS_3.18)(64bit)", + "libsmime3.so(NSS_3.2)", + "libsmime3.so(NSS_3.2)(64bit)", + "libsmime3.so(NSS_3.2.1)", + "libsmime3.so(NSS_3.2.1)(64bit)", + "libsmime3.so(NSS_3.3)", + "libsmime3.so(NSS_3.3)(64bit)", + "libsmime3.so(NSS_3.4)", + "libsmime3.so(NSS_3.4)(64bit)", + "libsmime3.so(NSS_3.4.1)", + "libsmime3.so(NSS_3.4.1)(64bit)", + "libsmime3.so(NSS_3.6)", + "libsmime3.so(NSS_3.6)(64bit)", + "libsmime3.so(NSS_3.7)", + "libsmime3.so(NSS_3.7)(64bit)", + "libsmime3.so(NSS_3.7.2)", + "libsmime3.so(NSS_3.7.2)(64bit)", + "libsmime3.so(NSS_3.8)", + "libsmime3.so(NSS_3.8)(64bit)", + "libsmime3.so(NSS_3.9)", + "libsmime3.so(NSS_3.9)(64bit)", + "libsmime3.so(NSS_3.9.3)", + "libsmime3.so(NSS_3.9.3)(64bit)", + "libxcb.so.1", + "libxcb.so.1()(64bit)" + ], + "openSUSE Leap 42.3": [ + "ld-linux-x86-64.so.2()(64bit)", + "ld-linux-x86-64.so.2(GLIBC_2.2.5)(64bit)", + "ld-linux-x86-64.so.2(GLIBC_2.3)(64bit)", + "ld-linux-x86-64.so.2(GLIBC_2.4)(64bit)", + "libX11-xcb.so.1", + "libX11-xcb.so.1()(64bit)", + "libX11.so.6", + "libX11.so.6()(64bit)", + "libXcomposite.so.1", + "libXcomposite.so.1()(64bit)", + "libXcursor.so.1", + "libXcursor.so.1()(64bit)", + "libXdamage.so.1", + "libXdamage.so.1()(64bit)", + "libXext.so.6", + "libXext.so.6()(64bit)", + "libXfixes.so.3", + "libXfixes.so.3()(64bit)", + "libXi.so.6", + "libXi.so.6()(64bit)", + "libXrandr.so.2", + "libXrandr.so.2()(64bit)", + "libXrender.so.1", + "libXrender.so.1()(64bit)", + "libXss.so.1", + "libXss.so.1()(64bit)", + "libXtst.so.6", + "libXtst.so.6()(64bit)", + "libasound.so.2", + "libasound.so.2()(64bit)", + "libasound.so.2(ALSA_0.9)", + "libasound.so.2(ALSA_0.9)(64bit)", + "libasound.so.2(ALSA_0.9.0)", + "libasound.so.2(ALSA_0.9.0)(64bit)", + "libasound.so.2(ALSA_0.9.0rc4)", + "libasound.so.2(ALSA_0.9.0rc4)(64bit)", + "libasound.so.2(ALSA_0.9.0rc8)", + "libasound.so.2(ALSA_0.9.0rc8)(64bit)", + "libasound.so.2(ALSA_0.9.3)", + "libasound.so.2(ALSA_0.9.3)(64bit)", + "libasound.so.2(ALSA_0.9.5)", + "libasound.so.2(ALSA_0.9.5)(64bit)", + "libasound.so.2(ALSA_0.9.7)", + "libasound.so.2(ALSA_0.9.7)(64bit)", + "libatk-1.0.so.0", + "libatk-1.0.so.0()(64bit)", + "libc.so.6", + "libc.so.6()(64bit)", + "libc.so.6(GCC_3.0)", + "libc.so.6(GLIBC_2.0)", + "libc.so.6(GLIBC_2.1)", + "libc.so.6(GLIBC_2.1.1)", + "libc.so.6(GLIBC_2.1.2)", + "libc.so.6(GLIBC_2.1.3)", + "libc.so.6(GLIBC_2.10)", + "libc.so.6(GLIBC_2.10)(64bit)", + "libc.so.6(GLIBC_2.11)", + "libc.so.6(GLIBC_2.11)(64bit)", + "libc.so.6(GLIBC_2.12)", + "libc.so.6(GLIBC_2.12)(64bit)", + "libc.so.6(GLIBC_2.13)", + "libc.so.6(GLIBC_2.13)(64bit)", + "libc.so.6(GLIBC_2.14)", + "libc.so.6(GLIBC_2.14)(64bit)", + "libc.so.6(GLIBC_2.15)", + "libc.so.6(GLIBC_2.15)(64bit)", + "libc.so.6(GLIBC_2.16)", + "libc.so.6(GLIBC_2.16)(64bit)", + "libc.so.6(GLIBC_2.17)", + "libc.so.6(GLIBC_2.17)(64bit)", + "libc.so.6(GLIBC_2.18)", + "libc.so.6(GLIBC_2.18)(64bit)", + "libc.so.6(GLIBC_2.2)", + "libc.so.6(GLIBC_2.2.1)", + "libc.so.6(GLIBC_2.2.2)", + "libc.so.6(GLIBC_2.2.3)", + "libc.so.6(GLIBC_2.2.4)", + "libc.so.6(GLIBC_2.2.5)(64bit)", + "libc.so.6(GLIBC_2.2.6)", + "libc.so.6(GLIBC_2.2.6)(64bit)", + "libc.so.6(GLIBC_2.22)", + "libc.so.6(GLIBC_2.22)(64bit)", + "libc.so.6(GLIBC_2.3)", + "libc.so.6(GLIBC_2.3)(64bit)", + "libc.so.6(GLIBC_2.3.2)", + "libc.so.6(GLIBC_2.3.2)(64bit)", + "libc.so.6(GLIBC_2.3.3)", + "libc.so.6(GLIBC_2.3.3)(64bit)", + "libc.so.6(GLIBC_2.3.4)", + "libc.so.6(GLIBC_2.3.4)(64bit)", + "libc.so.6(GLIBC_2.4)", + "libc.so.6(GLIBC_2.4)(64bit)", + "libc.so.6(GLIBC_2.5)", + "libc.so.6(GLIBC_2.5)(64bit)", + "libc.so.6(GLIBC_2.6)", + "libc.so.6(GLIBC_2.6)(64bit)", + "libc.so.6(GLIBC_2.7)", + "libc.so.6(GLIBC_2.7)(64bit)", + "libc.so.6(GLIBC_2.8)", + "libc.so.6(GLIBC_2.8)(64bit)", + "libc.so.6(GLIBC_2.9)", + "libc.so.6(GLIBC_2.9)(64bit)", + "libc.so.6(GLIBC_PRIVATE)", + "libcairo.so()(64bit)", + "libcairo.so.2", + "libcairo.so.2()(64bit)", + "libcups.so.2", + "libcups.so.2()(64bit)", + "libdbus-1.so.3", + "libdbus-1.so.3()(64bit)", + "libdl.so.2", + "libdl.so.2()(64bit)", + "libdl.so.2(GLIBC_2.0)", + "libdl.so.2(GLIBC_2.1)", + "libdl.so.2(GLIBC_2.2.5)(64bit)", + "libdl.so.2(GLIBC_2.3.3)", + "libdl.so.2(GLIBC_2.3.3)(64bit)", + "libdl.so.2(GLIBC_2.3.4)", + "libdl.so.2(GLIBC_2.3.4)(64bit)", + "libdl.so.2(GLIBC_PRIVATE)", + "libexpat.so.0", + "libexpat.so.0()(64bit)", + "libexpat.so.1", + "libexpat.so.1()(64bit)", + "libfontconfig.so.1", + "libfontconfig.so.1()(64bit)", + "libgcc_s.so.1", + "libgcc_s.so.1()(64bit)", + "libgcc_s.so.1(GCC_3.0)", + "libgcc_s.so.1(GCC_3.0)(64bit)", + "libgcc_s.so.1(GCC_3.3)", + "libgcc_s.so.1(GCC_3.3)(64bit)", + "libgcc_s.so.1(GCC_3.3.1)", + "libgcc_s.so.1(GCC_3.3.1)(64bit)", + "libgcc_s.so.1(GCC_3.4)", + "libgcc_s.so.1(GCC_3.4)(64bit)", + "libgcc_s.so.1(GCC_3.4.2)", + "libgcc_s.so.1(GCC_3.4.2)(64bit)", + "libgcc_s.so.1(GCC_3.4.4)(64bit)", + "libgcc_s.so.1(GCC_4.0.0)", + "libgcc_s.so.1(GCC_4.0.0)(64bit)", + "libgcc_s.so.1(GCC_4.2.0)", + "libgcc_s.so.1(GCC_4.2.0)(64bit)", + "libgcc_s.so.1(GCC_4.3.0)", + "libgcc_s.so.1(GCC_4.3.0)(64bit)", + "libgcc_s.so.1(GCC_4.4.0)", + "libgcc_s.so.1(GCC_4.5.0)", + "libgcc_s.so.1(GCC_4.7.0)", + "libgcc_s.so.1(GCC_4.7.0)(64bit)", + "libgcc_s.so.1(GCC_4.8.0)", + "libgcc_s.so.1(GCC_4.8.0)(64bit)", + "libgcc_s.so.1(GCC_7.0.0)", + "libgcc_s.so.1(GCC_7.0.0)(64bit)", + "libgcc_s.so.1(GLIBC_2.0)", + "libgconf-2.so.4", + "libgconf-2.so.4()(64bit)", + "libgdk-3.so.0", + "libgdk-3.so.0()(64bit)", + "libgdk_pixbuf-2.0.so.0", + "libgdk_pixbuf-2.0.so.0()(64bit)", + "libgio-2.0.so.0", + "libgio-2.0.so.0()(64bit)", + "libglib-2.0.so.0", + "libglib-2.0.so.0()(64bit)", + "libgmodule-2.0.so.0", + "libgmodule-2.0.so.0()(64bit)", + "libgobject-2.0.so.0", + "libgobject-2.0.so.0()(64bit)", + "libgtk-3.so.0", + "libgtk-3.so.0()(64bit)", + "libm.so.6", + "libm.so.6()(64bit)", + "libm.so.6(GLIBC_2.0)", + "libm.so.6(GLIBC_2.1)", + "libm.so.6(GLIBC_2.15)", + "libm.so.6(GLIBC_2.15)(64bit)", + "libm.so.6(GLIBC_2.18)", + "libm.so.6(GLIBC_2.18)(64bit)", + "libm.so.6(GLIBC_2.2)", + "libm.so.6(GLIBC_2.2.5)(64bit)", + "libm.so.6(GLIBC_2.4)", + "libm.so.6(GLIBC_2.4)(64bit)", + "libnspr4.so", + "libnspr4.so()(64bit)", + "libnss3.so", + "libnss3.so()(64bit)", + "libnss3.so(NSS_3.10)", + "libnss3.so(NSS_3.10)(64bit)", + "libnss3.so(NSS_3.10.2)", + "libnss3.so(NSS_3.10.2)(64bit)", + "libnss3.so(NSS_3.11)", + "libnss3.so(NSS_3.11)(64bit)", + "libnss3.so(NSS_3.11.1)", + "libnss3.so(NSS_3.11.1)(64bit)", + "libnss3.so(NSS_3.11.2)", + "libnss3.so(NSS_3.11.2)(64bit)", + "libnss3.so(NSS_3.11.7)", + "libnss3.so(NSS_3.11.7)(64bit)", + "libnss3.so(NSS_3.11.9)", + "libnss3.so(NSS_3.11.9)(64bit)", + "libnss3.so(NSS_3.12)", + "libnss3.so(NSS_3.12)(64bit)", + "libnss3.so(NSS_3.12.1)", + "libnss3.so(NSS_3.12.1)(64bit)", + "libnss3.so(NSS_3.12.10)", + "libnss3.so(NSS_3.12.10)(64bit)", + "libnss3.so(NSS_3.12.3)", + "libnss3.so(NSS_3.12.3)(64bit)", + "libnss3.so(NSS_3.12.4)", + "libnss3.so(NSS_3.12.4)(64bit)", + "libnss3.so(NSS_3.12.5)", + "libnss3.so(NSS_3.12.5)(64bit)", + "libnss3.so(NSS_3.12.6)", + "libnss3.so(NSS_3.12.6)(64bit)", + "libnss3.so(NSS_3.12.7)", + "libnss3.so(NSS_3.12.7)(64bit)", + "libnss3.so(NSS_3.12.9)", + "libnss3.so(NSS_3.12.9)(64bit)", + "libnss3.so(NSS_3.13)", + "libnss3.so(NSS_3.13)(64bit)", + "libnss3.so(NSS_3.13.2)", + "libnss3.so(NSS_3.13.2)(64bit)", + "libnss3.so(NSS_3.14)", + "libnss3.so(NSS_3.14)(64bit)", + "libnss3.so(NSS_3.14.1)", + "libnss3.so(NSS_3.14.1)(64bit)", + "libnss3.so(NSS_3.14.3)", + "libnss3.so(NSS_3.14.3)(64bit)", + "libnss3.so(NSS_3.15)", + "libnss3.so(NSS_3.15)(64bit)", + "libnss3.so(NSS_3.15.4)", + "libnss3.so(NSS_3.15.4)(64bit)", + "libnss3.so(NSS_3.16.1)", + "libnss3.so(NSS_3.16.1)(64bit)", + "libnss3.so(NSS_3.16.2)", + "libnss3.so(NSS_3.16.2)(64bit)", + "libnss3.so(NSS_3.18)", + "libnss3.so(NSS_3.18)(64bit)", + "libnss3.so(NSS_3.19)", + "libnss3.so(NSS_3.19)(64bit)", + "libnss3.so(NSS_3.19.1)", + "libnss3.so(NSS_3.19.1)(64bit)", + "libnss3.so(NSS_3.2)", + "libnss3.so(NSS_3.2)(64bit)", + "libnss3.so(NSS_3.2.1)", + "libnss3.so(NSS_3.2.1)(64bit)", + "libnss3.so(NSS_3.21)", + "libnss3.so(NSS_3.21)(64bit)", + "libnss3.so(NSS_3.22)", + "libnss3.so(NSS_3.22)(64bit)", + "libnss3.so(NSS_3.3)", + "libnss3.so(NSS_3.3)(64bit)", + "libnss3.so(NSS_3.3.1)", + "libnss3.so(NSS_3.3.1)(64bit)", + "libnss3.so(NSS_3.4)", + "libnss3.so(NSS_3.4)(64bit)", + "libnss3.so(NSS_3.5)", + "libnss3.so(NSS_3.5)(64bit)", + "libnss3.so(NSS_3.6)", + "libnss3.so(NSS_3.6)(64bit)", + "libnss3.so(NSS_3.7)", + "libnss3.so(NSS_3.7)(64bit)", + "libnss3.so(NSS_3.7.1)", + "libnss3.so(NSS_3.7.1)(64bit)", + "libnss3.so(NSS_3.8)", + "libnss3.so(NSS_3.8)(64bit)", + "libnss3.so(NSS_3.9)", + "libnss3.so(NSS_3.9)(64bit)", + "libnss3.so(NSS_3.9.2)", + "libnss3.so(NSS_3.9.2)(64bit)", + "libnss3.so(NSS_3.9.3)", + "libnss3.so(NSS_3.9.3)(64bit)", + "libnssutil3.so", + "libnssutil3.so()(64bit)", + "libnssutil3.so(NSSUTIL_3.12)", + "libnssutil3.so(NSSUTIL_3.12)(64bit)", + "libnssutil3.so(NSSUTIL_3.12.3)", + "libnssutil3.so(NSSUTIL_3.12.3)(64bit)", + "libnssutil3.so(NSSUTIL_3.12.5)", + "libnssutil3.so(NSSUTIL_3.12.5)(64bit)", + "libnssutil3.so(NSSUTIL_3.12.7)", + "libnssutil3.so(NSSUTIL_3.12.7)(64bit)", + "libnssutil3.so(NSSUTIL_3.13)", + "libnssutil3.so(NSSUTIL_3.13)(64bit)", + "libnssutil3.so(NSSUTIL_3.14)", + "libnssutil3.so(NSSUTIL_3.14)(64bit)", + "libnssutil3.so(NSSUTIL_3.15)", + "libnssutil3.so(NSSUTIL_3.15)(64bit)", + "libnssutil3.so(NSSUTIL_3.17.1)", + "libnssutil3.so(NSSUTIL_3.17.1)(64bit)", + "libnssutil3.so(NSSUTIL_3.21)", + "libnssutil3.so(NSSUTIL_3.21)(64bit)", + "libnssutil3.so(NSSUTIL_3.24)", + "libnssutil3.so(NSSUTIL_3.24)(64bit)", + "libpango-1.0.so.0", + "libpango-1.0.so.0()(64bit)", + "libpangocairo-1.0.so.0", + "libpangocairo-1.0.so.0()(64bit)", + "libpthread.so.0", + "libpthread.so.0()(64bit)", + "libpthread.so.0(GLIBC_2.0)", + "libpthread.so.0(GLIBC_2.1)", + "libpthread.so.0(GLIBC_2.1.1)", + "libpthread.so.0(GLIBC_2.1.2)", + "libpthread.so.0(GLIBC_2.11)", + "libpthread.so.0(GLIBC_2.11)(64bit)", + "libpthread.so.0(GLIBC_2.12)", + "libpthread.so.0(GLIBC_2.12)(64bit)", + "libpthread.so.0(GLIBC_2.18)", + "libpthread.so.0(GLIBC_2.18)(64bit)", + "libpthread.so.0(GLIBC_2.2)", + "libpthread.so.0(GLIBC_2.2.3)", + "libpthread.so.0(GLIBC_2.2.5)(64bit)", + "libpthread.so.0(GLIBC_2.2.6)", + "libpthread.so.0(GLIBC_2.2.6)(64bit)", + "libpthread.so.0(GLIBC_2.3.2)", + "libpthread.so.0(GLIBC_2.3.2)(64bit)", + "libpthread.so.0(GLIBC_2.3.3)", + "libpthread.so.0(GLIBC_2.3.3)(64bit)", + "libpthread.so.0(GLIBC_2.3.4)", + "libpthread.so.0(GLIBC_2.3.4)(64bit)", + "libpthread.so.0(GLIBC_2.4)", + "libpthread.so.0(GLIBC_2.4)(64bit)", + "libpthread.so.0(GLIBC_PRIVATE)", + "librt.so.1", + "librt.so.1()(64bit)", + "librt.so.1(GLIBC_2.1)", + "librt.so.1(GLIBC_2.2)", + "librt.so.1(GLIBC_2.2.5)(64bit)", + "librt.so.1(GLIBC_2.3.3)(64bit)", + "librt.so.1(GLIBC_2.3.4)", + "librt.so.1(GLIBC_2.3.4)(64bit)", + "librt.so.1(GLIBC_2.4)", + "librt.so.1(GLIBC_2.4)(64bit)", + "librt.so.1(GLIBC_2.7)", + "librt.so.1(GLIBC_2.7)(64bit)", + "libsmime3.so", + "libsmime3.so()(64bit)", + "libsmime3.so(NSS_3.10)", + "libsmime3.so(NSS_3.10)(64bit)", + "libsmime3.so(NSS_3.12.10)", + "libsmime3.so(NSS_3.12.10)(64bit)", + "libsmime3.so(NSS_3.12.2)", + "libsmime3.so(NSS_3.12.2)(64bit)", + "libsmime3.so(NSS_3.13)", + "libsmime3.so(NSS_3.13)(64bit)", + "libsmime3.so(NSS_3.15)", + "libsmime3.so(NSS_3.15)(64bit)", + "libsmime3.so(NSS_3.16)", + "libsmime3.so(NSS_3.16)(64bit)", + "libsmime3.so(NSS_3.18)", + "libsmime3.so(NSS_3.18)(64bit)", + "libsmime3.so(NSS_3.2)", + "libsmime3.so(NSS_3.2)(64bit)", + "libsmime3.so(NSS_3.2.1)", + "libsmime3.so(NSS_3.2.1)(64bit)", + "libsmime3.so(NSS_3.3)", + "libsmime3.so(NSS_3.3)(64bit)", + "libsmime3.so(NSS_3.4)", + "libsmime3.so(NSS_3.4)(64bit)", + "libsmime3.so(NSS_3.4.1)", + "libsmime3.so(NSS_3.4.1)(64bit)", + "libsmime3.so(NSS_3.6)", + "libsmime3.so(NSS_3.6)(64bit)", + "libsmime3.so(NSS_3.7)", + "libsmime3.so(NSS_3.7)(64bit)", + "libsmime3.so(NSS_3.7.2)", + "libsmime3.so(NSS_3.7.2)(64bit)", + "libsmime3.so(NSS_3.8)", + "libsmime3.so(NSS_3.8)(64bit)", + "libsmime3.so(NSS_3.9)", + "libsmime3.so(NSS_3.9)(64bit)", + "libsmime3.so(NSS_3.9.3)", + "libsmime3.so(NSS_3.9.3)(64bit)", + "libxcb.so.1", + "libxcb.so.1()(64bit)" + ] +}
diff --git a/chrome/installer/linux/rpm/update-package-provides.py b/chrome/installer/linux/rpm/update-package-provides.py new file mode 100755 index 0000000..4099f4e1d --- /dev/null +++ b/chrome/installer/linux/rpm/update-package-provides.py
@@ -0,0 +1,133 @@ +#!/usr/bin/env python +# 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 binascii +import cStringIO +import gzip +import hashlib +import json +import os +import urllib2 +import xml.etree.ElementTree + +PACKAGE_FILTER = [ + "ld-linux-x86-64.so", + "libX11-xcb.so", + "libX11.so", + "libXcomposite.so", + "libXcursor.so", + "libXdamage.so", + "libXext.so", + "libXfixes.so", + "libXi.so", + "libXrandr.so", + "libXrender.so", + "libXss.so", + "libXtst.so", + "libasound.so", + "libatk-1.0.so", + "libc.so", + "libcairo.so", + "libcups.so", + "libdbus-1.so", + "libdl.so", + "libexpat.so", + "libfontconfig.so", + "libgcc_s.so", + "libgconf-2.so", + "libgdk-3.so", + "libgdk_pixbuf-2.0.so", + "libgio-2.0.so", + "libglib-2.0.so", + "libgmodule-2.0.so", + "libgobject-2.0.so", + "libgtk-3.so", + "libm.so", + "libnspr4.so", + "libnss3.so", + "libnssutil3.so", + "libpango-1.0.so", + "libpangocairo-1.0.so", + "libpthread.so", + "librt.so", + "libsmime3.so", + "libxcb.so", +] + +SUPPORTED_FEDORA_RELEASES = ['25', '26'] +SUPPORTED_OPENSUSE_LEAP_RELEASES = ['42.2', '42.3'] + +COMMON_NS = "http://linux.duke.edu/metadata/common" +RPM_NS = "http://linux.duke.edu/metadata/rpm" +REPO_NS = "http://linux.duke.edu/metadata/repo" + +rpm_sources = {} +for version in SUPPORTED_FEDORA_RELEASES: + rpm_sources['Fedora ' + version] = [ + "https://download.fedoraproject.org/pub/fedora/linux/releases/%s/Everything/x86_64/os/" % version, + # 'updates' must appear after 'releases' since its entries + # overwrite the originals. + "https://download.fedoraproject.org/pub/fedora/linux/updates/%s/x86_64/" % version, + ] +for version in SUPPORTED_OPENSUSE_LEAP_RELEASES: + rpm_sources['openSUSE Leap ' + version] = [ + "https://download.opensuse.org/distribution/leap/%s/repo/oss/suse/" % version, + # 'update' must appear after 'distribution' since its entries + # overwrite the originals. + "https://download.opensuse.org/update/leap/%s/oss/" % version, + ] + +provides = {} +for distro in rpm_sources: + distro_provides = {} + for source in rpm_sources[distro]: + # |source| may redirect to a real download mirror. However, these + # mirrors may be out-of-sync with each other. Follow the redirect + # to ensure the file-references from the metadata file are valid. + source = urllib2.urlopen(source).geturl() + + response = urllib2.urlopen(source + "repodata/repomd.xml") + repomd = xml.etree.ElementTree.fromstring(response.read()) + primary = source + repomd.find("./{%s}data[@type='primary']/{%s}location" % + (REPO_NS, REPO_NS)).attrib['href'] + expected_checksum = repomd.find( + "./{%s}data[@type='primary']/{%s}checksum[@type='sha256']" % + (REPO_NS, REPO_NS)).text + + response = urllib2.urlopen(primary) + gz_data = response.read() + + sha = hashlib.sha256() + sha.update(gz_data) + actual_checksum = binascii.hexlify(sha.digest()) + assert expected_checksum == actual_checksum + + zipped_file = cStringIO.StringIO() + zipped_file.write(gz_data) + zipped_file.seek(0) + contents = gzip.GzipFile(fileobj=zipped_file, mode='rb').read() + metadata = xml.etree.ElementTree.fromstring(contents) + for package in metadata.findall('./{%s}package' % COMMON_NS): + if package.find('./{%s}arch' % COMMON_NS).text != 'x86_64': + continue + package_name = package.find('./{%s}name' % COMMON_NS).text + package_provides = [] + for entry in package.findall('./{%s}format/{%s}provides/{%s}entry' % + (COMMON_NS, RPM_NS, RPM_NS)): + name = entry.attrib['name'] + for prefix in PACKAGE_FILTER: + if name.startswith(prefix): + package_provides.append(name) + distro_provides[package_name] = package_provides + provides[distro] = sorted(list(set( + [package_provides for package in distro_provides + for package_provides in distro_provides[package]]))) + + +script_dir = os.path.dirname(os.path.realpath(__file__)) +with open(os.path.join(script_dir, 'dist-package-provides.json'), 'w') as f: + f.write(json.dumps(provides, sort_keys=True, indent=4, + separators=(',', ': '))) + f.write('\n')
diff --git a/chromecast/browser/BUILD.gn b/chromecast/browser/BUILD.gn index 578caab..32c09c1 100644 --- a/chromecast/browser/BUILD.gn +++ b/chromecast/browser/BUILD.gn
@@ -40,6 +40,8 @@ "cast_quota_permission_context.h", "cast_resource_dispatcher_host_delegate.cc", "cast_resource_dispatcher_host_delegate.h", + "cast_web_contents_manager.cc", + "cast_web_contents_manager.h", "cast_web_view.cc", "cast_web_view.h", "devtools/cast_devtools_manager_delegate.cc",
diff --git a/chromecast/browser/cast_browser_main_parts.cc b/chromecast/browser/cast_browser_main_parts.cc index 506cb34..3f3c14a3 100644 --- a/chromecast/browser/cast_browser_main_parts.cc +++ b/chromecast/browser/cast_browser_main_parts.cc
@@ -223,7 +223,6 @@ // TODO(714676): this should probably set the no restrictions autoplay // policy instead. {switches::kIgnoreAutoplayRestrictionsForTests, ""}, - {switches::kDisableMediaSuspend, ""}, #else // GPU shader disk cache disabling is largely to conserve disk space. {switches::kDisableGpuShaderDiskCache, ""}, @@ -265,6 +264,7 @@ {switches::kEnableUseZoomForDSF, "false"}, // TODO(halliwell): Revert after fix for b/63101386. {switches::kDisallowNonExactResourceReuse, ""}, + {switches::kEnableMediaSuspend, ""}, }; void AddDefaultCommandLineSwitches(base::CommandLine* command_line) { @@ -419,7 +419,8 @@ breakpad::CrashDumpObserver::Create(); breakpad::CrashDumpObserver::GetInstance()->RegisterClient( base::MakeUnique<breakpad::ChildProcessCrashObserver>( - crash_dumps_dir, kAndroidMinidumpDescriptor)); + crash_dumps_dir, kAndroidMinidumpDescriptor, + base::Bind(&base::DoNothing))); #else base::FilePath home_dir; CHECK(PathService::Get(DIR_CAST_HOME, &home_dir));
diff --git a/chromecast/browser/cast_web_contents_manager.cc b/chromecast/browser/cast_web_contents_manager.cc new file mode 100644 index 0000000..1ab1a2b --- /dev/null +++ b/chromecast/browser/cast_web_contents_manager.cc
@@ -0,0 +1,80 @@ +// 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 "chromecast/browser/cast_web_contents_manager.h" + +#include <algorithm> + +#include "base/bind.h" +#include "base/location.h" +#include "base/macros.h" +#include "base/memory/ptr_util.h" +#include "base/sequenced_task_runner.h" +#include "base/stl_util.h" +#include "base/threading/sequenced_task_runner_handle.h" +#include "base/time/time.h" +#include "content/public/browser/media_session.h" +#include "content/public/browser/web_contents.h" + +namespace chromecast { + +CastWebContentsManager::CastWebContentsManager( + content::BrowserContext* browser_context) + : browser_context_(browser_context), + task_runner_(base::SequencedTaskRunnerHandle::Get()), + weak_factory_(this) { + DCHECK(browser_context_); + DCHECK(task_runner_); +} + +CastWebContentsManager::~CastWebContentsManager() = default; + +std::unique_ptr<CastWebView> CastWebContentsManager::CreateWebView( + CastWebView::Delegate* delegate, + scoped_refptr<content::SiteInstance> site_instance, + bool transparent) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + return base::MakeUnique<CastWebView>(delegate, this, browser_context_, + site_instance, transparent); +} + +void CastWebContentsManager::DelayWebContentsDeletion( + std::unique_ptr<content::WebContents> web_contents, + base::TimeDelta time_delta) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(web_contents); + if (time_delta <= base::TimeDelta()) { + LOG(INFO) << "Deleting WebContents for " << web_contents->GetVisibleURL(); + web_contents.reset(); + return; + } + auto* web_contents_ptr = web_contents.get(); + // Suspend the MediaSession to free up media resources for the next content + // window. + content::MediaSession::Get(web_contents_ptr) + ->Suspend(content::MediaSession::SuspendType::SYSTEM); + LOG(INFO) << "WebContents for " << web_contents->GetVisibleURL() + << " will be deleted in " << time_delta.InMilliseconds() + << " milliseconds."; + expiring_web_contents_.insert(std::move(web_contents)); + task_runner_->PostDelayedTask( + FROM_HERE, + base::BindOnce(&CastWebContentsManager::DeleteWebContents, + weak_factory_.GetWeakPtr(), web_contents_ptr), + time_delta); +} + +void CastWebContentsManager::DeleteWebContents( + content::WebContents* web_contents) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(web_contents); + LOG(INFO) << "Deleting WebContents for " << web_contents->GetVisibleURL(); + base::EraseIf( + expiring_web_contents_, + [web_contents](const std::unique_ptr<content::WebContents>& ptr) { + return ptr.get() == web_contents; + }); +} + +} // namespace chromecast
diff --git a/chromecast/browser/cast_web_contents_manager.h b/chromecast/browser/cast_web_contents_manager.h new file mode 100644 index 0000000..fe89cca --- /dev/null +++ b/chromecast/browser/cast_web_contents_manager.h
@@ -0,0 +1,65 @@ +// 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 CHROMECAST_BROWSER_CAST_WEB_CONTENTS_MANAGER_H_ +#define CHROMECAST_BROWSER_CAST_WEB_CONTENTS_MANAGER_H_ + +#include <memory> + +#include "base/containers/flat_set.h" +#include "base/macros.h" +#include "base/memory/ref_counted.h" +#include "base/memory/weak_ptr.h" +#include "base/sequence_checker.h" +#include "chromecast/browser/cast_web_view.h" + +namespace base { +class SequencedTaskRunner; +} // namespace base + +namespace content { +class BrowserContext; +class WebContents; +} // namespace content + +namespace chromecast { + +// This class dispenses CastWebView objects which are used to wrap WebContents +// in cast_shell. This class can take ownership of a WebContents instance when +// the page is in the process of tearing down; we cannot simply post a delayed +// task since WebContents may try to use browser objects that get deleted as a +// result of browser shutdown. +class CastWebContentsManager { + public: + explicit CastWebContentsManager(content::BrowserContext* browser_context); + ~CastWebContentsManager(); + + std::unique_ptr<CastWebView> CreateWebView( + CastWebView::Delegate* delegate, + scoped_refptr<content::SiteInstance> site_instance, + bool transparent); + + // Take ownership of |web_contents| and delete after |time_delta|, or sooner + // if necessary. + void DelayWebContentsDeletion( + std::unique_ptr<content::WebContents> web_contents, + base::TimeDelta time_delta); + + private: + void DeleteWebContents(content::WebContents* web_contents); + + content::BrowserContext* const browser_context_; + base::flat_set<std::unique_ptr<content::WebContents>> expiring_web_contents_; + + const scoped_refptr<base::SequencedTaskRunner> task_runner_; + + SEQUENCE_CHECKER(sequence_checker_); + base::WeakPtrFactory<CastWebContentsManager> weak_factory_; + + DISALLOW_COPY_AND_ASSIGN(CastWebContentsManager); +}; + +} // namespace chromecast + +#endif // CHROMECAST_BROWSER_CAST_WEB_CONTENTS_MANAGER_H_
diff --git a/chromecast/browser/cast_web_view.cc b/chromecast/browser/cast_web_view.cc index 358c5aa8..113c22d 100644 --- a/chromecast/browser/cast_web_view.cc +++ b/chromecast/browser/cast_web_view.cc
@@ -9,6 +9,7 @@ #include "base/logging.h" #include "base/threading/thread_task_runner_handle.h" #include "chromecast/base/metrics/cast_metrics_helper.h" +#include "chromecast/browser/cast_web_contents_manager.h" #include "content/public/browser/navigation_handle.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_view_host.h" @@ -31,9 +32,6 @@ namespace chromecast { namespace { -// The time (in milliseconds) we wait for after a page is closed (i.e. -// after an app is stopped) before we delete the corresponding WebContents. -constexpr int kWebContentsDestructionDelayInMs = 50; std::unique_ptr<content::WebContents> CreateWebContents( content::BrowserContext* browser_context, @@ -55,10 +53,12 @@ } // namespace CastWebView::CastWebView(Delegate* delegate, + CastWebContentsManager* web_contents_manager, content::BrowserContext* browser_context, scoped_refptr<content::SiteInstance> site_instance, bool transparent) : delegate_(delegate), + web_contents_manager_(web_contents_manager), browser_context_(browser_context), site_instance_(std::move(site_instance)), transparent_(transparent), @@ -67,6 +67,7 @@ did_start_navigation_(false), weak_factory_(this) { DCHECK(delegate_); + DCHECK(web_contents_manager_); DCHECK(browser_context_); DCHECK(window_); content::WebContentsObserver::Observe(web_contents_.get()); @@ -83,31 +84,21 @@ ui::PAGE_TRANSITION_TYPED, ""); } -void CastWebView::ClosePage() { +void CastWebView::ClosePage(const base::TimeDelta& shutdown_delay) { + shutdown_delay_ = shutdown_delay; content::WebContentsObserver::Observe(nullptr); + web_contents_->DispatchBeforeUnload(); web_contents_->ClosePage(); } void CastWebView::CloseContents(content::WebContents* source) { DCHECK_EQ(source, web_contents_.get()); - + window_.reset(); // Window destructor requires live web_contents on Android. // We need to delay the deletion of web_contents_ to give (and guarantee) the // renderer enough time to finish 'onunload' handler (but we don't want to // wait any longer than that to delay the starting of next app). - base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( - FROM_HERE, base::Bind(&CastWebView::DelayedCloseContents, - weak_factory_.GetWeakPtr()), - base::TimeDelta::FromMilliseconds(kWebContentsDestructionDelayInMs)); -} - -void CastWebView::DelayedCloseContents() { - // Delete the WebContents object here so that the gfx surface will be - // deleted as part of destroying RenderWidgetHostViewCast object. - // We want to delete the surface before we start the next app because - // the next app could be an external one whose Start() function would - // destroy the primary gfx plane. - window_.reset(); // Window destructor requires live web_contents on Android. - web_contents_.reset(); + web_contents_manager_->DelayWebContentsDeletion(std::move(web_contents_), + shutdown_delay_); delegate_->OnPageStopped(net::OK); }
diff --git a/chromecast/browser/cast_web_view.h b/chromecast/browser/cast_web_view.h index b6231c96..61589f32 100644 --- a/chromecast/browser/cast_web_view.h +++ b/chromecast/browser/cast_web_view.h
@@ -9,6 +9,7 @@ #include <string> #include "base/memory/weak_ptr.h" +#include "base/time/time.h" #include "chromecast/browser/cast_content_window.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents_delegate.h" @@ -22,6 +23,7 @@ namespace chromecast { +class CastWebContentsManager; class CastWindowManager; // A simplified interface for loading and displaying WebContents in cast_shell. @@ -42,6 +44,7 @@ // |delegate| and |browser_context| should outlive the lifetime of this // object. CastWebView(Delegate* delegate, + CastWebContentsManager* web_contents_manager, content::BrowserContext* browser_context, scoped_refptr<content::SiteInstance> site_instance, bool transparent); @@ -57,8 +60,9 @@ // Begins the close process for this page (ie. triggering document.onunload). // A consumer of the class can be notified when the process has been finished - // via Delegate::OnPageStopped(). - void ClosePage(); + // via Delegate::OnPageStopped(). The page will be torn down after + // |shutdown_delay| has elapsed, or sooner if required. + void ClosePage(const base::TimeDelta& shutdown_delay); // Makes the page visible to the user. void Show(CastWindowManager* window_manager); @@ -94,15 +98,15 @@ override; #endif // defined(OS_ANDROID) - void DelayedCloseContents(); - Delegate* const delegate_; + CastWebContentsManager* const web_contents_manager_; content::BrowserContext* const browser_context_; const scoped_refptr<content::SiteInstance> site_instance_; const bool transparent_; std::unique_ptr<content::WebContents> web_contents_; std::unique_ptr<shell::CastContentWindow> window_; bool did_start_navigation_; + base::TimeDelta shutdown_delay_; base::WeakPtrFactory<CastWebView> weak_factory_;
diff --git a/chromecast/browser/service/cast_service_simple.cc b/chromecast/browser/service/cast_service_simple.cc index 56144b7..3770d50b 100644 --- a/chromecast/browser/service/cast_service_simple.cc +++ b/chromecast/browser/service/cast_service_simple.cc
@@ -9,6 +9,8 @@ #include "base/command_line.h" #include "base/files/file_util.h" #include "base/memory/ptr_util.h" +#include "base/time/time.h" +#include "chromecast/browser/cast_web_contents_manager.h" #include "content/public/browser/web_contents.h" #include "content/public/common/content_switches.h" #include "net/base/filename_util.h" @@ -39,7 +41,9 @@ PrefService* pref_service, CastWindowManager* window_manager) : CastService(browser_context, pref_service), - window_manager_(window_manager) { + window_manager_(window_manager), + web_contents_manager_( + base::MakeUnique<CastWebContentsManager>(browser_context)) { DCHECK(window_manager_); } @@ -58,16 +62,15 @@ return; } - cast_web_view_ = base::MakeUnique<CastWebView>(this, browser_context(), - /*site_instance*/ nullptr, - /*transparent*/ false); + cast_web_view_ = web_contents_manager_->CreateWebView( + this, /*site_instance*/ nullptr, /*transparent*/ false); cast_web_view_->LoadUrl(startup_url_); cast_web_view_->Show(window_manager_); } void CastServiceSimple::StopInternal() { if (cast_web_view_) { - cast_web_view_->ClosePage(); + cast_web_view_->ClosePage(base::TimeDelta()); } cast_web_view_.reset(); }
diff --git a/chromecast/browser/service/cast_service_simple.h b/chromecast/browser/service/cast_service_simple.h index 1a48b89..c8525a9 100644 --- a/chromecast/browser/service/cast_service_simple.h +++ b/chromecast/browser/service/cast_service_simple.h
@@ -13,6 +13,7 @@ #include "url/gurl.h" namespace chromecast { +class CastWebContentsManager; class CastWindowManager; namespace shell { @@ -41,6 +42,7 @@ private: CastWindowManager* const window_manager_; + const std::unique_ptr<CastWebContentsManager> web_contents_manager_; std::unique_ptr<CastWebView> cast_web_view_; GURL startup_url_;
diff --git a/chromecast/browser/test/cast_browser_test.cc b/chromecast/browser/test/cast_browser_test.cc index b3c71f5db..9528a10e 100644 --- a/chromecast/browser/test/cast_browser_test.cc +++ b/chromecast/browser/test/cast_browser_test.cc
@@ -13,6 +13,7 @@ #include "chromecast/browser/cast_browser_context.h" #include "chromecast/browser/cast_browser_process.h" #include "chromecast/browser/cast_content_window.h" +#include "chromecast/browser/cast_web_contents_manager.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/render_process_host.h" #include "content/public/browser/web_contents.h" @@ -44,6 +45,8 @@ base::RunLoop().RunUntilIdle(); metrics::CastMetricsHelper::GetInstance()->SetDummySessionIdForTesting(); + web_contents_manager_ = base::MakeUnique<CastWebContentsManager>( + CastBrowserProcess::GetInstance()->browser_context()); } void CastBrowserTest::PostRunTestOnMainThread() { @@ -51,9 +54,8 @@ } content::WebContents* CastBrowserTest::NavigateToURL(const GURL& url) { - cast_web_view_ = base::WrapUnique(new CastWebView( - this, CastBrowserProcess::GetInstance()->browser_context(), nullptr, - false /*transparent*/)); + cast_web_view_ = web_contents_manager_->CreateWebView( + this, nullptr /*site_instance*/, false /*transparent*/); content::WebContents* web_contents = cast_web_view_->web_contents(); content::WaitForLoadStop(web_contents);
diff --git a/chromecast/browser/test/cast_browser_test.h b/chromecast/browser/test/cast_browser_test.h index 895384e..f86c5f0 100644 --- a/chromecast/browser/test/cast_browser_test.h +++ b/chromecast/browser/test/cast_browser_test.h
@@ -17,6 +17,9 @@ } namespace chromecast { + +class CastWebContentsManager; + namespace shell { // This test allows for running an entire browser-process lifecycle per unit @@ -44,6 +47,7 @@ void OnWindowDestroyed() override; void OnKeyEvent(const ui::KeyEvent& key_event) override; + std::unique_ptr<CastWebContentsManager> web_contents_manager_; std::unique_ptr<CastWebView> cast_web_view_; DISALLOW_COPY_AND_ASSIGN(CastBrowserTest);
diff --git a/chromecast/media/cdm/cast_cdm_factory.cc b/chromecast/media/cdm/cast_cdm_factory.cc index 2d0cca55..a09de7c0 100644 --- a/chromecast/media/cdm/cast_cdm_factory.cc +++ b/chromecast/media/cdm/cast_cdm_factory.cc
@@ -11,6 +11,7 @@ #include "media/base/bind_to_current_loop.h" #include "media/base/cdm_config.h" #include "media/base/cdm_key_information.h" +#include "url/origin.h" namespace chromecast { namespace media { @@ -28,7 +29,7 @@ void CastCdmFactory::Create( const std::string& key_system, - const GURL& security_origin, + const url::Origin& security_origin, const ::media::CdmConfig& cdm_config, const ::media::SessionMessageCB& session_message_cb, const ::media::SessionClosedCB& session_closed_cb, @@ -67,7 +68,7 @@ scoped_refptr<CastCdm> CastCdmFactory::CreatePlatformBrowserCdm( const CastKeySystem& cast_key_system, - const GURL& security_origin, + const url::Origin& security_origin, const ::media::CdmConfig& cdm_config) { return nullptr; }
diff --git a/chromecast/media/cdm/cast_cdm_factory.h b/chromecast/media/cdm/cast_cdm_factory.h index 24120eb7..cd477d2 100644 --- a/chromecast/media/cdm/cast_cdm_factory.h +++ b/chromecast/media/cdm/cast_cdm_factory.h
@@ -33,7 +33,7 @@ // ::media::CdmFactory implementation: void Create( const std::string& key_system, - const GURL& security_origin, + const url::Origin& security_origin, const ::media::CdmConfig& cdm_config, const ::media::SessionMessageCB& session_message_cb, const ::media::SessionClosedCB& session_closed_cb, @@ -44,7 +44,7 @@ // Provides a platform-specific BrowserCdm instance. virtual scoped_refptr<CastCdm> CreatePlatformBrowserCdm( const CastKeySystem& cast_key_system, - const GURL& security_origin, + const url::Origin& security_origin, const ::media::CdmConfig& cdm_config); protected:
diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM index 2478b28..aeb23ca 100644 --- a/chromeos/CHROMEOS_LKGM +++ b/chromeos/CHROMEOS_LKGM
@@ -1 +1 @@ -9864.0.0 \ No newline at end of file +9896.0.0 \ No newline at end of file
diff --git a/chromeos/components/tether/BUILD.gn b/chromeos/components/tether/BUILD.gn index ba889cb8..2f38e9f 100644 --- a/chromeos/components/tether/BUILD.gn +++ b/chromeos/components/tether/BUILD.gn
@@ -30,6 +30,8 @@ "device_status_util.h", "disconnect_tethering_operation.cc", "disconnect_tethering_operation.h", + "disconnect_tethering_request_sender.cc", + "disconnect_tethering_request_sender.h", "host_connection_metrics_logger.cc", "host_connection_metrics_logger.h", "host_scan_cache.cc", @@ -47,6 +49,8 @@ "host_scanner_operation.h", "initializer.cc", "initializer.h", + "initializer_impl.cc", + "initializer_impl.h", "keep_alive_operation.cc", "keep_alive_operation.h", "keep_alive_scheduler.cc", @@ -115,8 +119,12 @@ "fake_active_host.h", "fake_ble_connection_manager.cc", "fake_ble_connection_manager.h", + "fake_disconnect_tethering_request_sender.cc", + "fake_disconnect_tethering_request_sender.h", "fake_host_scan_cache.cc", "fake_host_scan_cache.h", + "fake_initializer.cc", + "fake_initializer.h", "fake_network_configuration_remover.cc", "fake_network_configuration_remover.h", "fake_notification_presenter.cc", @@ -170,7 +178,7 @@ "host_scan_scheduler_unittest.cc", "host_scanner_operation_unittest.cc", "host_scanner_unittest.cc", - "initializer_unittest.cc", + "initializer_impl_unittest.cc", "keep_alive_operation_unittest.cc", "keep_alive_scheduler_unittest.cc", "master_host_scan_cache_unittest.cc",
diff --git a/chromeos/components/tether/disconnect_tethering_request_sender.cc b/chromeos/components/tether/disconnect_tethering_request_sender.cc new file mode 100644 index 0000000..543b9e4 --- /dev/null +++ b/chromeos/components/tether/disconnect_tethering_request_sender.cc
@@ -0,0 +1,31 @@ +// 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 "chromeos/components/tether/disconnect_tethering_request_sender.h" + +namespace chromeos { + +namespace tether { + +DisconnectTetheringRequestSender::DisconnectTetheringRequestSender() {} + +DisconnectTetheringRequestSender::~DisconnectTetheringRequestSender() {} + +void DisconnectTetheringRequestSender::AddObserver(Observer* observer) { + observer_list_.AddObserver(observer); +} + +void DisconnectTetheringRequestSender::RemoveObserver(Observer* observer) { + observer_list_.RemoveObserver(observer); +} + +void DisconnectTetheringRequestSender:: + NotifyPendingDisconnectRequestsComplete() { + for (auto& observer : observer_list_) + observer.OnPendingDisconnectRequestsComplete(); +} + +} // namespace tether + +} // namespace chromeos
diff --git a/chromeos/components/tether/disconnect_tethering_request_sender.h b/chromeos/components/tether/disconnect_tethering_request_sender.h new file mode 100644 index 0000000..935b9039 --- /dev/null +++ b/chromeos/components/tether/disconnect_tethering_request_sender.h
@@ -0,0 +1,53 @@ +// 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 CHROMEOS_COMPONENTS_TETHER_DISCONNECT_TETHERING_REQUEST_SENDER_H_ +#define CHROMEOS_COMPONENTS_TETHER_DISCONNECT_TETHERING_REQUEST_SENDER_H_ + +#include "base/macros.h" +#include "base/observer_list.h" + +namespace chromeos { + +namespace tether { + +// Sends a DisconnectTetheringRequest to the formerly active host. Supports +// multiple concurrent messages. +class DisconnectTetheringRequestSender { + public: + class Observer { + public: + Observer() {} + virtual ~Observer() {} + + virtual void OnPendingDisconnectRequestsComplete() {} + }; + + DisconnectTetheringRequestSender(); + virtual ~DisconnectTetheringRequestSender(); + + // Sends a DisconnectTetheringRequest to the device with the given ID. + virtual void SendDisconnectRequestToDevice(const std::string& device_id) = 0; + + // Returns whether at least one DisconnectTetheringRequest is still in the + // process of being sent. + virtual bool HasPendingRequests() = 0; + + void AddObserver(Observer* observer); + void RemoveObserver(Observer* observer); + + protected: + void NotifyPendingDisconnectRequestsComplete(); + + private: + base::ObserverList<Observer> observer_list_; + + DISALLOW_COPY_AND_ASSIGN(DisconnectTetheringRequestSender); +}; + +} // namespace tether + +} // namespace chromeos + +#endif // CHROMEOS_COMPONENTS_TETHER_DISCONNECT_TETHERING_REQUEST_SENDER_H_
diff --git a/chromeos/components/tether/fake_disconnect_tethering_request_sender.cc b/chromeos/components/tether/fake_disconnect_tethering_request_sender.cc new file mode 100644 index 0000000..b4234e4 --- /dev/null +++ b/chromeos/components/tether/fake_disconnect_tethering_request_sender.cc
@@ -0,0 +1,32 @@ +// 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 "chromeos/components/tether/fake_disconnect_tethering_request_sender.h" + +namespace chromeos { + +namespace tether { + +FakeDisconnectTetheringRequestSender::FakeDisconnectTetheringRequestSender() {} + +FakeDisconnectTetheringRequestSender::~FakeDisconnectTetheringRequestSender() {} + +void FakeDisconnectTetheringRequestSender::SendDisconnectRequestToDevice( + const std::string& device_id) { + // TODO(lesliewatkins): Flesh out. +} + +bool FakeDisconnectTetheringRequestSender::HasPendingRequests() { + // TODO(lesliewatkins): Flesh out. + return false; +} + +void FakeDisconnectTetheringRequestSender:: + NotifyPendingDisconnectRequestsComplete() { + DisconnectTetheringRequestSender::NotifyPendingDisconnectRequestsComplete(); +} + +} // namespace tether + +} // namespace chromeos
diff --git a/chromeos/components/tether/fake_disconnect_tethering_request_sender.h b/chromeos/components/tether/fake_disconnect_tethering_request_sender.h new file mode 100644 index 0000000..025414b --- /dev/null +++ b/chromeos/components/tether/fake_disconnect_tethering_request_sender.h
@@ -0,0 +1,37 @@ +// 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 CHROMEOS_COMPONENTS_TETHER_FAKE_DISCONNECT_TETHERING_REQUEST_SENDER_H_ +#define CHROMEOS_COMPONENTS_TETHER_FAKE_DISCONNECT_TETHERING_REQUEST_SENDER_H_ + +#include "base/macros.h" +#include "base/observer_list.h" +#include "chromeos/components/tether/disconnect_tethering_request_sender.h" + +namespace chromeos { + +namespace tether { + +// Test double for DisconnectTetheringRequestSender. +class FakeDisconnectTetheringRequestSender + : public DisconnectTetheringRequestSender { + public: + FakeDisconnectTetheringRequestSender(); + ~FakeDisconnectTetheringRequestSender() override; + + // DisconnectTetheringRequestSender: + void SendDisconnectRequestToDevice(const std::string& device_id) override; + bool HasPendingRequests() override; + + void NotifyPendingDisconnectRequestsComplete(); + + private: + DISALLOW_COPY_AND_ASSIGN(FakeDisconnectTetheringRequestSender); +}; + +} // namespace tether + +} // namespace chromeos + +#endif // CHROMEOS_COMPONENTS_TETHER_FAKE_DISCONNECT_TETHERING_REQUEST_SENDER_H_
diff --git a/chromeos/components/tether/fake_initializer.cc b/chromeos/components/tether/fake_initializer.cc new file mode 100644 index 0000000..0b4e109c --- /dev/null +++ b/chromeos/components/tether/fake_initializer.cc
@@ -0,0 +1,32 @@ +// 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 "chromeos/components/tether/fake_initializer.h" + +namespace chromeos { + +namespace tether { + +FakeInitializer::FakeInitializer(bool has_asynchronous_shutdown) + : has_asynchronous_shutdown_(has_asynchronous_shutdown) {} + +FakeInitializer::~FakeInitializer() {} + +void FakeInitializer::FinishAsynchronousShutdown() { + DCHECK(status() == Initializer::Status::SHUTTING_DOWN); + TransitionToStatus(Initializer::Status::SHUT_DOWN); +} + +void FakeInitializer::RequestShutdown() { + DCHECK(status() == Initializer::Status::ACTIVE); + + if (has_asynchronous_shutdown_) + TransitionToStatus(Initializer::Status::SHUTTING_DOWN); + else + TransitionToStatus(Initializer::Status::SHUT_DOWN); +} + +} // namespace tether + +} // namespace chromeos
diff --git a/chromeos/components/tether/fake_initializer.h b/chromeos/components/tether/fake_initializer.h new file mode 100644 index 0000000..b7f4234 --- /dev/null +++ b/chromeos/components/tether/fake_initializer.h
@@ -0,0 +1,41 @@ +// 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 CHROMEOS_COMPONENTS_TETHER_FAKE_INITIALIZER_H_ +#define CHROMEOS_COMPONENTS_TETHER_FAKE_INITIALIZER_H_ + +#include "base/macros.h" +#include "chromeos/components/tether/initializer.h" + +namespace chromeos { + +namespace tether { + +// Test double for Initializer. +class FakeInitializer : public Initializer { + public: + explicit FakeInitializer(bool has_asynchronous_shutdown); + ~FakeInitializer() override; + + void set_has_asynchronous_shutdown(bool has_asynchronous_shutdown) { + has_asynchronous_shutdown_ = has_asynchronous_shutdown; + } + + // Should only be called when status() == SHUTTING_DOWN. + void FinishAsynchronousShutdown(); + + // Initializer: + void RequestShutdown() override; + + private: + bool has_asynchronous_shutdown_; + + DISALLOW_COPY_AND_ASSIGN(FakeInitializer); +}; + +} // namespace tether + +} // namespace chromeos + +#endif // CHROMEOS_COMPONENTS_TETHER_FAKE_INITIALIZER_H_
diff --git a/chromeos/components/tether/initializer.cc b/chromeos/components/tether/initializer.cc index 1eb416e..495e700 100644 --- a/chromeos/components/tether/initializer.cc +++ b/chromeos/components/tether/initializer.cc
@@ -1,238 +1,36 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. +// 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 "chromeos/components/tether/initializer.h" -#include "base/bind.h" -#include "chromeos/components/tether/active_host.h" -#include "chromeos/components/tether/active_host_network_state_updater.h" -#include "chromeos/components/tether/ble_connection_manager.h" -#include "chromeos/components/tether/crash_recovery_manager.h" -#include "chromeos/components/tether/device_id_tether_network_guid_map.h" -#include "chromeos/components/tether/host_connection_metrics_logger.h" -#include "chromeos/components/tether/host_scan_device_prioritizer_impl.h" -#include "chromeos/components/tether/host_scan_scheduler.h" -#include "chromeos/components/tether/host_scanner.h" -#include "chromeos/components/tether/keep_alive_scheduler.h" -#include "chromeos/components/tether/master_host_scan_cache.h" -#include "chromeos/components/tether/network_configuration_remover.h" -#include "chromeos/components/tether/network_connection_handler_tether_delegate.h" -#include "chromeos/components/tether/network_host_scan_cache.h" -#include "chromeos/components/tether/notification_presenter.h" -#include "chromeos/components/tether/notification_remover.h" -#include "chromeos/components/tether/persistent_host_scan_cache_impl.h" -#include "chromeos/components/tether/tether_connector.h" -#include "chromeos/components/tether/tether_disconnector_impl.h" -#include "chromeos/components/tether/tether_host_fetcher.h" -#include "chromeos/components/tether/tether_host_response_recorder.h" -#include "chromeos/components/tether/tether_network_disconnection_handler.h" -#include "chromeos/components/tether/timer_factory.h" -#include "chromeos/components/tether/wifi_hotspot_connector.h" -#include "chromeos/network/managed_network_configuration_handler.h" -#include "chromeos/network/network_connect.h" -#include "chromeos/network/network_connection_handler.h" -#include "chromeos/network/network_state_handler.h" -#include "components/cryptauth/bluetooth_throttler_impl.h" -#include "components/cryptauth/cryptauth_service.h" -#include "components/cryptauth/local_device_data_provider.h" -#include "components/cryptauth/remote_beacon_seed_fetcher.h" -#include "components/prefs/pref_service.h" -#include "components/proximity_auth/logging/logging.h" - namespace chromeos { namespace tether { -// static -Initializer* Initializer::instance_ = nullptr; +Initializer::Initializer() {} -// static -void Initializer::Init( - cryptauth::CryptAuthService* cryptauth_service, - NotificationPresenter* notification_presenter, - PrefService* pref_service, - ProfileOAuth2TokenService* token_service, - NetworkStateHandler* network_state_handler, - ManagedNetworkConfigurationHandler* managed_network_configuration_handler, - NetworkConnect* network_connect, - NetworkConnectionHandler* network_connection_handler, - scoped_refptr<device::BluetoothAdapter> adapter) { - if (instance_) { - // The Tether feature has already been initialized. No need to do anything. +Initializer::~Initializer() {} + +void Initializer::AddObserver(Observer* observer) { + observer_list_.AddObserver(observer); +} + +void Initializer::RemoveObserver(Observer* observer) { + observer_list_.RemoveObserver(observer); +} + +void Initializer::TransitionToStatus(Status new_status) { + if (status_ == new_status) return; - } - PA_LOG(INFO) << "Initializing Tether feature."; - instance_ = - new Initializer(cryptauth_service, std::move(notification_presenter), - pref_service, token_service, network_state_handler, - managed_network_configuration_handler, network_connect, - network_connection_handler, adapter); -} + status_ = new_status; -// static -void Initializer::Shutdown() { - if (instance_) { - PA_LOG(INFO) << "Shutting down Tether feature."; - delete instance_; - instance_ = nullptr; - } -} - -// static -void Initializer::RegisterProfilePrefs(PrefRegistrySimple* registry) { - ActiveHost::RegisterPrefs(registry); - PersistentHostScanCacheImpl::RegisterPrefs(registry); - TetherHostResponseRecorder::RegisterPrefs(registry); - TetherDisconnectorImpl::RegisterPrefs(registry); -} - -Initializer::Initializer( - cryptauth::CryptAuthService* cryptauth_service, - NotificationPresenter* notification_presenter, - PrefService* pref_service, - ProfileOAuth2TokenService* token_service, - NetworkStateHandler* network_state_handler, - ManagedNetworkConfigurationHandler* managed_network_configuration_handler, - NetworkConnect* network_connect, - NetworkConnectionHandler* network_connection_handler, - scoped_refptr<device::BluetoothAdapter> adapter) - : cryptauth_service_(cryptauth_service), - notification_presenter_(notification_presenter), - pref_service_(pref_service), - token_service_(token_service), - network_state_handler_(network_state_handler), - managed_network_configuration_handler_( - managed_network_configuration_handler), - network_connect_(network_connect), - network_connection_handler_(network_connection_handler), - adapter_(adapter), - weak_ptr_factory_(this) { - if (!token_service_->RefreshTokenIsAvailable( - cryptauth_service_->GetAccountId())) { - PA_LOG(INFO) << "Refresh token not yet available; " - << "waiting for valid token to initializing tether feature."; - token_service_->AddObserver(this); + if (status_ != Status::SHUT_DOWN) return; - } - PA_LOG(INFO) << "Refresh token is available; initializing tether feature."; - CreateComponent(); -} - -Initializer::~Initializer() { - token_service_->RemoveObserver(this); - network_state_handler_->set_tether_sort_delegate(nullptr); -} - -void Initializer::OnRefreshTokensLoaded() { - if (!token_service_->RefreshTokenIsAvailable( - cryptauth_service_->GetAccountId())) { - // If a token for the active account is still not available, continue - // waiting for a new token. - return; - } - - PA_LOG(INFO) << "Refresh token has loaded; initializing tether feature."; - - token_service_->RemoveObserver(this); - CreateComponent(); -} - -void Initializer::CreateComponent() { - PA_LOG(INFO) << "Successfully set Bluetooth advertisement interval. " - << "Initializing tether feature."; - - tether_host_fetcher_ = - base::MakeUnique<TetherHostFetcher>(cryptauth_service_); - local_device_data_provider_ = - base::MakeUnique<cryptauth::LocalDeviceDataProvider>(cryptauth_service_); - remote_beacon_seed_fetcher_ = - base::MakeUnique<cryptauth::RemoteBeaconSeedFetcher>( - cryptauth_service_->GetCryptAuthDeviceManager()); - ble_connection_manager_ = base::MakeUnique<BleConnectionManager>( - cryptauth_service_, adapter_, local_device_data_provider_.get(), - remote_beacon_seed_fetcher_.get(), - cryptauth::BluetoothThrottlerImpl::GetInstance()); - tether_host_response_recorder_ = - base::MakeUnique<TetherHostResponseRecorder>(pref_service_); - device_id_tether_network_guid_map_ = - base::MakeUnique<DeviceIdTetherNetworkGuidMap>(); - host_scan_device_prioritizer_ = - base::MakeUnique<HostScanDevicePrioritizerImpl>( - tether_host_response_recorder_.get(), - device_id_tether_network_guid_map_.get()); - network_state_handler_->set_tether_sort_delegate( - host_scan_device_prioritizer_.get()); - wifi_hotspot_connector_ = base::MakeUnique<WifiHotspotConnector>( - network_state_handler_, network_connect_); - active_host_ = - base::MakeUnique<ActiveHost>(tether_host_fetcher_.get(), pref_service_); - active_host_network_state_updater_ = - base::MakeUnique<ActiveHostNetworkStateUpdater>(active_host_.get(), - network_state_handler_); - persistent_host_scan_cache_ = - base::MakeUnique<PersistentHostScanCacheImpl>(pref_service_); - network_host_scan_cache_ = base::MakeUnique<NetworkHostScanCache>( - network_state_handler_, tether_host_response_recorder_.get(), - device_id_tether_network_guid_map_.get()); - master_host_scan_cache_ = base::MakeUnique<MasterHostScanCache>( - base::MakeUnique<TimerFactory>(), active_host_.get(), - network_host_scan_cache_.get(), persistent_host_scan_cache_.get()); - notification_remover_ = base::MakeUnique<NotificationRemover>( - network_state_handler_, notification_presenter_, - master_host_scan_cache_.get(), active_host_.get()); - keep_alive_scheduler_ = base::MakeUnique<KeepAliveScheduler>( - active_host_.get(), ble_connection_manager_.get(), - master_host_scan_cache_.get(), device_id_tether_network_guid_map_.get()); - clock_ = base::MakeUnique<base::DefaultClock>(); - host_scanner_ = base::MakeUnique<HostScanner>( - network_state_handler_, tether_host_fetcher_.get(), - ble_connection_manager_.get(), host_scan_device_prioritizer_.get(), - tether_host_response_recorder_.get(), notification_presenter_, - device_id_tether_network_guid_map_.get(), master_host_scan_cache_.get(), - clock_.get()); - host_scan_scheduler_ = base::MakeUnique<HostScanScheduler>( - network_state_handler_, host_scanner_.get()); - host_connection_metrics_logger_ = - base::MakeUnique<HostConnectionMetricsLogger>(); - tether_connector_ = base::MakeUnique<TetherConnector>( - network_state_handler_, wifi_hotspot_connector_.get(), active_host_.get(), - tether_host_fetcher_.get(), ble_connection_manager_.get(), - tether_host_response_recorder_.get(), - device_id_tether_network_guid_map_.get(), master_host_scan_cache_.get(), - notification_presenter_, host_connection_metrics_logger_.get()); - network_configuration_remover_ = - base::MakeUnique<NetworkConfigurationRemover>( - network_state_handler_, managed_network_configuration_handler_); - tether_disconnector_ = base::MakeUnique<TetherDisconnectorImpl>( - network_connection_handler_, network_state_handler_, active_host_.get(), - ble_connection_manager_.get(), network_configuration_remover_.get(), - tether_connector_.get(), device_id_tether_network_guid_map_.get(), - tether_host_fetcher_.get(), pref_service_); - tether_network_disconnection_handler_ = - base::MakeUnique<TetherNetworkDisconnectionHandler>( - active_host_.get(), network_state_handler_, - network_configuration_remover_.get()); - network_connection_handler_tether_delegate_ = - base::MakeUnique<NetworkConnectionHandlerTetherDelegate>( - network_connection_handler_, tether_connector_.get(), - tether_disconnector_.get()); - - crash_recovery_manager_ = base::MakeUnique<CrashRecoveryManager>( - network_state_handler_, active_host_.get(), - master_host_scan_cache_.get()); - crash_recovery_manager_->RestorePreCrashStateIfNecessary(base::Bind( - &Initializer::OnPreCrashStateRestored, weak_ptr_factory_.GetWeakPtr())); -} - -void Initializer::OnPreCrashStateRestored() { - // |crash_recovery_manager_| is no longer needed since it has completed. - crash_recovery_manager_.reset(); - - // Start a scan now that the Tether module has started up. - host_scan_scheduler_->ScheduleScan(); + for (auto& observer : observer_list_) + observer.OnShutdownComplete(); } } // namespace tether
diff --git a/chromeos/components/tether/initializer.h b/chromeos/components/tether/initializer.h index c58993c..b4a841b 100644 --- a/chromeos/components/tether/initializer.h +++ b/chromeos/components/tether/initializer.h
@@ -1,154 +1,50 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. +// 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 CHROMEOS_COMPONENTS_TETHER_INITIALIZER_H_ #define CHROMEOS_COMPONENTS_TETHER_INITIALIZER_H_ -#include <memory> - -#include "base/gtest_prod_util.h" #include "base/macros.h" -#include "base/memory/ref_counted.h" -#include "base/memory/weak_ptr.h" -#include "base/time/default_clock.h" -#include "components/prefs/pref_registry_simple.h" -#include "components/signin/core/browser/profile_oauth2_token_service.h" -#include "device/bluetooth/bluetooth_adapter.h" -#include "device/bluetooth/bluetooth_advertisement.h" - -class PrefService; - -namespace cryptauth { -class CryptAuthService; -class LocalDeviceDataProvider; -class RemoteBeaconSeedFetcher; -} +#include "base/observer_list.h" namespace chromeos { -class ManagedNetworkConfigurationHandler; -class NetworkConnect; -class NetworkConnectionHandler; -class NetworkStateHandler; - namespace tether { -class ActiveHost; -class ActiveHostNetworkStateUpdater; -class BleConnectionManager; -class CrashRecoveryManager; -class NetworkConnectionHandlerTetherDelegate; -class DeviceIdTetherNetworkGuidMap; -class HostScanner; -class HostScanScheduler; -class HostScanDevicePrioritizerImpl; -class KeepAliveScheduler; -class HostConnectionMetricsLogger; -class MasterHostScanCache; -class NetworkConfigurationRemover; -class NetworkHostScanCache; -class NotificationPresenter; -class NotificationRemover; -class PersistentHostScanCache; -class TetherConnector; -class TetherDisconnector; -class TetherHostFetcher; -class TetherHostResponseRecorder; -class TetherNetworkDisconnectionHandler; -class WifiHotspotConnector; - -// Initializes the Tether Chrome OS component. -class Initializer : public OAuth2TokenService::Observer { +// Initializes the Tether component. +class Initializer { public: - // Initializes the tether feature. If the feature has already been - // initialized, this function is a no-op. - static void Init( - cryptauth::CryptAuthService* cryptauth_service, - NotificationPresenter* notification_presenter, - PrefService* pref_service, - ProfileOAuth2TokenService* token_service, - NetworkStateHandler* network_state_handler, - ManagedNetworkConfigurationHandler* managed_network_configuration_handler, - NetworkConnect* network_connect, - NetworkConnectionHandler* network_connection_handler, - scoped_refptr<device::BluetoothAdapter> adapter); + class Observer { + public: + Observer() {} + virtual ~Observer() {} - // Shuts down the tether feature, destroying all internal classes. This should - // be called before the dependencies passed to Init() are destroyed. - static void Shutdown(); + virtual void OnShutdownComplete() = 0; + }; - static void RegisterProfilePrefs(PrefRegistrySimple* registry); + enum class Status { ACTIVE, SHUTTING_DOWN, SHUT_DOWN }; + + Initializer(); + virtual ~Initializer(); + + // Requests that the Tether component shuts down. If the component can be shut + // down synchronously, this causes Initializer to transition to the SHUT_DOWN + // status immediately. However, if the component requires an asynchronous + // shutdown, the class transitions to the SHUTTING_DOWN status; once an + // asynchronous shutdown completes, Initializer transitions to the SHUT_DOWN + // status and notifies observers. + virtual void RequestShutdown() = 0; + + void AddObserver(Observer* observer); + void RemoveObserver(Observer* observer); + + Status status() { return status_; } + void TransitionToStatus(Status new_status); private: - friend class InitializerTest; - - static Initializer* instance_; - - Initializer( - cryptauth::CryptAuthService* cryptauth_service, - NotificationPresenter* notification_presenter, - PrefService* pref_service, - ProfileOAuth2TokenService* token_service, - NetworkStateHandler* network_state_handler, - ManagedNetworkConfigurationHandler* managed_network_configuration_handler, - NetworkConnect* network_connect, - NetworkConnectionHandler* network_connection_handler, - scoped_refptr<device::BluetoothAdapter> adapter); - ~Initializer() override; - - // OAuth2TokenService::Observer: - void OnRefreshTokensLoaded() override; - - void CreateComponent(); - void OnPreCrashStateRestored(); - - cryptauth::CryptAuthService* cryptauth_service_; - NotificationPresenter* notification_presenter_; - PrefService* pref_service_; - ProfileOAuth2TokenService* token_service_; - NetworkStateHandler* network_state_handler_; - ManagedNetworkConfigurationHandler* managed_network_configuration_handler_; - NetworkConnect* network_connect_; - NetworkConnectionHandler* network_connection_handler_; - scoped_refptr<device::BluetoothAdapter> adapter_; - - // Declare new objects in the order that they will be created during - // initialization to ensure that they are destroyed in the correct order. This - // order will be enforced by InitializerTest.TestCreateAndDestroy. - std::unique_ptr<TetherHostFetcher> tether_host_fetcher_; - std::unique_ptr<cryptauth::LocalDeviceDataProvider> - local_device_data_provider_; - std::unique_ptr<cryptauth::RemoteBeaconSeedFetcher> - remote_beacon_seed_fetcher_; - std::unique_ptr<BleConnectionManager> ble_connection_manager_; - std::unique_ptr<TetherHostResponseRecorder> tether_host_response_recorder_; - std::unique_ptr<HostScanDevicePrioritizerImpl> host_scan_device_prioritizer_; - std::unique_ptr<WifiHotspotConnector> wifi_hotspot_connector_; - std::unique_ptr<ActiveHost> active_host_; - std::unique_ptr<ActiveHostNetworkStateUpdater> - active_host_network_state_updater_; - std::unique_ptr<DeviceIdTetherNetworkGuidMap> - device_id_tether_network_guid_map_; - std::unique_ptr<PersistentHostScanCache> persistent_host_scan_cache_; - std::unique_ptr<NetworkHostScanCache> network_host_scan_cache_; - std::unique_ptr<MasterHostScanCache> master_host_scan_cache_; - std::unique_ptr<NotificationRemover> notification_remover_; - std::unique_ptr<KeepAliveScheduler> keep_alive_scheduler_; - std::unique_ptr<base::DefaultClock> clock_; - std::unique_ptr<HostScanner> host_scanner_; - std::unique_ptr<HostScanScheduler> host_scan_scheduler_; - std::unique_ptr<HostConnectionMetricsLogger> host_connection_metrics_logger_; - std::unique_ptr<TetherConnector> tether_connector_; - std::unique_ptr<TetherDisconnector> tether_disconnector_; - std::unique_ptr<NetworkConfigurationRemover> network_configuration_remover_; - std::unique_ptr<NetworkConnectionHandlerTetherDelegate> - network_connection_handler_tether_delegate_; - std::unique_ptr<TetherNetworkDisconnectionHandler> - tether_network_disconnection_handler_; - std::unique_ptr<CrashRecoveryManager> crash_recovery_manager_; - - base::WeakPtrFactory<Initializer> weak_ptr_factory_; + Status status_ = Status::ACTIVE; + base::ObserverList<Observer> observer_list_; DISALLOW_COPY_AND_ASSIGN(Initializer); };
diff --git a/chromeos/components/tether/initializer_impl.cc b/chromeos/components/tether/initializer_impl.cc new file mode 100644 index 0000000..66367f4 --- /dev/null +++ b/chromeos/components/tether/initializer_impl.cc
@@ -0,0 +1,343 @@ +// Copyright 2016 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 "chromeos/components/tether/initializer_impl.h" + +#include "base/bind.h" +#include "chromeos/components/tether/active_host.h" +#include "chromeos/components/tether/active_host_network_state_updater.h" +#include "chromeos/components/tether/ble_connection_manager.h" +#include "chromeos/components/tether/crash_recovery_manager.h" +#include "chromeos/components/tether/device_id_tether_network_guid_map.h" +#include "chromeos/components/tether/disconnect_tethering_request_sender.h" +#include "chromeos/components/tether/host_connection_metrics_logger.h" +#include "chromeos/components/tether/host_scan_device_prioritizer_impl.h" +#include "chromeos/components/tether/host_scan_scheduler.h" +#include "chromeos/components/tether/host_scanner.h" +#include "chromeos/components/tether/keep_alive_scheduler.h" +#include "chromeos/components/tether/master_host_scan_cache.h" +#include "chromeos/components/tether/network_configuration_remover.h" +#include "chromeos/components/tether/network_connection_handler_tether_delegate.h" +#include "chromeos/components/tether/network_host_scan_cache.h" +#include "chromeos/components/tether/notification_presenter.h" +#include "chromeos/components/tether/notification_remover.h" +#include "chromeos/components/tether/persistent_host_scan_cache_impl.h" +#include "chromeos/components/tether/tether_connector.h" +#include "chromeos/components/tether/tether_disconnector_impl.h" +#include "chromeos/components/tether/tether_host_fetcher.h" +#include "chromeos/components/tether/tether_host_response_recorder.h" +#include "chromeos/components/tether/tether_network_disconnection_handler.h" +#include "chromeos/components/tether/timer_factory.h" +#include "chromeos/components/tether/wifi_hotspot_connector.h" +#include "chromeos/network/managed_network_configuration_handler.h" +#include "chromeos/network/network_connect.h" +#include "chromeos/network/network_connection_handler.h" +#include "chromeos/network/network_state_handler.h" +#include "components/cryptauth/bluetooth_throttler_impl.h" +#include "components/cryptauth/cryptauth_service.h" +#include "components/cryptauth/local_device_data_provider.h" +#include "components/cryptauth/remote_beacon_seed_fetcher.h" +#include "components/prefs/pref_service.h" +#include "components/proximity_auth/logging/logging.h" + +namespace chromeos { + +namespace tether { + +namespace { + +// TODO(lesliewatkins): Remove this and use the actual +// DisconnectTetheringRequestSender. +class DummyDisconnectTetheringRequestSender + : public DisconnectTetheringRequestSender { + public: + DummyDisconnectTetheringRequestSender() {} + ~DummyDisconnectTetheringRequestSender() override {} + + // DisconnectTetheringRequestSender: + void SendDisconnectRequestToDevice(const std::string& device_id) override {} + bool HasPendingRequests() override { return false; } +}; + +} // namespace + +// static +InitializerImpl::Factory* InitializerImpl::Factory::factory_instance_ = nullptr; + +// static +std::unique_ptr<Initializer> InitializerImpl::Factory::NewInstance( + cryptauth::CryptAuthService* cryptauth_service, + NotificationPresenter* notification_presenter, + PrefService* pref_service, + ProfileOAuth2TokenService* token_service, + NetworkStateHandler* network_state_handler, + ManagedNetworkConfigurationHandler* managed_network_configuration_handler, + NetworkConnect* network_connect, + NetworkConnectionHandler* network_connection_handler, + scoped_refptr<device::BluetoothAdapter> adapter) { + if (!factory_instance_) { + factory_instance_ = new Factory(); + } + return factory_instance_->BuildInstance( + cryptauth_service, notification_presenter, pref_service, token_service, + network_state_handler, managed_network_configuration_handler, + network_connect, network_connection_handler, adapter); +} + +// static +void InitializerImpl::Factory::SetInstanceForTesting(Factory* factory) { + factory_instance_ = factory; +} + +// static +void InitializerImpl::RegisterProfilePrefs(PrefRegistrySimple* registry) { + ActiveHost::RegisterPrefs(registry); + PersistentHostScanCacheImpl::RegisterPrefs(registry); + TetherHostResponseRecorder::RegisterPrefs(registry); + TetherDisconnectorImpl::RegisterPrefs(registry); +} + +std::unique_ptr<Initializer> InitializerImpl::Factory::BuildInstance( + cryptauth::CryptAuthService* cryptauth_service, + NotificationPresenter* notification_presenter, + PrefService* pref_service, + ProfileOAuth2TokenService* token_service, + NetworkStateHandler* network_state_handler, + ManagedNetworkConfigurationHandler* managed_network_configuration_handler, + NetworkConnect* network_connect, + NetworkConnectionHandler* network_connection_handler, + scoped_refptr<device::BluetoothAdapter> adapter) { + return base::WrapUnique(new InitializerImpl( + cryptauth_service, notification_presenter, pref_service, token_service, + network_state_handler, managed_network_configuration_handler, + network_connect, network_connection_handler, adapter)); +} + +InitializerImpl::InitializerImpl( + cryptauth::CryptAuthService* cryptauth_service, + NotificationPresenter* notification_presenter, + PrefService* pref_service, + ProfileOAuth2TokenService* token_service, + NetworkStateHandler* network_state_handler, + ManagedNetworkConfigurationHandler* managed_network_configuration_handler, + NetworkConnect* network_connect, + NetworkConnectionHandler* network_connection_handler, + scoped_refptr<device::BluetoothAdapter> adapter) + : cryptauth_service_(cryptauth_service), + notification_presenter_(notification_presenter), + pref_service_(pref_service), + token_service_(token_service), + network_state_handler_(network_state_handler), + managed_network_configuration_handler_( + managed_network_configuration_handler), + network_connect_(network_connect), + network_connection_handler_(network_connection_handler), + adapter_(adapter), + weak_ptr_factory_(this) { + if (!token_service_->RefreshTokenIsAvailable( + cryptauth_service_->GetAccountId())) { + PA_LOG(INFO) << "Refresh token not yet available; " + << "waiting for valid token to initializing tether feature."; + token_service_->AddObserver(this); + return; + } + + PA_LOG(INFO) << "Refresh token is available; initializing tether feature."; + CreateComponent(); +} + +InitializerImpl::~InitializerImpl() { + token_service_->RemoveObserver(this); + network_state_handler_->set_tether_sort_delegate(nullptr); + + if (disconnect_tethering_request_sender_) + disconnect_tethering_request_sender_->RemoveObserver(this); +} + +void InitializerImpl::RequestShutdown() { + DCHECK(status() == Initializer::Status::ACTIVE); + + if (!disconnect_tethering_request_sender_ || + !disconnect_tethering_request_sender_->HasPendingRequests()) { + TransitionToStatus(Initializer::Status::SHUT_DOWN); + return; + } + + TransitionToStatus(Initializer::Status::SHUTTING_DOWN); + StartAsynchronousShutdown(); +} + +void InitializerImpl::OnRefreshTokensLoaded() { + if (!token_service_->RefreshTokenIsAvailable( + cryptauth_service_->GetAccountId())) { + // If a token for the active account is still not available, continue + // waiting for a new token. + return; + } + + PA_LOG(INFO) << "Refresh token has loaded; initializing tether feature."; + + token_service_->RemoveObserver(this); + CreateComponent(); +} + +void InitializerImpl::OnPendingDisconnectRequestsComplete() { + DCHECK(status() == Initializer::Status::SHUTTING_DOWN); + disconnect_tethering_request_sender_->RemoveObserver(this); + + // Shutdown has completed. It is now safe to delete the objects that were + // shutting down asynchronously. + disconnect_tethering_request_sender_ = + base::MakeUnique<DummyDisconnectTetheringRequestSender>(); + ble_connection_manager_ = base::MakeUnique<BleConnectionManager>( + cryptauth_service_, adapter_, local_device_data_provider_.get(), + remote_beacon_seed_fetcher_.get(), + cryptauth::BluetoothThrottlerImpl::GetInstance()); + remote_beacon_seed_fetcher_ = + base::MakeUnique<cryptauth::RemoteBeaconSeedFetcher>( + cryptauth_service_->GetCryptAuthDeviceManager()); + local_device_data_provider_ = + base::MakeUnique<cryptauth::LocalDeviceDataProvider>(cryptauth_service_); + tether_host_fetcher_ = + base::MakeUnique<TetherHostFetcher>(cryptauth_service_); + + TransitionToStatus(Initializer::Status::SHUT_DOWN); +} + +void InitializerImpl::CreateComponent() { + PA_LOG(INFO) << "Successfully set Bluetooth advertisement interval. " + << "Initializing tether feature."; + + tether_host_fetcher_ = + base::MakeUnique<TetherHostFetcher>(cryptauth_service_); + local_device_data_provider_ = + base::MakeUnique<cryptauth::LocalDeviceDataProvider>(cryptauth_service_); + remote_beacon_seed_fetcher_ = + base::MakeUnique<cryptauth::RemoteBeaconSeedFetcher>( + cryptauth_service_->GetCryptAuthDeviceManager()); + ble_connection_manager_ = base::MakeUnique<BleConnectionManager>( + cryptauth_service_, adapter_, local_device_data_provider_.get(), + remote_beacon_seed_fetcher_.get(), + cryptauth::BluetoothThrottlerImpl::GetInstance()); + // TODO(lesliewatkins): Use actual DisconnectTetheringRequestSender. + disconnect_tethering_request_sender_ = + base::MakeUnique<DummyDisconnectTetheringRequestSender>(); + tether_host_response_recorder_ = + base::MakeUnique<TetherHostResponseRecorder>(pref_service_); + device_id_tether_network_guid_map_ = + base::MakeUnique<DeviceIdTetherNetworkGuidMap>(); + host_scan_device_prioritizer_ = + base::MakeUnique<HostScanDevicePrioritizerImpl>( + tether_host_response_recorder_.get(), + device_id_tether_network_guid_map_.get()); + network_state_handler_->set_tether_sort_delegate( + host_scan_device_prioritizer_.get()); + wifi_hotspot_connector_ = base::MakeUnique<WifiHotspotConnector>( + network_state_handler_, network_connect_); + active_host_ = + base::MakeUnique<ActiveHost>(tether_host_fetcher_.get(), pref_service_); + active_host_network_state_updater_ = + base::MakeUnique<ActiveHostNetworkStateUpdater>(active_host_.get(), + network_state_handler_); + persistent_host_scan_cache_ = + base::MakeUnique<PersistentHostScanCacheImpl>(pref_service_); + network_host_scan_cache_ = base::MakeUnique<NetworkHostScanCache>( + network_state_handler_, tether_host_response_recorder_.get(), + device_id_tether_network_guid_map_.get()); + master_host_scan_cache_ = base::MakeUnique<MasterHostScanCache>( + base::MakeUnique<TimerFactory>(), active_host_.get(), + network_host_scan_cache_.get(), persistent_host_scan_cache_.get()); + notification_remover_ = base::MakeUnique<NotificationRemover>( + network_state_handler_, notification_presenter_, + master_host_scan_cache_.get(), active_host_.get()); + keep_alive_scheduler_ = base::MakeUnique<KeepAliveScheduler>( + active_host_.get(), ble_connection_manager_.get(), + master_host_scan_cache_.get(), device_id_tether_network_guid_map_.get()); + clock_ = base::MakeUnique<base::DefaultClock>(); + host_scanner_ = base::MakeUnique<HostScanner>( + network_state_handler_, tether_host_fetcher_.get(), + ble_connection_manager_.get(), host_scan_device_prioritizer_.get(), + tether_host_response_recorder_.get(), notification_presenter_, + device_id_tether_network_guid_map_.get(), master_host_scan_cache_.get(), + clock_.get()); + host_scan_scheduler_ = base::MakeUnique<HostScanScheduler>( + network_state_handler_, host_scanner_.get()); + host_connection_metrics_logger_ = + base::MakeUnique<HostConnectionMetricsLogger>(); + tether_connector_ = base::MakeUnique<TetherConnector>( + network_state_handler_, wifi_hotspot_connector_.get(), active_host_.get(), + tether_host_fetcher_.get(), ble_connection_manager_.get(), + tether_host_response_recorder_.get(), + device_id_tether_network_guid_map_.get(), master_host_scan_cache_.get(), + notification_presenter_, host_connection_metrics_logger_.get()); + network_configuration_remover_ = + base::MakeUnique<NetworkConfigurationRemover>( + network_state_handler_, managed_network_configuration_handler_); + tether_disconnector_ = base::MakeUnique<TetherDisconnectorImpl>( + network_connection_handler_, network_state_handler_, active_host_.get(), + ble_connection_manager_.get(), network_configuration_remover_.get(), + tether_connector_.get(), device_id_tether_network_guid_map_.get(), + tether_host_fetcher_.get(), pref_service_); + tether_network_disconnection_handler_ = + base::MakeUnique<TetherNetworkDisconnectionHandler>( + active_host_.get(), network_state_handler_, + network_configuration_remover_.get()); + network_connection_handler_tether_delegate_ = + base::MakeUnique<NetworkConnectionHandlerTetherDelegate>( + network_connection_handler_, tether_connector_.get(), + tether_disconnector_.get()); + + crash_recovery_manager_ = base::MakeUnique<CrashRecoveryManager>( + network_state_handler_, active_host_.get(), + master_host_scan_cache_.get()); + crash_recovery_manager_->RestorePreCrashStateIfNecessary( + base::Bind(&InitializerImpl::OnPreCrashStateRestored, + weak_ptr_factory_.GetWeakPtr())); +} + +void InitializerImpl::OnPreCrashStateRestored() { + // |crash_recovery_manager_| is no longer needed since it has completed. + crash_recovery_manager_.reset(); + + // Start a scan now that the Tether module has started up. + host_scan_scheduler_->ScheduleScan(); +} + +void InitializerImpl::StartAsynchronousShutdown() { + DCHECK(status() == Initializer::Status::SHUTTING_DOWN); + DCHECK(disconnect_tethering_request_sender_->HasPendingRequests()); + + // Currently, the only task which needs to be performed asynchronously during + // shutdown is the DisconnectTetheringRequestSender. Observer this class so + // that when it finishes sending messages, Initializer can shut down. + disconnect_tethering_request_sender_->AddObserver(this); + + // All objects which are not dependencies of + // |disconnect_tethering_request_sender_| are + crash_recovery_manager_.reset(); + network_connection_handler_tether_delegate_.reset(); + tether_network_disconnection_handler_.reset(); + tether_disconnector_.reset(); + network_configuration_remover_.reset(); + tether_connector_.reset(); + host_connection_metrics_logger_.reset(); + host_scan_scheduler_.reset(); + host_scanner_.reset(); + clock_.reset(); + keep_alive_scheduler_.reset(); + notification_remover_.reset(); + master_host_scan_cache_.reset(); + network_host_scan_cache_.reset(); + persistent_host_scan_cache_.reset(); + active_host_network_state_updater_.reset(); + active_host_.reset(); + wifi_hotspot_connector_.reset(); + host_scan_device_prioritizer_.reset(); + device_id_tether_network_guid_map_.reset(); + tether_host_response_recorder_.reset(); +} + +} // namespace tether + +} // namespace chromeos
diff --git a/chromeos/components/tether/initializer_impl.h b/chromeos/components/tether/initializer_impl.h new file mode 100644 index 0000000..82235f1b --- /dev/null +++ b/chromeos/components/tether/initializer_impl.h
@@ -0,0 +1,188 @@ +// Copyright 2016 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 CHROMEOS_COMPONENTS_TETHER_INITIALIZER_IMPL_H_ +#define CHROMEOS_COMPONENTS_TETHER_INITIALIZER_IMPL_H_ + +#include <memory> + +#include "base/gtest_prod_util.h" +#include "base/macros.h" +#include "base/memory/ref_counted.h" +#include "base/memory/weak_ptr.h" +#include "base/time/default_clock.h" +#include "chromeos/components/tether/disconnect_tethering_request_sender.h" +#include "chromeos/components/tether/initializer.h" +#include "components/prefs/pref_registry_simple.h" +#include "components/signin/core/browser/profile_oauth2_token_service.h" +#include "device/bluetooth/bluetooth_adapter.h" +#include "device/bluetooth/bluetooth_advertisement.h" + +class PrefService; + +namespace cryptauth { +class CryptAuthService; +class LocalDeviceDataProvider; +class RemoteBeaconSeedFetcher; +} // namespace cryptauth + +namespace chromeos { + +class ManagedNetworkConfigurationHandler; +class NetworkConnect; +class NetworkConnectionHandler; +class NetworkStateHandler; + +namespace tether { + +class ActiveHost; +class ActiveHostNetworkStateUpdater; +class BleConnectionManager; +class CrashRecoveryManager; +class NetworkConnectionHandlerTetherDelegate; +class DeviceIdTetherNetworkGuidMap; +class HostScanner; +class HostScanScheduler; +class HostScanDevicePrioritizerImpl; +class KeepAliveScheduler; +class HostConnectionMetricsLogger; +class MasterHostScanCache; +class NetworkConfigurationRemover; +class NetworkHostScanCache; +class NotificationPresenter; +class NotificationRemover; +class PersistentHostScanCache; +class TetherConnector; +class TetherDisconnector; +class TetherHostFetcher; +class TetherHostResponseRecorder; +class TetherNetworkDisconnectionHandler; +class WifiHotspotConnector; + +// Initializes the Tether Chrome OS component. +class InitializerImpl : public Initializer, + public OAuth2TokenService::Observer, + public DisconnectTetheringRequestSender::Observer { + public: + static void RegisterProfilePrefs(PrefRegistrySimple* registry); + + class Factory { + public: + static std::unique_ptr<Initializer> NewInstance( + cryptauth::CryptAuthService* cryptauth_service, + NotificationPresenter* notification_presenter, + PrefService* pref_service, + ProfileOAuth2TokenService* token_service, + NetworkStateHandler* network_state_handler, + ManagedNetworkConfigurationHandler* + managed_network_configuration_handler, + NetworkConnect* network_connect, + NetworkConnectionHandler* network_connection_handler, + scoped_refptr<device::BluetoothAdapter> adapter); + + static void SetInstanceForTesting(Factory* factory); + + protected: + virtual std::unique_ptr<Initializer> BuildInstance( + cryptauth::CryptAuthService* cryptauth_service, + NotificationPresenter* notification_presenter, + PrefService* pref_service, + ProfileOAuth2TokenService* token_service, + NetworkStateHandler* network_state_handler, + ManagedNetworkConfigurationHandler* + managed_network_configuration_handler, + NetworkConnect* network_connect, + NetworkConnectionHandler* network_connection_handler, + scoped_refptr<device::BluetoothAdapter> adapter); + + private: + static Factory* factory_instance_; + }; + + InitializerImpl( + cryptauth::CryptAuthService* cryptauth_service, + NotificationPresenter* notification_presenter, + PrefService* pref_service, + ProfileOAuth2TokenService* token_service, + NetworkStateHandler* network_state_handler, + ManagedNetworkConfigurationHandler* managed_network_configuration_handler, + NetworkConnect* network_connect, + NetworkConnectionHandler* network_connection_handler, + scoped_refptr<device::BluetoothAdapter> adapter); + ~InitializerImpl() override; + + protected: + // Initializer: + void RequestShutdown() override; + + // OAuth2TokenService::Observer: + void OnRefreshTokensLoaded() override; + + // DisconnectTetheringRequestSender::Observer: + void OnPendingDisconnectRequestsComplete() override; + + private: + friend class InitializerImplTest; + + void CreateComponent(); + void OnPreCrashStateRestored(); + void StartAsynchronousShutdown(); + + cryptauth::CryptAuthService* cryptauth_service_; + NotificationPresenter* notification_presenter_; + PrefService* pref_service_; + ProfileOAuth2TokenService* token_service_; + NetworkStateHandler* network_state_handler_; + ManagedNetworkConfigurationHandler* managed_network_configuration_handler_; + NetworkConnect* network_connect_; + NetworkConnectionHandler* network_connection_handler_; + scoped_refptr<device::BluetoothAdapter> adapter_; + + // Declare new objects in the order that they will be created during + // initialization to ensure that they are destroyed in the correct order. This + // order will be enforced by InitializerTest.TestCreateAndDestroy. + std::unique_ptr<TetherHostFetcher> tether_host_fetcher_; + std::unique_ptr<cryptauth::LocalDeviceDataProvider> + local_device_data_provider_; + std::unique_ptr<cryptauth::RemoteBeaconSeedFetcher> + remote_beacon_seed_fetcher_; + std::unique_ptr<BleConnectionManager> ble_connection_manager_; + std::unique_ptr<DisconnectTetheringRequestSender> + disconnect_tethering_request_sender_; + std::unique_ptr<TetherHostResponseRecorder> tether_host_response_recorder_; + std::unique_ptr<DeviceIdTetherNetworkGuidMap> + device_id_tether_network_guid_map_; + std::unique_ptr<HostScanDevicePrioritizerImpl> host_scan_device_prioritizer_; + std::unique_ptr<WifiHotspotConnector> wifi_hotspot_connector_; + std::unique_ptr<ActiveHost> active_host_; + std::unique_ptr<ActiveHostNetworkStateUpdater> + active_host_network_state_updater_; + std::unique_ptr<PersistentHostScanCache> persistent_host_scan_cache_; + std::unique_ptr<NetworkHostScanCache> network_host_scan_cache_; + std::unique_ptr<MasterHostScanCache> master_host_scan_cache_; + std::unique_ptr<NotificationRemover> notification_remover_; + std::unique_ptr<KeepAliveScheduler> keep_alive_scheduler_; + std::unique_ptr<base::DefaultClock> clock_; + std::unique_ptr<HostScanner> host_scanner_; + std::unique_ptr<HostScanScheduler> host_scan_scheduler_; + std::unique_ptr<HostConnectionMetricsLogger> host_connection_metrics_logger_; + std::unique_ptr<TetherConnector> tether_connector_; + std::unique_ptr<NetworkConfigurationRemover> network_configuration_remover_; + std::unique_ptr<TetherDisconnector> tether_disconnector_; + std::unique_ptr<TetherNetworkDisconnectionHandler> + tether_network_disconnection_handler_; + std::unique_ptr<NetworkConnectionHandlerTetherDelegate> + network_connection_handler_tether_delegate_; + std::unique_ptr<CrashRecoveryManager> crash_recovery_manager_; + + base::WeakPtrFactory<InitializerImpl> weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(InitializerImpl); +}; + +} // namespace tether + +} // namespace chromeos + +#endif // CHROMEOS_COMPONENTS_TETHER_INITIALIZER_IMPL_H_
diff --git a/chromeos/components/tether/initializer_unittest.cc b/chromeos/components/tether/initializer_impl_unittest.cc similarity index 97% rename from chromeos/components/tether/initializer_unittest.cc rename to chromeos/components/tether/initializer_impl_unittest.cc index ae8266bb6..c683af9 100644 --- a/chromeos/components/tether/initializer_unittest.cc +++ b/chromeos/components/tether/initializer_impl_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 "chromeos/components/tether/initializer.h" +#include "chromeos/components/tether/initializer_impl.h" #include <memory> @@ -129,7 +129,7 @@ NetworkStateHandler::TECHNOLOGY_ENABLED); test_pref_service_ = base::MakeUnique<TestingPrefServiceSimple>(); - Initializer::RegisterProfilePrefs(test_pref_service_->registry()); + InitializerImpl::RegisterProfilePrefs(test_pref_service_->registry()); } void TearDown() override { @@ -148,7 +148,7 @@ NetworkConnect* network_connect, NetworkConnectionHandler* network_connection_handler, scoped_refptr<device::BluetoothAdapter> adapter) { - Initializer* initializer = new Initializer( + Initializer* initializer = new InitializerImpl( cryptauth_service, notification_presenter, pref_service, token_service, network_state_handler, managed_network_configuration_handler, network_connect, network_connection_handler, adapter);
diff --git a/components/crash/content/browser/child_process_crash_observer_android.cc b/components/crash/content/browser/child_process_crash_observer_android.cc index b59a0dd..ca3fb794 100644 --- a/components/crash/content/browser/child_process_crash_observer_android.cc +++ b/components/crash/content/browser/child_process_crash_observer_android.cc
@@ -6,6 +6,7 @@ #include "base/bind.h" #include "base/files/file_util.h" +#include "base/task_runner_util.h" #include "base/task_scheduler/post_task.h" #include "components/crash/content/app/breakpad_linux.h" #include "components/crash/content/browser/crash_dump_manager_android.h" @@ -14,8 +15,18 @@ ChildProcessCrashObserver::ChildProcessCrashObserver( const base::FilePath crash_dump_dir, - int descriptor_id) - : crash_dump_dir_(crash_dump_dir), descriptor_id_(descriptor_id) {} + int descriptor_id, + const base::Closure& increase_crash_cb) + : crash_dump_dir_(crash_dump_dir), + descriptor_id_(descriptor_id), + increase_crash_cb_(base::Bind( + [](base::Closure cb, bool run_cb) { + if (run_cb) + cb.Run(); + }, + increase_crash_cb)), + background_task_runner_(base::CreateSequencedTaskRunnerWithTraits( + {base::MayBlock(), base::TaskPriority::BACKGROUND})) {} ChildProcessCrashObserver::~ChildProcessCrashObserver() {} @@ -41,12 +52,14 @@ // This might be called twice for a given child process, with a // NOTIFICATION_RENDERER_PROCESS_TERMINATED and then with // NOTIFICATION_RENDERER_PROCESS_CLOSED. - base::PostTaskWithTraits( - FROM_HERE, {base::MayBlock(), base::TaskPriority::BACKGROUND}, + + base::PostTaskAndReplyWithResult( + background_task_runner_.get(), FROM_HERE, base::Bind(&CrashDumpManager::ProcessMinidumpFileFromChild, base::Unretained(CrashDumpManager::GetInstance()), crash_dump_dir_, child_process_id, process_type, - termination_status, app_state)); + termination_status, app_state), + increase_crash_cb_); } } // namespace breakpad
diff --git a/components/crash/content/browser/child_process_crash_observer_android.h b/components/crash/content/browser/child_process_crash_observer_android.h index fad32f2..76a4fdb2 100644 --- a/components/crash/content/browser/child_process_crash_observer_android.h +++ b/components/crash/content/browser/child_process_crash_observer_android.h
@@ -6,14 +6,19 @@ #define COMPONENTS_CRASH_CONTENT_BROWSER_CHILD_PROCESS_CRASH_OBSERVER_ANDROID_H_ #include "base/files/file_path.h" +#include "base/sequenced_task_runner.h" #include "components/crash/content/browser/crash_dump_observer_android.h" namespace breakpad { class ChildProcessCrashObserver : public breakpad::CrashDumpObserver::Client { public: + // |increase_crash_cb is| the callback to run after processing minidump file. + // For now this callback is used to increase render crash counter based on + // processing minidump result. ChildProcessCrashObserver(const base::FilePath crash_dump_dir, - int descriptor_id); + int descriptor_id, + const base::Closure& increase_crash_cb); ~ChildProcessCrashObserver() override; // breakpad::CrashDumpObserver::Client implementation: @@ -31,6 +36,10 @@ // descriptor mappings passed to the child process. int descriptor_id_; + base::Callback<void(bool)> increase_crash_cb_; + + scoped_refptr<base::SequencedTaskRunner> background_task_runner_; + DISALLOW_COPY_AND_ASSIGN(ChildProcessCrashObserver); };
diff --git a/components/crash/content/browser/crash_dump_manager_android.cc b/components/crash/content/browser/crash_dump_manager_android.cc index d7cadd74..6d204696 100644 --- a/components/crash/content/browser/crash_dump_manager_android.cc +++ b/components/crash/content/browser/crash_dump_manager_android.cc
@@ -60,18 +60,19 @@ return base::ScopedFD(minidump_file.TakePlatformFile()); } -void CrashDumpManager::ProcessMinidumpFileFromChild( +bool CrashDumpManager::ProcessMinidumpFileFromChild( base::FilePath crash_dump_dir, base::ProcessHandle pid, content::ProcessType process_type, base::TerminationStatus termination_status, base::android::ApplicationState app_state) { base::ThreadRestrictions::AssertIOAllowed(); + bool increase_crash_count = false; base::FilePath minidump_path; // If the minidump for a given child process has already been // processed, then there is no more work to do. if (!GetMinidumpPath(pid, &minidump_path)) - return; + return increase_crash_count; int64_t file_size = 0; int r = base::GetFileSize(minidump_path, &file_size); @@ -108,6 +109,9 @@ } if (process_type == content::PROCESS_TYPE_RENDERER) { if (termination_status == base::TERMINATION_STATUS_OOM_PROTECTED) { + // There is a delay for OOM flag to be removed when app goes to + // background, so we can't just check for OOM_PROTECTED flag. + increase_crash_count = is_running || is_paused; UMA_HISTOGRAM_ENUMERATION("Tab.RendererDetailedExitStatus", exit_status, ExitStatus::MINIDUMP_STATUS_COUNT); @@ -128,14 +132,14 @@ r = base::DeleteFile(minidump_path, false); DCHECK(r) << "Failed to delete temporary minidump file " << minidump_path.value(); - return; + return increase_crash_count; } // We are dealing with a valid minidump. Copy it to the crash report // directory from where Java code will upload it later on. if (crash_dump_dir.empty()) { NOTREACHED() << "Failed to retrieve the crash dump directory."; - return; + return increase_crash_count; } const uint64_t rand = base::RandUint64(); const std::string filename = @@ -147,7 +151,7 @@ LOG(ERROR) << "Failed to move crash dump from " << minidump_path.value() << " to " << dest_path.value(); base::DeleteFile(minidump_path, false); - return; + return increase_crash_count; } VLOG(1) << "Crash minidump successfully generated: " << dest_path.value(); @@ -158,6 +162,7 @@ base::android::ScopedJavaLocalRef<jstring> j_dest_path = base::android::ConvertUTF8ToJavaString(env, dest_path.value()); Java_CrashDumpManager_tryToUploadMinidump(env, j_dest_path); + return increase_crash_count; } void CrashDumpManager::SetMinidumpPath(int child_process_id,
diff --git a/components/crash/content/browser/crash_dump_manager_android.h b/components/crash/content/browser/crash_dump_manager_android.h index 6aa5885..5c54c38 100644 --- a/components/crash/content/browser/crash_dump_manager_android.h +++ b/components/crash/content/browser/crash_dump_manager_android.h
@@ -31,7 +31,8 @@ public: static CrashDumpManager* GetInstance(); - void ProcessMinidumpFileFromChild(base::FilePath crash_dump_dir, + // Returns the condition whether we should write the crash to stability proto. + bool ProcessMinidumpFileFromChild(base::FilePath crash_dump_dir, base::ProcessHandle pid, content::ProcessType process_type, base::TerminationStatus termination_status,
diff --git a/components/metrics/BUILD.gn b/components/metrics/BUILD.gn index 8dd663c..faf3387 100644 --- a/components/metrics/BUILD.gn +++ b/components/metrics/BUILD.gn
@@ -109,6 +109,7 @@ "//components/prefs", "//components/variations", "//components/version_info:version_info", + "//extensions/features:features", "//third_party/zlib/google:compression_utils", ] @@ -409,6 +410,7 @@ "//components/metrics/public/cpp:call_stack_unit_tests", "//components/prefs:test_support", "//components/variations", + "//extensions/features:features", "//mojo/public/cpp/bindings", "//net:test_support", "//services/service_manager/public/cpp",
diff --git a/components/metrics/DEPS b/components/metrics/DEPS index bd7bd415..711120e 100644 --- a/components/metrics/DEPS +++ b/components/metrics/DEPS
@@ -10,6 +10,7 @@ "+components/variations", "+components/version_info", "+content/public/test", + "+extensions/features", "+mojo/public/cpp", "+services/service_manager/public/cpp", "+third_party/zlib/google",
diff --git a/components/metrics/stability_metrics_helper.cc b/components/metrics/stability_metrics_helper.cc index 1ba27b9..cf54081 100644 --- a/components/metrics/stability_metrics_helper.cc +++ b/components/metrics/stability_metrics_helper.cc
@@ -13,10 +13,12 @@ #include "base/metrics/sparse_histogram.h" #include "base/metrics/user_metrics.h" #include "build/build_config.h" +#include "build/buildflag.h" #include "components/metrics/metrics_pref_names.h" #include "components/metrics/proto/system_profile.pb.h" #include "components/prefs/pref_registry_simple.h" #include "components/prefs/pref_service.h" +#include "extensions/features/features.h" #if defined(OS_WIN) #include <windows.h> // Needed for STATUS_* codes @@ -164,6 +166,14 @@ registry->RegisterInt64Pref(prefs::kUninstallMetricsPageLoadCount, 0); } +// static +void StabilityMetricsHelper::IncreaseRendererCrashCount( + PrefService* local_state) { + // It doesn't use IncrementPrefValue() because the function is static. + int value = local_state->GetInteger(prefs::kStabilityRendererCrashCount); + local_state->SetInteger(prefs::kStabilityRendererCrashCount, value + 1); +} + void StabilityMetricsHelper::BrowserChildProcessCrashed() { IncrementPrefValue(prefs::kStabilityChildProcessCrashCount); } @@ -189,6 +199,9 @@ case base::TERMINATION_STATUS_ABNORMAL_TERMINATION: case base::TERMINATION_STATUS_OOM: if (was_extension_process) { +#if !BUILDFLAG(ENABLE_EXTENSIONS) + NOTREACHED(); +#endif IncrementPrefValue(prefs::kStabilityExtensionRendererCrashCount); UMA_HISTOGRAM_SPARSE_SLOWLY("CrashExitCodes.Extension",
diff --git a/components/metrics/stability_metrics_helper.h b/components/metrics/stability_metrics_helper.h index bc9aaed0..a67dad2 100644 --- a/components/metrics/stability_metrics_helper.h +++ b/components/metrics/stability_metrics_helper.h
@@ -48,11 +48,14 @@ // Registers local state prefs used by this class. static void RegisterPrefs(PrefRegistrySimple* registry); + // Increments the RendererCrash pref. + static void IncreaseRendererCrashCount(PrefService* local_state); + private: - // Increment an Integer pref value specified by |path|. + // Increments an Integer pref value specified by |path|. void IncrementPrefValue(const char* path); - // Increment a 64-bit Integer pref value specified by |path|. + // Increments a 64-bit Integer pref value specified by |path|. void IncrementLongPrefsValue(const char* path); PrefService* local_state_;
diff --git a/components/metrics/stability_metrics_helper_unittest.cc b/components/metrics/stability_metrics_helper_unittest.cc index 018906d..edc9aaa 100644 --- a/components/metrics/stability_metrics_helper_unittest.cc +++ b/components/metrics/stability_metrics_helper_unittest.cc
@@ -6,10 +6,12 @@ #include "base/macros.h" #include "base/test/histogram_tester.h" +#include "build/build_config.h" #include "components/metrics/proto/system_profile.pb.h" #include "components/prefs/pref_service.h" #include "components/prefs/scoped_user_pref_update.h" #include "components/prefs/testing_pref_service.h" +#include "extensions/features/features.h" #include "testing/gtest/include/gtest/gtest.h" namespace metrics { @@ -90,7 +92,29 @@ EXPECT_EQ(1, system_profile.stability().renderer_failed_launch_count()); EXPECT_EQ(0, system_profile.stability().extension_renderer_crash_count()); - helper.ClearSavedStabilityMetrics(); + histogram_tester.ExpectUniqueSample("CrashExitCodes.Renderer", 1, 3); + histogram_tester.ExpectBucketCount("BrowserRenderProcessHost.ChildCrashes", + RENDERER_TYPE_RENDERER, 3); + + // One launch failure each. + histogram_tester.ExpectBucketCount( + "BrowserRenderProcessHost.ChildLaunchFailures", RENDERER_TYPE_RENDERER, + 1); + + // TERMINATION_STATUS_PROCESS_WAS_KILLED for a renderer. + histogram_tester.ExpectBucketCount("BrowserRenderProcessHost.ChildKills", + RENDERER_TYPE_RENDERER, 1); + histogram_tester.ExpectBucketCount("BrowserRenderProcessHost.ChildKills", + RENDERER_TYPE_EXTENSION, 0); + histogram_tester.ExpectBucketCount( + "BrowserRenderProcessHost.ChildLaunchFailureCodes", 1, 1); +} + +// Note: ENABLE_EXTENSIONS is set to false in Android +#if BUILDFLAG(ENABLE_EXTENSIONS) +TEST_F(StabilityMetricsHelperTest, LogRendererCrashEnableExtensions) { + StabilityMetricsHelper helper(prefs()); + base::HistogramTester histogram_tester; // Crash and abnormal termination should increment extension crash count. helper.LogRendererCrash(true, base::TERMINATION_STATUS_PROCESS_CRASHED, 1); @@ -101,7 +125,7 @@ // Failed launch increments extension failed launch count. helper.LogRendererCrash(true, base::TERMINATION_STATUS_LAUNCH_FAILED, 1); - system_profile.Clear(); + metrics::SystemProfileProto system_profile; helper.ProvideStabilityMetrics(&system_profile); EXPECT_EQ(0, system_profile.stability().renderer_crash_count()); @@ -109,32 +133,15 @@ EXPECT_EQ( 1, system_profile.stability().extension_renderer_failed_launch_count()); - // TERMINATION_STATUS_PROCESS_CRASHED, TERMINATION_STATUS_ABNORMAL_TERMINATION - // and TERMINATION_STATUS_OOM = 3. - histogram_tester.ExpectUniqueSample("CrashExitCodes.Renderer", 1, 3); - histogram_tester.ExpectBucketCount("BrowserRenderProcessHost.ChildCrashes", - RENDERER_TYPE_RENDERER, 3); - - // TERMINATION_STATUS_PROCESS_CRASHED and TERMINATION_STATUS_OOM = 2. + histogram_tester.ExpectBucketCount( + "BrowserRenderProcessHost.ChildLaunchFailureCodes", 1, 1); histogram_tester.ExpectUniqueSample("CrashExitCodes.Extension", 1, 2); histogram_tester.ExpectBucketCount("BrowserRenderProcessHost.ChildCrashes", RENDERER_TYPE_EXTENSION, 2); - - // One launch failure each. - histogram_tester.ExpectBucketCount( - "BrowserRenderProcessHost.ChildLaunchFailures", RENDERER_TYPE_RENDERER, - 1); histogram_tester.ExpectBucketCount( "BrowserRenderProcessHost.ChildLaunchFailures", RENDERER_TYPE_EXTENSION, 1); - histogram_tester.ExpectBucketCount( - "BrowserRenderProcessHost.ChildLaunchFailureCodes", 1, 2); - - // TERMINATION_STATUS_PROCESS_WAS_KILLED for a renderer. - histogram_tester.ExpectBucketCount("BrowserRenderProcessHost.ChildKills", - RENDERER_TYPE_RENDERER, 1); - histogram_tester.ExpectBucketCount("BrowserRenderProcessHost.ChildKills", - RENDERER_TYPE_EXTENSION, 0); } +#endif } // namespace metrics
diff --git a/components/url_formatter/url_formatter.cc b/components/url_formatter/url_formatter.cc index abfb716f..bad3a45a 100644 --- a/components/url_formatter/url_formatter.cc +++ b/components/url_formatter/url_formatter.cc
@@ -68,7 +68,7 @@ std::string domain_and_registry = net::registry_controlled_domains::GetDomainAndRegistry( component_text, - net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES); + net::registry_controlled_domains::EXCLUDE_PRIVATE_REGISTRIES); base::OffsetAdjuster::Adjustments trivial_subdomains_adjustments; base::StringTokenizer tokenizer(
diff --git a/components/url_formatter/url_formatter_unittest.cc b/components/url_formatter/url_formatter_unittest.cc index 6cc9b19..f08a17b3 100644 --- a/components/url_formatter/url_formatter_unittest.cc +++ b/components/url_formatter/url_formatter_unittest.cc
@@ -950,6 +950,9 @@ "http://en.m.wikipedia.org/", kFormatUrlExperimentalOmitTrivialSubdomains, net::UnescapeRule::NORMAL, L"http://en.wikipedia.org/", 7}, + {"omit trivial subdomains - exclude private registries", + "http://www.blogspot.com/", kFormatUrlExperimentalOmitTrivialSubdomains, + net::UnescapeRule::NORMAL, L"http://blogspot.com/", 7}, {"omit trivial subdomains - don't do blind substring matches for www", "http://wwww.google.com/", kFormatUrlExperimentalOmitTrivialSubdomains, net::UnescapeRule::NORMAL, L"http://wwww.google.com/", 7},
diff --git a/content/browser/browser_main_loop.cc b/content/browser/browser_main_loop.cc index ebf10e6..d2f4f26 100644 --- a/content/browser/browser_main_loop.cc +++ b/content/browser/browser_main_loop.cc
@@ -479,7 +479,7 @@ } // namespace -#if defined(USE_X11) && !defined(OS_CHROMEOS) +#if defined(USE_X11) namespace internal { // Forwards GPUInfo updates to ui::XVisualManager @@ -883,7 +883,7 @@ GpuDataManagerImpl* gpu_data_manager = GpuDataManagerImpl::GetInstance(); -#if defined(USE_X11) && !defined(OS_CHROMEOS) +#if defined(USE_X11) // GpuDataManagerVisualProxy() just adds itself as an observer of // |gpu_data_manager|, which is safe to do before Initialize(). gpu_data_manager_visual_proxy_.reset(
diff --git a/content/browser/browser_main_loop.h b/content/browser/browser_main_loop.h index 1afdc00..d341e72d 100644 --- a/content/browser/browser_main_loop.h +++ b/content/browser/browser_main_loop.h
@@ -105,7 +105,7 @@ class ScreenOrientationDelegate; #endif -#if defined(USE_X11) && !defined(OS_CHROMEOS) +#if defined(USE_X11) namespace internal { class GpuDataManagerVisualProxy; } @@ -303,7 +303,7 @@ // Torn down in ShutdownThreadsAndCleanUp. std::unique_ptr<base::MemoryPressureMonitor> memory_pressure_monitor_; std::unique_ptr<SwapMetricsDriver> swap_metrics_driver_; -#if defined(USE_X11) && !(OS_CHROMEOS) +#if defined(USE_X11) std::unique_ptr<internal::GpuDataManagerVisualProxy> gpu_data_manager_visual_proxy_; #endif
diff --git a/content/browser/download/download_manager_impl.cc b/content/browser/download/download_manager_impl.cc index 0abd4a0f..4722f36 100644 --- a/content/browser/download/download_manager_impl.cc +++ b/content/browser/download/download_manager_impl.cc
@@ -61,7 +61,7 @@ #include "storage/browser/blob/blob_url_request_job_factory.h" #include "url/origin.h" -#if defined(USE_X11) && !defined(OS_CHROMEOS) +#if defined(USE_X11) #include "base/nix/xdg_util.h" #endif @@ -219,7 +219,7 @@ } }; -#if defined(USE_X11) && !defined(OS_CHROMEOS) +#if defined(USE_X11) base::FilePath GetTemporaryDownloadDirectory() { std::unique_ptr<base::Environment> env(base::Environment::Create()); return base::nix::GetXDGDirectory(env.get(), "XDG_DATA_HOME", ".local/share"); @@ -410,7 +410,7 @@ } base::FilePath default_download_directory; -#if defined(USE_X11) && !defined(OS_CHROMEOS) +#if defined(USE_X11) // TODO(thomasanderson): Remove this when all Linux distros with // versions of GTK lower than 3.14.7 are no longer supported. This // should happen when support for Ubuntu Trusty and Debian Jessie
diff --git a/content/browser/download/download_manager_impl_unittest.cc b/content/browser/download/download_manager_impl_unittest.cc index ab96db1..0aedd18 100644 --- a/content/browser/download/download_manager_impl_unittest.cc +++ b/content/browser/download/download_manager_impl_unittest.cc
@@ -547,7 +547,7 @@ EXPECT_CALL(GetMockDownloadManagerDelegate(), GetNextId(_)) .WillOnce(RunCallback<0>(local_id)); -#if !defined(USE_X11) || defined(OS_CHROMEOS) +#if !defined(USE_X11) // Doing nothing will set the default download directory to null. EXPECT_CALL(GetMockDownloadManagerDelegate(), GetSaveDir(_, _, _, _)); #endif
diff --git a/content/browser/frame_host/navigation_request.cc b/content/browser/frame_host/navigation_request.cc index ee72196..279dcd5 100644 --- a/content/browser/frame_host/navigation_request.cc +++ b/content/browser/frame_host/navigation_request.cc
@@ -7,6 +7,7 @@ #include <utility> #include "base/memory/ptr_util.h" +#include "base/optional.h" #include "base/strings/string_util.h" #include "content/browser/appcache/appcache_navigation_handle.h" #include "content/browser/appcache/chrome_appcache_service.h" @@ -424,7 +425,7 @@ // Create a navigation handle so that the correct error code can be set on // it by OnRequestFailed(). CreateNavigationHandle(); - OnRequestFailed(false, net::ERR_BLOCKED_BY_CLIENT); + OnRequestFailed(false, net::ERR_BLOCKED_BY_CLIENT, base::nullopt, false); // DO NOT ADD CODE after this. The previous call to OnRequestFailed has // destroyed the NavigationRequest. @@ -438,7 +439,7 @@ // Create a navigation handle so that the correct error code can be set on // it by OnRequestFailed(). CreateNavigationHandle(); - OnRequestFailed(false, net::ERR_ABORTED); + OnRequestFailed(false, net::ERR_ABORTED, base::nullopt, false); // DO NOT ADD CODE after this. The previous call to OnRequestFailed has // destroyed the NavigationRequest. @@ -597,7 +598,7 @@ // otherwise block. if (CheckContentSecurityPolicyFrameSrc(true /* is redirect */) == CONTENT_SECURITY_POLICY_CHECK_FAILED) { - OnRequestFailed(false, net::ERR_BLOCKED_BY_CLIENT); + OnRequestFailed(false, net::ERR_BLOCKED_BY_CLIENT, base::nullopt, false); // DO NOT ADD CODE after this. The previous call to OnRequestFailed has // destroyed the NavigationRequest. @@ -608,7 +609,7 @@ CredentialedSubresourceCheckResult::BLOCK_REQUEST || CheckLegacyProtocolInSubresource() == LegacyProtocolInSubresourceCheckResult::BLOCK_REQUEST) { - OnRequestFailed(false, net::ERR_ABORTED); + OnRequestFailed(false, net::ERR_ABORTED, base::nullopt, false); // DO NOT ADD CODE after this. The previous call to OnRequestFailed has // destroyed the NavigationRequest. @@ -740,9 +741,15 @@ base::Unretained(this))); } -void NavigationRequest::OnRequestFailed(bool has_stale_copy_in_cache, - int net_error) { +// TODO(crbug.com/751941): Pass certificate_error_info to navigation throttles. +void NavigationRequest::OnRequestFailed( + bool has_stale_copy_in_cache, + int net_error, + const base::Optional<net::SSLInfo>& ssl_info, + bool should_ssl_errors_be_fatal) { DCHECK(state_ == STARTED || state_ == RESPONSE_STARTED); + // TODO(https://crbug.com/757633): Check that ssl_info.has_value() if + // net_error is a certificate error. TRACE_EVENT_ASYNC_STEP_INTO1("navigation", "NavigationRequest", this, "OnRequestFailed", "error", net_error); state_ = FAILED; @@ -838,10 +845,10 @@ // is no onbeforeunload handler or if a NavigationThrottle cancelled it, // then this could cause reentrancy into NavigationController. So use a // PostTask to avoid that. - BrowserThread::PostTask( - BrowserThread::UI, FROM_HERE, - base::BindOnce(&NavigationRequest::OnRequestFailed, - weak_factory_.GetWeakPtr(), false, error_code)); + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, + base::BindOnce(&NavigationRequest::OnRequestFailed, + weak_factory_.GetWeakPtr(), false, + error_code, base::nullopt, false)); // DO NOT ADD CODE after this. The previous call to OnRequestFailed has // destroyed the NavigationRequest. @@ -936,7 +943,7 @@ if (result == NavigationThrottle::CANCEL_AND_IGNORE || result == NavigationThrottle::CANCEL) { // TODO(clamy): distinguish between CANCEL and CANCEL_AND_IGNORE if needed. - OnRequestFailed(false, net::ERR_ABORTED); + OnRequestFailed(false, net::ERR_ABORTED, base::nullopt, false); // DO NOT ADD CODE after this. The previous call to OnRequestFailed has // destroyed the NavigationRequest. @@ -945,7 +952,7 @@ if (result == NavigationThrottle::BLOCK_REQUEST || result == NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE) { - OnRequestFailed(false, net::ERR_BLOCKED_BY_CLIENT); + OnRequestFailed(false, net::ERR_BLOCKED_BY_CLIENT, base::nullopt, false); // DO NOT ADD CODE after this. The previous call to OnRequestFailed has // destroyed the NavigationRequest. return; @@ -969,7 +976,7 @@ if (result == NavigationThrottle::CANCEL_AND_IGNORE || result == NavigationThrottle::CANCEL || !response_should_be_rendered_) { // TODO(clamy): distinguish between CANCEL and CANCEL_AND_IGNORE. - OnRequestFailed(false, net::ERR_ABORTED); + OnRequestFailed(false, net::ERR_ABORTED, base::nullopt, false); // DO NOT ADD CODE after this. The previous call to OnRequestFailed has // destroyed the NavigationRequest. @@ -977,7 +984,7 @@ } if (result == NavigationThrottle::BLOCK_RESPONSE) { - OnRequestFailed(false, net::ERR_BLOCKED_BY_RESPONSE); + OnRequestFailed(false, net::ERR_BLOCKED_BY_RESPONSE, base::nullopt, false); // DO NOT ADD CODE after this. The previous call to OnRequestFailed has // destroyed the NavigationRequest. return;
diff --git a/content/browser/frame_host/navigation_request.h b/content/browser/frame_host/navigation_request.h index 53971d2..82cbaf5 100644 --- a/content/browser/frame_host/navigation_request.h +++ b/content/browser/frame_host/navigation_request.h
@@ -209,7 +209,10 @@ bool is_stream, mojom::URLLoaderFactoryPtrInfo subresource_url_loader_factory_info) override; - void OnRequestFailed(bool has_stale_copy_in_cache, int net_error) override; + void OnRequestFailed(bool has_stale_copy_in_cache, + int net_error, + const base::Optional<net::SSLInfo>& ssl_info, + bool should_ssl_errors_be_fatal) override; void OnRequestStarted(base::TimeTicks timestamp) override; // Called when the NavigationThrottles have been checked by the
diff --git a/content/browser/gpu/gpu_internals_ui.cc b/content/browser/gpu/gpu_internals_ui.cc index cdb4a406..2d46fc8d 100644 --- a/content/browser/gpu/gpu_internals_ui.cc +++ b/content/browser/gpu/gpu_internals_ui.cc
@@ -249,7 +249,7 @@ info->Set("diagnostics", std::move(dx_info)); #endif -#if defined(USE_X11) && !defined(OS_CHROMEOS) +#if defined(USE_X11) basic_info->Append(NewDescriptionValuePair( "System visual ID", base::Uint64ToString(gpu_info.system_visual))); basic_info->Append(NewDescriptionValuePair(
diff --git a/content/browser/gpu/gpu_process_host.cc b/content/browser/gpu/gpu_process_host.cc index e1a3860..40ffc80 100644 --- a/content/browser/gpu/gpu_process_host.cc +++ b/content/browser/gpu/gpu_process_host.cc
@@ -91,7 +91,7 @@ #include "ui/ozone/public/ozone_switches.h" #endif -#if defined(USE_X11) && !defined(OS_CHROMEOS) +#if defined(USE_X11) #include "ui/gfx/x/x11_switches.h" // nogncheck #endif @@ -163,7 +163,7 @@ #if defined(USE_OZONE) switches::kOzonePlatform, #endif -#if defined(USE_X11) && !defined(OS_CHROMEOS) +#if defined(USE_X11) switches::kX11Display, #endif switches::kGpuTestingGLVendor,
diff --git a/content/browser/loader/navigation_resource_handler.cc b/content/browser/loader/navigation_resource_handler.cc index c6f84ef..4a522b1 100644 --- a/content/browser/loader/navigation_resource_handler.cc +++ b/content/browser/loader/navigation_resource_handler.cc
@@ -8,6 +8,7 @@ #include "base/bind.h" #include "base/logging.h" +#include "base/optional.h" #include "content/browser/loader/navigation_url_loader_impl_core.h" #include "content/browser/loader/resource_controller.h" #include "content/browser/loader/resource_loader.h" @@ -21,7 +22,23 @@ #include "content/public/browser/stream_handle.h" #include "content/public/common/resource_response.h" #include "net/base/net_errors.h" +#include "net/http/transport_security_state.h" +#include "net/ssl/ssl_info.h" #include "net/url_request/url_request.h" +#include "net/url_request/url_request_context.h" +#include "url/gurl.h" + +namespace { + +// TODO(crbug.com/757633): Attach this information to net::SSLInfo instead of +// calculating it here. +bool ShouldSSLErrorsBeFatal(net::URLRequest* request) { + net::TransportSecurityState* state = + request->context()->transport_security_state(); + return state->ShouldSSLErrorsBeFatal(request->url().host()); +} + +} // namespace namespace content { @@ -47,7 +64,7 @@ NavigationResourceHandler::~NavigationResourceHandler() { if (core_) { - core_->NotifyRequestFailed(false, net::ERR_ABORTED); + core_->NotifyRequestFailed(false, net::ERR_ABORTED, base::nullopt, false); DetachFromCore(); } } @@ -144,9 +161,16 @@ const net::URLRequestStatus& status, std::unique_ptr<ResourceController> controller) { if (core_) { - DCHECK_NE(net::OK, status.error()); - core_->NotifyRequestFailed(request()->response_info().was_cached, - status.error()); + int net_error = status.error(); + DCHECK_NE(net::OK, net_error); + + base::Optional<net::SSLInfo> ssl_info; + if (net::IsCertStatusError(request()->ssl_info().cert_status)) { + ssl_info = request()->ssl_info(); + } + + core_->NotifyRequestFailed(request()->response_info().was_cached, net_error, + ssl_info, ShouldSSLErrorsBeFatal(request())); DetachFromCore(); } next_handler_->OnResponseCompleted(status, std::move(controller));
diff --git a/content/browser/loader/navigation_url_loader_delegate.h b/content/browser/loader/navigation_url_loader_delegate.h index 34723cf..2dbb64f 100644 --- a/content/browser/loader/navigation_url_loader_delegate.h +++ b/content/browser/loader/navigation_url_loader_delegate.h
@@ -15,6 +15,7 @@ namespace net { struct RedirectInfo; +class SSLInfo; } namespace content { @@ -55,8 +56,18 @@ // Called if the request fails before receving a response. |net_error| is a // network error code for the failure. |has_stale_copy_in_cache| is true if - // there is a stale copy of the unreachable page in cache. - virtual void OnRequestFailed(bool has_stale_copy_in_cache, int net_error) = 0; + // there is a stale copy of the unreachable page in cache. |ssl_info| is the + // SSL info for the request. |should_ssl_errors_be_fatal| indicates + // whether SSL errors for the request should be fatal. + // If |net_error| is a certificate error, the caller should pass a value for + // |ssl_info|. If |net_error| is not a certificate error, |ssl_info| and + // |fatal_cert_error| are ignored. + // TODO(https://crbug.com/757633): Change "should pass a value for |ssl_info|" + // to "must pass..." + virtual void OnRequestFailed(bool has_stale_copy_in_cache, + int net_error, + const base::Optional<net::SSLInfo>& ssl_info, + bool should_ssl_errors_be_fatal) = 0; // Called after the network request has begun on the IO thread at time // |timestamp|. This is just a thread hop but is used to compare timing
diff --git a/content/browser/loader/navigation_url_loader_impl.cc b/content/browser/loader/navigation_url_loader_impl.cc index 556294f..6371909 100644 --- a/content/browser/loader/navigation_url_loader_impl.cc +++ b/content/browser/loader/navigation_url_loader_impl.cc
@@ -8,6 +8,7 @@ #include "base/bind.h" #include "base/location.h" +#include "base/optional.h" #include "base/trace_event/trace_event.h" #include "content/browser/appcache/appcache_navigation_handle.h" #include "content/browser/appcache/appcache_navigation_handle_core.h" @@ -107,12 +108,15 @@ ssl_status, std::move(navigation_data), request_id, is_download, is_stream, mojom::URLLoaderFactoryPtrInfo()); } - -void NavigationURLLoaderImpl::NotifyRequestFailed(bool in_cache, - int net_error) { +void NavigationURLLoaderImpl::NotifyRequestFailed( + bool in_cache, + int net_error, + base::Optional<net::SSLInfo> ssl_info, + bool should_ssl_errors_be_fatal) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - delegate_->OnRequestFailed(in_cache, net_error); + delegate_->OnRequestFailed(in_cache, net_error, ssl_info, + should_ssl_errors_be_fatal); } void NavigationURLLoaderImpl::NotifyRequestStarted(base::TimeTicks timestamp) {
diff --git a/content/browser/loader/navigation_url_loader_impl.h b/content/browser/loader/navigation_url_loader_impl.h index 5b6c2a3c6..3349458 100644 --- a/content/browser/loader/navigation_url_loader_impl.h +++ b/content/browser/loader/navigation_url_loader_impl.h
@@ -10,11 +10,13 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" +#include "base/optional.h" #include "base/time/time.h" #include "content/browser/loader/navigation_url_loader.h" namespace net { struct RedirectInfo; +class SSLInfo; } namespace content { @@ -60,8 +62,14 @@ bool is_download, bool is_stream); - // Notifies the delegate the request failed to return a response. - void NotifyRequestFailed(bool in_cache, int net_error); + // Notifies the delegate the the request has failed. If |net_error| is a + // certificate error, the caller must pass valid values for |ssl_info| and + // |fatal_cert_error|. If |net_error| is not a certificate error, |ssl_info| + // and |fatal_cert_error| are ignored. + void NotifyRequestFailed(bool in_cache, + int net_error, + base::Optional<net::SSLInfo> ssl_info, + bool should_ssl_errors_be_fatal); // Notifies the delegate the begin navigation request was handled and a // potential first network request is about to be made.
diff --git a/content/browser/loader/navigation_url_loader_impl_core.cc b/content/browser/loader/navigation_url_loader_impl_core.cc index a505821..0166832 100644 --- a/content/browser/loader/navigation_url_loader_impl_core.cc +++ b/content/browser/loader/navigation_url_loader_impl_core.cc
@@ -136,8 +136,11 @@ is_stream)); } -void NavigationURLLoaderImplCore::NotifyRequestFailed(bool in_cache, - int net_error) { +void NavigationURLLoaderImplCore::NotifyRequestFailed( + bool in_cache, + int net_error, + const base::Optional<net::SSLInfo>& ssl_info, + bool should_ssl_errors_be_fatal) { DCHECK_CURRENTLY_ON(BrowserThread::IO); TRACE_EVENT_ASYNC_END0("navigation", "Navigation redirectDelay", this); TRACE_EVENT_ASYNC_END2("navigation", "Navigation timeToResponseStarted", this, @@ -147,7 +150,8 @@ BrowserThread::PostTask( BrowserThread::UI, FROM_HERE, base::BindOnce(&NavigationURLLoaderImpl::NotifyRequestFailed, loader_, - in_cache, net_error)); + in_cache, net_error, ssl_info, + should_ssl_errors_be_fatal)); } } // namespace content
diff --git a/content/browser/loader/navigation_url_loader_impl_core.h b/content/browser/loader/navigation_url_loader_impl_core.h index b4044b23..2d5d5f88 100644 --- a/content/browser/loader/navigation_url_loader_impl_core.h +++ b/content/browser/loader/navigation_url_loader_impl_core.h
@@ -83,7 +83,10 @@ bool is_stream); // Notifies |loader_| on the UI thread that the request failed. - void NotifyRequestFailed(bool in_cache, int net_error); + void NotifyRequestFailed(bool in_cache, + int net_error, + const base::Optional<net::SSLInfo>& ssl_info, + bool should_ssl_errors_be_fatal); private: friend class base::RefCountedThreadSafe<NavigationURLLoaderImplCore>;
diff --git a/content/browser/loader/navigation_url_loader_network_service.cc b/content/browser/loader/navigation_url_loader_network_service.cc index a61d394..9e11659 100644 --- a/content/browser/loader/navigation_url_loader_network_service.cc +++ b/content/browser/loader/navigation_url_loader_network_service.cc
@@ -548,10 +548,16 @@ TRACE_EVENT_ASYNC_END2("navigation", "Navigation timeToResponseStarted", this, "&NavigationURLLoaderNetworkService", this, "success", false); - - delegate_->OnRequestFailed(completion_status.exists_in_cache, - completion_status.error_code); } + + // TODO(https://crbug.com/757633): Pass real values in the case of cert + // errors. + base::Optional<net::SSLInfo> ssl_info = base::nullopt; + bool should_ssl_errors_be_fatal = true; + + delegate_->OnRequestFailed(completion_status.exists_in_cache, + completion_status.error_code, ssl_info, + should_ssl_errors_be_fatal); } } // namespace content
diff --git a/content/browser/loader/navigation_url_loader_unittest.cc b/content/browser/loader/navigation_url_loader_unittest.cc index 5cb278b..8c5c860 100644 --- a/content/browser/loader/navigation_url_loader_unittest.cc +++ b/content/browser/loader/navigation_url_loader_unittest.cc
@@ -31,7 +31,9 @@ #include "content/test/test_navigation_url_loader_delegate.h" #include "net/base/load_flags.h" #include "net/base/net_errors.h" +#include "net/cert/cert_status_flags.h" #include "net/http/http_response_headers.h" +#include "net/test/embedded_test_server/embedded_test_server.h" #include "net/traffic_annotation/network_traffic_annotation_test_helper.h" #include "net/url_request/redirect_info.h" #include "net/url_request/url_request.h" @@ -115,6 +117,7 @@ url::Origin(url)); CommonNavigationParams common_params; common_params.url = url; + std::unique_ptr<NavigationRequestInfo> request_info( new NavigationRequestInfo(common_params, begin_params, url, true, false, false, -1, false, false, @@ -172,7 +175,7 @@ } // Tests that request failures are propagated correctly. -TEST_F(NavigationURLLoaderTest, RequestFailed) { +TEST_F(NavigationURLLoaderTest, RequestFailedNoCertError) { TestNavigationURLLoaderDelegate delegate; std::unique_ptr<NavigationURLLoader> loader = MakeTestLoader(GURL("bogus:bogus"), &delegate); @@ -180,6 +183,65 @@ // Wait for the request to fail as expected. delegate.WaitForRequestFailed(); EXPECT_EQ(net::ERR_UNKNOWN_URL_SCHEME, delegate.net_error()); + EXPECT_FALSE(delegate.ssl_info().has_value()); + EXPECT_EQ(1, delegate.on_request_handled_counter()); +} + +// Tests that request failures are propagated correctly for a (non-fatal) cert +// error: +// - |ssl_info| has the expected values. +// - |should_ssl_errors_be_fatal| is false. +TEST_F(NavigationURLLoaderTest, RequestFailedCertError) { + net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS); + https_server.SetSSLConfig(net::EmbeddedTestServer::CERT_MISMATCHED_NAME); + ASSERT_TRUE(https_server.Start()); + + TestNavigationURLLoaderDelegate delegate; + std::unique_ptr<NavigationURLLoader> loader = + MakeTestLoader(https_server.GetURL("/"), &delegate); + + // Wait for the request to fail as expected. + delegate.WaitForRequestFailed(); + ASSERT_EQ(net::ERR_ABORTED, delegate.net_error()); + net::SSLInfo ssl_info = delegate.ssl_info().value(); + EXPECT_TRUE(net::MapCertStatusToNetError(ssl_info.is_valid())); + EXPECT_TRUE(https_server.GetCertificate()->Equals(ssl_info.cert.get())); + EXPECT_EQ(net::ERR_CERT_COMMON_NAME_INVALID, + net::MapCertStatusToNetError(ssl_info.cert_status)); + EXPECT_FALSE(delegate.should_ssl_errors_be_fatal()); + EXPECT_EQ(1, delegate.on_request_handled_counter()); +} + +// Tests that request failures are propagated correctly for a fatal cert error: +// - |ssl_info| has the expected values. +// - |should_ssl_errors_be_fatal| is true. +TEST_F(NavigationURLLoaderTest, RequestFailedCertErrorFatal) { + net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS); + https_server.SetSSLConfig(net::EmbeddedTestServer::CERT_MISMATCHED_NAME); + ASSERT_TRUE(https_server.Start()); + GURL url = https_server.GetURL("/"); + + // Set HSTS for the test domain in order to make SSL errors fatal. + net::TransportSecurityState* transport_security_state = + browser_context_->GetResourceContext() + ->GetRequestContext() + ->transport_security_state(); + base::Time expiry = base::Time::Now() + base::TimeDelta::FromDays(1000); + bool include_subdomains = false; + transport_security_state->AddHSTS(url.host(), expiry, include_subdomains); + + TestNavigationURLLoaderDelegate delegate; + std::unique_ptr<NavigationURLLoader> loader = MakeTestLoader(url, &delegate); + + // Wait for the request to fail as expected. + delegate.WaitForRequestFailed(); + ASSERT_EQ(net::ERR_ABORTED, delegate.net_error()); + net::SSLInfo ssl_info = delegate.ssl_info().value(); + EXPECT_TRUE(net::MapCertStatusToNetError(ssl_info.is_valid())); + EXPECT_TRUE(https_server.GetCertificate()->Equals(ssl_info.cert.get())); + EXPECT_EQ(net::ERR_CERT_COMMON_NAME_INVALID, + net::MapCertStatusToNetError(ssl_info.cert_status)); + EXPECT_TRUE(delegate.should_ssl_errors_be_fatal()); EXPECT_EQ(1, delegate.on_request_handled_counter()); }
diff --git a/content/browser/loader/resource_dispatcher_host_impl.cc b/content/browser/loader/resource_dispatcher_host_impl.cc index 1d4db3f..a3ae030 100644 --- a/content/browser/loader/resource_dispatcher_host_impl.cc +++ b/content/browser/loader/resource_dispatcher_host_impl.cc
@@ -2106,7 +2106,7 @@ info.common_params.url, resource_type, resource_context))) { - loader->NotifyRequestFailed(false, net::ERR_ABORTED); + loader->NotifyRequestFailed(false, net::ERR_ABORTED, base::nullopt, false); return; } @@ -2152,7 +2152,8 @@ if (body) { if (!GetBodyBlobDataHandles(body, resource_context, &blob_handles)) { new_request->CancelWithError(net::ERR_INSUFFICIENT_RESOURCES); - loader->NotifyRequestFailed(false, net::ERR_ABORTED); + loader->NotifyRequestFailed(false, net::ERR_ABORTED, base::nullopt, + false); return; } new_request->set_upload(UploadDataStreamBuilder::Build(
diff --git a/content/browser/renderer_host/OWNERS b/content/browser/renderer_host/OWNERS index 8a92367..4b90552 100644 --- a/content/browser/renderer_host/OWNERS +++ b/content/browser/renderer_host/OWNERS
@@ -19,6 +19,9 @@ sadrul@chromium.org tdresser@chromium.org +# For surface ID propagation and synchronization +fsamuel@chromium.org + # Linux sandboxing per-file render_sandbox_host_linux.*=jln@chromium.org per-file render_sandbox_host_linux.*=jorgelo@chromium.org
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 bcc553a..dda1da68 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura.cc +++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
@@ -113,7 +113,7 @@ #include "ui/gfx/gdi_util.h" #endif -#if defined(USE_X11) && !defined(OS_CHROMEOS) +#if defined(USE_X11) #include "content/browser/accessibility/browser_accessibility_auralinux.h" #endif @@ -526,61 +526,12 @@ void RenderWidgetHostViewAura::Show() { window_->Show(); - - if (!host_->is_hidden()) - return; - - bool has_saved_frame = - delegated_frame_host_ ? delegated_frame_host_->HasSavedFrame() : false; - ui::LatencyInfo renderer_latency_info, browser_latency_info; - if (has_saved_frame) { - browser_latency_info.AddLatencyNumber( - ui::TAB_SHOW_COMPONENT, host_->GetLatencyComponentId(), 0); - } else { - renderer_latency_info.AddLatencyNumber( - ui::TAB_SHOW_COMPONENT, host_->GetLatencyComponentId(), 0); - } - host_->WasShown(renderer_latency_info); - - aura::Window* root = window_->GetRootWindow(); - if (root) { - aura::client::CursorClient* cursor_client = - aura::client::GetCursorClient(root); - if (cursor_client) - NotifyRendererOfCursorVisibilityState(cursor_client->IsCursorVisible()); - } - - if (delegated_frame_host_) - delegated_frame_host_->WasShown(browser_latency_info); - -#if defined(OS_WIN) - UpdateLegacyWin(); -#endif + WasUnOccluded(); } void RenderWidgetHostViewAura::Hide() { window_->Hide(); - - if (!host_->is_hidden()) { - host_->WasHidden(); - if (delegated_frame_host_) - delegated_frame_host_->WasHidden(); - -#if defined(OS_WIN) - aura::WindowTreeHost* host = window_->GetHost(); - if (host) { - // We reparent the legacy Chrome_RenderWidgetHostHWND window to the global - // hidden window on the same lines as Windowed plugin windows. - if (legacy_render_widget_host_HWND_) - legacy_render_widget_host_HWND_->UpdateParent(ui::GetHiddenWindow()); - } -#endif - } - -#if defined(OS_WIN) - if (legacy_render_widget_host_HWND_) - legacy_render_widget_host_HWND_->Hide(); -#endif + WasOccluded(); } void RenderWidgetHostViewAura::SetSize(const gfx::Size& size) { @@ -632,7 +583,7 @@ host_->GetOrCreateRootBrowserAccessibilityManager(); if (manager) return ToBrowserAccessibilityWin(manager->GetRoot())->GetCOM(); -#elif defined(USE_X11) && !defined(OS_CHROMEOS) +#elif defined(USE_X11) BrowserAccessibilityManager* manager = host_->GetOrCreateRootBrowserAccessibilityManager(); if (manager) @@ -715,6 +666,61 @@ return window_->IsVisible(); } +void RenderWidgetHostViewAura::WasUnOccluded() { + if (!host_->is_hidden()) + return; + + bool has_saved_frame = + delegated_frame_host_ ? delegated_frame_host_->HasSavedFrame() : false; + ui::LatencyInfo renderer_latency_info, browser_latency_info; + if (has_saved_frame) { + browser_latency_info.AddLatencyNumber(ui::TAB_SHOW_COMPONENT, + host_->GetLatencyComponentId(), 0); + } else { + renderer_latency_info.AddLatencyNumber(ui::TAB_SHOW_COMPONENT, + host_->GetLatencyComponentId(), 0); + } + host_->WasShown(renderer_latency_info); + + aura::Window* root = window_->GetRootWindow(); + if (root) { + aura::client::CursorClient* cursor_client = + aura::client::GetCursorClient(root); + if (cursor_client) + NotifyRendererOfCursorVisibilityState(cursor_client->IsCursorVisible()); + } + + if (delegated_frame_host_) + delegated_frame_host_->WasShown(browser_latency_info); + +#if defined(OS_WIN) + UpdateLegacyWin(); +#endif +} + +void RenderWidgetHostViewAura::WasOccluded() { + if (!host_->is_hidden()) { + host_->WasHidden(); + if (delegated_frame_host_) + delegated_frame_host_->WasHidden(); + +#if defined(OS_WIN) + aura::WindowTreeHost* host = window_->GetHost(); + if (host) { + // We reparent the legacy Chrome_RenderWidgetHostHWND window to the global + // hidden window on the same lines as Windowed plugin windows. + if (legacy_render_widget_host_HWND_) + legacy_render_widget_host_HWND_->UpdateParent(ui::GetHiddenWindow()); + } +#endif + } + +#if defined(OS_WIN) + if (legacy_render_widget_host_HWND_) + legacy_render_widget_host_HWND_->Hide(); +#endif +} + gfx::Rect RenderWidgetHostViewAura::GetViewBounds() const { return window_->GetBoundsInScreen(); } @@ -2389,7 +2395,7 @@ if (!focused_view) return; -#if defined(USE_X11) && !defined(OS_CHROMEOS) +#if defined(USE_X11) const TextInputManager::TextSelection* selection = GetTextInputManager()->GetTextSelection(focused_view); if (selection->selected_text().length()) {
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.h b/content/browser/renderer_host/render_widget_host_view_aura.h index a6a4297..243679d 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura.h +++ b/content/browser/renderer_host/render_widget_host_view_aura.h
@@ -109,6 +109,8 @@ void Show() override; void Hide() override; bool IsShowing() override; + void WasUnOccluded() override; + void WasOccluded() override; gfx::Rect GetViewBounds() const override; void SetBackgroundColor(SkColor color) override; SkColor background_color() const override;
diff --git a/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc b/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc index 2675ab47..2ce5362 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc +++ b/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc
@@ -1746,6 +1746,43 @@ EXPECT_EQ(InputMsg_HandleInputEvent::ID, sink_->GetMessageAt(1)->type()); } +// Checks that WasOcculded/WasUnOccluded notifies RenderWidgetHostImpl. +TEST_F(RenderWidgetHostViewAuraTest, WasOccluded) { + view_->InitAsChild(nullptr); + view_->Show(); + EXPECT_FALSE(widget_host_->is_hidden()); + + // Verifies WasOccluded sets RenderWidgetHostImpl as hidden and WasUnOccluded + // resets the state. + view_->WasOccluded(); + EXPECT_TRUE(widget_host_->is_hidden()); + view_->WasUnOccluded(); + EXPECT_FALSE(widget_host_->is_hidden()); + + // Verifies WasOccluded sets RenderWidgetHostImpl as hidden and Show resets + // the state. + view_->WasOccluded(); + EXPECT_TRUE(widget_host_->is_hidden()); + view_->Show(); + EXPECT_FALSE(widget_host_->is_hidden()); + + // WasOccluded and WasUnOccluded are not in pairs. The last one dictates + // the final state. + for (int i = 0; i < 2; ++i) { + view_->WasOccluded(); + EXPECT_TRUE(widget_host_->is_hidden()); + } + view_->WasUnOccluded(); + EXPECT_FALSE(widget_host_->is_hidden()); + + for (int i = 0; i < 4; ++i) { + view_->WasUnOccluded(); + EXPECT_FALSE(widget_host_->is_hidden()); + } + view_->WasOccluded(); + EXPECT_TRUE(widget_host_->is_hidden()); +} + // Checks that touch-event state is maintained correctly. TEST_F(RenderWidgetHostViewAuraRafAlignedTouchDisabledTest, TouchEventState) { view_->InitAsChild(nullptr); @@ -6264,7 +6301,7 @@ } } -#if defined(USE_X11) && !defined(OS_CHROMEOS) +#if defined(USE_X11) // This test will verify that after selection, the selected text is written to // the clipboard from the focused widget. TEST_F(InputMethodStateAuraTest, SelectedTextCopiedToClipboard) {
diff --git a/content/browser/web_contents/web_contents_impl_unittest.cc b/content/browser/web_contents/web_contents_impl_unittest.cc index a11f6f08..bb30a92 100644 --- a/content/browser/web_contents/web_contents_impl_unittest.cc +++ b/content/browser/web_contents/web_contents_impl_unittest.cc
@@ -2495,7 +2495,7 @@ RunAllPendingInMessageLoop(); EXPECT_TRUE(deleted); - // Now try again but this time crash the intersitial after it was shown. + // Now try again but this time crash the interstitial after it was shown. interstitial = new TestInterstitialPage(contents(), true, url, &state, &deleted); interstitial->Show();
diff --git a/content/browser/web_contents/web_contents_view_aura.cc b/content/browser/web_contents/web_contents_view_aura.cc index 374c7a0..f407726a 100644 --- a/content/browser/web_contents/web_contents_view_aura.cc +++ b/content/browser/web_contents/web_contents_view_aura.cc
@@ -150,7 +150,7 @@ DISALLOW_COPY_AND_ASSIGN(WebDragSourceAura); }; -#if (!defined(OS_CHROMEOS) && defined(USE_X11)) || defined(OS_WIN) +#if defined(USE_X11) || defined(OS_WIN) // Fill out the OSExchangeData with a file contents, synthesizing a name if // necessary. void PrepareDragForFileContents(const DropData& drop_data, @@ -286,7 +286,7 @@ if (!drop_data.download_metadata.empty()) PrepareDragForDownload(drop_data, provider, web_contents); #endif -#if (!defined(OS_CHROMEOS) && defined(USE_X11)) || defined(OS_WIN) +#if defined(USE_X11) || defined(OS_WIN) // We set the file contents before the URL because the URL also sets file // contents (to a .URL shortcut). We want to prefer file content data over // a shortcut so we add it first. @@ -1158,7 +1158,7 @@ // Linux window managers like to handle raise-on-click themselves. If we // raise-on-click manually, this may override user settings that prevent // focus-stealing. -#if !defined(USE_X11) || defined (OS_CHROMEOS) +#if !defined(USE_X11) web_contents_->GetDelegate()->ActivateContents(web_contents_); #endif }
diff --git a/content/common/feature_policy/feature_policy.cc b/content/common/feature_policy/feature_policy.cc index 6d82e7b..8255175 100644 --- a/content/common/feature_policy/feature_policy.cc +++ b/content/common/feature_policy/feature_policy.cc
@@ -235,6 +235,8 @@ {blink::WebFeaturePolicyFeature::kSyncXHR, FeaturePolicy::FeatureDefault::EnableForAll}, {blink::WebFeaturePolicyFeature::kUsb, + FeaturePolicy::FeatureDefault::EnableForSelf}, + {blink::WebFeaturePolicyFeature::kWebVr, FeaturePolicy::FeatureDefault::EnableForSelf}})); return default_feature_list; }
diff --git a/content/public/android/java/src/org/chromium/content/browser/SelectionPopupController.java b/content/public/android/java/src/org/chromium/content/browser/SelectionPopupController.java index 10fb514..346d306 100644 --- a/content/public/android/java/src/org/chromium/content/browser/SelectionPopupController.java +++ b/content/public/android/java/src/org/chromium/content/browser/SelectionPopupController.java
@@ -651,7 +651,7 @@ int id = item.getItemId(); int groupId = item.getGroupId(); - if (BuildInfo.isAtLeastO()) { + if (BuildInfo.isAtLeastO() && id == android.R.id.textAssist) { doAssistAction(); mode.finish(); } else if (id == R.id.select_action_menu_select_all) {
diff --git a/content/public/test/simple_url_loader_test_helper.cc b/content/public/test/simple_url_loader_test_helper.cc new file mode 100644 index 0000000..85f74f5f --- /dev/null +++ b/content/public/test/simple_url_loader_test_helper.cc
@@ -0,0 +1,40 @@ +// 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 "content/public/test/simple_url_loader_test_helper.h" + +#include "base/bind.h" +#include "base/callback.h" +#include "base/logging.h" + +namespace content { + +SimpleURLLoaderTestHelper::SimpleURLLoaderTestHelper() + : weak_ptr_factory_(this) {} + +SimpleURLLoaderTestHelper::~SimpleURLLoaderTestHelper() {} + +SimpleURLLoader::BodyAsStringCallback SimpleURLLoaderTestHelper::GetCallback() { + DCHECK(!callback_created_); + callback_created_ = true; + + return base::Bind(&SimpleURLLoaderTestHelper::OnCompleteCallback, + weak_ptr_factory_.GetWeakPtr()); +} + +void SimpleURLLoaderTestHelper::WaitForCallback() { + DCHECK(!wait_started_); + wait_started_ = true; + run_loop_.Run(); +} + +void SimpleURLLoaderTestHelper::OnCompleteCallback( + std::unique_ptr<std::string> response_body) { + DCHECK(!response_body_); + + response_body_ = std::move(response_body); + run_loop_.Quit(); +} + +} // namespace content
diff --git a/content/public/test/simple_url_loader_test_helper.h b/content/public/test/simple_url_loader_test_helper.h new file mode 100644 index 0000000..b3cec95d --- /dev/null +++ b/content/public/test/simple_url_loader_test_helper.h
@@ -0,0 +1,58 @@ +// 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 CONTENT_PUBLIC_TEST_SIMPLE_URL_LOADER_TEST_HELPER_H_ +#define CONTENT_PUBLIC_TEST_SIMPLE_URL_LOADER_TEST_HELPER_H_ + +#include <memory> +#include <string> + +#include "base/callback_forward.h" +#include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "base/run_loop.h" +#include "content/public/common/simple_url_loader.h" + +namespace content { + +// Test utility class for waiting until a SimpleURLLoader has received a +// response body. +class SimpleURLLoaderTestHelper { + public: + SimpleURLLoaderTestHelper(); + ~SimpleURLLoaderTestHelper(); + + // Returns a BodyAsStringCallback for use with a SimpleURLLoader. May be + // called only once. + SimpleURLLoader::BodyAsStringCallback GetCallback(); + + // Waits until the callback returned by GetCallback() is invoked. + void WaitForCallback(); + + // Response body passed to the callback returned by GetCallback, if there was + // one. + const std::string* response_body() const { return response_body_.get(); } + + private: + // Called back GetCallback(). Stores the response body and quits the message + // loop. + void OnCompleteCallback(std::unique_ptr<std::string> response_body); + + // Used to ensure GetCallback() is called only once. + bool callback_created_ = false; + // Used to ensure WaitForCallback() is called only once. + bool wait_started_ = false; + + base::RunLoop run_loop_; + + std::unique_ptr<std::string> response_body_; + + base::WeakPtrFactory<SimpleURLLoaderTestHelper> weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(SimpleURLLoaderTestHelper); +}; + +} // namespace content + +#endif // CONTENT_PUBLIC_TEST_SIMPLE_URL_LOADER_TEST_HELPER_H_
diff --git a/content/renderer/media/cdm/pepper_cdm_wrapper.h b/content/renderer/media/cdm/pepper_cdm_wrapper.h index 1f4c934..b925439 100644 --- a/content/renderer/media/cdm/pepper_cdm_wrapper.h +++ b/content/renderer/media/cdm/pepper_cdm_wrapper.h
@@ -17,7 +17,9 @@ #include "base/callback.h" #include "base/macros.h" -class GURL; +namespace url { +class Origin; +} namespace content { class ContentDecryptorDelegate; @@ -41,7 +43,7 @@ // Pepper CDM can not be created. typedef base::Callback<std::unique_ptr<PepperCdmWrapper>( const std::string& pluginType, - const GURL& security_origin)> + const url::Origin& security_origin)> CreatePepperCdmCB; } // namespace content
diff --git a/content/renderer/media/cdm/pepper_cdm_wrapper_impl.cc b/content/renderer/media/cdm/pepper_cdm_wrapper_impl.cc index 33172fa..5cad0ab0 100644 --- a/content/renderer/media/cdm/pepper_cdm_wrapper_impl.cc +++ b/content/renderer/media/cdm/pepper_cdm_wrapper_impl.cc
@@ -32,7 +32,7 @@ std::unique_ptr<PepperCdmWrapper> PepperCdmWrapperImpl::Create( blink::WebLocalFrame* frame, const std::string& pluginType, - const GURL& security_origin) { + const url::Origin& security_origin) { DCHECK(frame); // The frame security origin could be different from the origin where the CDM @@ -40,8 +40,8 @@ // Note: The code will continue after navigation to the "same" origin, even // though the CDM is no longer necessary. // TODO: Consider avoiding this possibility entirely. http://crbug.com/575236 - GURL frame_security_origin(url::Origin(frame->GetSecurityOrigin()).GetURL()); - if (frame_security_origin != security_origin) { + const url::Origin frame_security_origin(frame->GetSecurityOrigin()); + if (!security_origin.IsSameOriginWith(frame_security_origin)) { LOG(ERROR) << "Frame has a different origin than the EME call."; return std::unique_ptr<PepperCdmWrapper>(); } @@ -61,9 +61,8 @@ if (!plugin_instance.get()) return std::unique_ptr<PepperCdmWrapper>(); - GURL plugin_url(plugin_instance->container()->GetDocument().Url()); - GURL plugin_security_origin = plugin_url.GetOrigin(); - CHECK_EQ(security_origin, plugin_security_origin) + CHECK(security_origin.IsSameOriginWith( + plugin_instance->container()->GetDocument().GetSecurityOrigin())) << "Pepper instance has a different origin than the EME call."; if (!plugin_instance->GetContentDecryptorDelegate())
diff --git a/content/renderer/media/cdm/pepper_cdm_wrapper_impl.h b/content/renderer/media/cdm/pepper_cdm_wrapper_impl.h index ba0efca..34d972d0 100644 --- a/content/renderer/media/cdm/pepper_cdm_wrapper_impl.h +++ b/content/renderer/media/cdm/pepper_cdm_wrapper_impl.h
@@ -23,6 +23,10 @@ class WebLocalFrame; } +namespace url { +class Origin; +} + namespace content { class ContentDecryptorDelegate; @@ -44,9 +48,10 @@ // blink:: objects. class PepperCdmWrapperImpl : public PepperCdmWrapper { public: - static std::unique_ptr<PepperCdmWrapper> Create(blink::WebLocalFrame* frame, - const std::string& pluginType, - const GURL& security_origin); + static std::unique_ptr<PepperCdmWrapper> Create( + blink::WebLocalFrame* frame, + const std::string& pluginType, + const url::Origin& security_origin); ~PepperCdmWrapperImpl() override;
diff --git a/content/renderer/media/cdm/ppapi_decryptor.cc b/content/renderer/media/cdm/ppapi_decryptor.cc index 7eaeda13..7faec01c 100644 --- a/content/renderer/media/cdm/ppapi_decryptor.cc +++ b/content/renderer/media/cdm/ppapi_decryptor.cc
@@ -23,12 +23,13 @@ #include "media/base/key_systems.h" #include "media/base/video_decoder_config.h" #include "media/base/video_frame.h" +#include "url/origin.h" namespace content { void PpapiDecryptor::Create( const std::string& key_system, - const GURL& security_origin, + const url::Origin& security_origin, bool allow_distinctive_identifier, bool allow_persistent_state, const CreatePepperCdmCB& create_pepper_cdm_cb,
diff --git a/content/renderer/media/cdm/ppapi_decryptor.h b/content/renderer/media/cdm/ppapi_decryptor.h index 3355b872..524bad5 100644 --- a/content/renderer/media/cdm/ppapi_decryptor.h +++ b/content/renderer/media/cdm/ppapi_decryptor.h
@@ -21,12 +21,14 @@ #include "media/base/decryptor.h" #include "media/base/video_decoder_config.h" -class GURL; - namespace base { class SingleThreadTaskRunner; } +namespace url { +class Origin; +} + namespace content { class ContentDecryptorDelegate; @@ -39,7 +41,7 @@ public: static void Create( const std::string& key_system, - const GURL& security_origin, + const url::Origin& security_origin, bool allow_distinctive_identifier, bool allow_persistent_state, const CreatePepperCdmCB& create_pepper_cdm_cb,
diff --git a/content/renderer/media/cdm/render_cdm_factory.cc b/content/renderer/media/cdm/render_cdm_factory.cc index f4c1e95..6f17c04 100644 --- a/content/renderer/media/cdm/render_cdm_factory.cc +++ b/content/renderer/media/cdm/render_cdm_factory.cc
@@ -17,7 +17,7 @@ #include "media/base/key_systems.h" #include "media/cdm/aes_decryptor.h" #include "media/media_features.h" -#include "url/gurl.h" +#include "url/origin.h" #if BUILDFLAG(ENABLE_LIBRARY_CDMS) #include "content/renderer/media/cdm/ppapi_decryptor.h" @@ -39,7 +39,7 @@ void RenderCdmFactory::Create( const std::string& key_system, - const GURL& security_origin, + const url::Origin& security_origin, const media::CdmConfig& cdm_config, const media::SessionMessageCB& session_message_cb, const media::SessionClosedCB& session_closed_cb, @@ -48,7 +48,7 @@ const media::CdmCreatedCB& cdm_created_cb) { DCHECK(thread_checker_.CalledOnValidThread()); - if (!security_origin.is_valid()) { + if (security_origin.unique()) { base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(cdm_created_cb, nullptr, "Invalid origin.")); return;
diff --git a/content/renderer/media/cdm/render_cdm_factory.h b/content/renderer/media/cdm/render_cdm_factory.h index b9dcf0f..f1223fc0 100644 --- a/content/renderer/media/cdm/render_cdm_factory.h +++ b/content/renderer/media/cdm/render_cdm_factory.h
@@ -17,12 +17,6 @@ #include "content/renderer/media/cdm/pepper_cdm_wrapper.h" #endif -class GURL; - -namespace media { -struct CdmConfig; -} // namespace media - namespace content { // CdmFactory implementation in content/renderer. This class is not thread safe @@ -40,7 +34,7 @@ // CdmFactory implementation. void Create( const std::string& key_system, - const GURL& security_origin, + const url::Origin& security_origin, const media::CdmConfig& cdm_config, const media::SessionMessageCB& session_message_cb, const media::SessionClosedCB& session_closed_cb,
diff --git a/content/renderer/media/media_factory.cc b/content/renderer/media/media_factory.cc index 2ccdca1..0fc99e4 100644 --- a/content/renderer/media/media_factory.cc +++ b/content/renderer/media/media_factory.cc
@@ -37,6 +37,7 @@ #include "services/ui/public/cpp/gpu/context_provider_command_buffer.h" #include "third_party/WebKit/public/web/WebKit.h" #include "third_party/WebKit/public/web/WebLocalFrame.h" +#include "url/origin.h" #if defined(OS_ANDROID) #include "content/renderer/media/android/media_player_renderer_client_factory.h" @@ -45,6 +46,7 @@ #include "content/renderer/media/android/stream_texture_wrapper_impl.h" #include "media/base/android/media_codec_util.h" #include "media/base/media.h" +#include "url/gurl.h" #endif #if BUILDFLAG(ENABLE_MOJO_MEDIA)
diff --git a/content/renderer/media/media_factory.h b/content/renderer/media/media_factory.h index 3b67219..8dddde7a 100644 --- a/content/renderer/media/media_factory.h +++ b/content/renderer/media/media_factory.h
@@ -21,7 +21,6 @@ #include "third_party/WebKit/public/platform/WebSecurityOrigin.h" #include "third_party/WebKit/public/platform/WebSetSinkIdCallbacks.h" #include "third_party/WebKit/public/platform/WebString.h" -#include "url/gurl.h" #if BUILDFLAG(ENABLE_MOJO_MEDIA) #include "media/mojo/interfaces/interface_factory.mojom.h" // nogncheck
diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc index fdec645..f1cf732c 100644 --- a/content/renderer/render_widget.cc +++ b/content/renderer/render_widget.cc
@@ -1460,14 +1460,8 @@ RenderThreadImpl::current()->sync_message_filter(), compositor_->GetSourceFrameNumber()); - if (swap_promise) { + if (swap_promise) compositor_->QueueSwapPromise(std::move(swap_promise)); - // Request a main frame. This might either A) request a commit ahead of time - // or B) request a commit which is not needed because there are not pending - // updates. If B) then the frame will be aborted early and the swap promises - // will be broken (see EarlyOut_NoUpdates). - compositor_->SetNeedsBeginFrame(); - } } void RenderWidget::DidChangeCursor(const WebCursorInfo& cursor_info) {
diff --git a/content/renderer/webclipboard_impl.cc b/content/renderer/webclipboard_impl.cc index efe4152..e914aef 100644 --- a/content/renderer/webclipboard_impl.cc +++ b/content/renderer/webclipboard_impl.cc
@@ -220,7 +220,7 @@ case kBufferStandard: break; case kBufferSelection: -#if defined(USE_X11) && !defined(OS_CHROMEOS) +#if defined(USE_X11) *result = ui::CLIPBOARD_TYPE_SELECTION; break; #else
diff --git a/content/shell/browser/shell_browser_main_parts.cc b/content/shell/browser/shell_browser_main_parts.cc index 32524409..1f25cd74ff 100644 --- a/content/shell/browser/shell_browser_main_parts.cc +++ b/content/shell/browser/shell_browser_main_parts.cc
@@ -175,7 +175,8 @@ switches::kCrashDumpsDir); breakpad::CrashDumpObserver::GetInstance()->RegisterClient( base::MakeUnique<breakpad::ChildProcessCrashObserver>( - crash_dumps_dir, kAndroidMinidumpDescriptor)); + crash_dumps_dir, kAndroidMinidumpDescriptor, + base::Bind(&base::DoNothing))); } return 0;
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index c7cebf0..9cf97e0 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -104,6 +104,8 @@ "../public/test/render_view_test.h", "../public/test/service_worker_test_helpers.cc", "../public/test/service_worker_test_helpers.h", + "../public/test/simple_url_loader_test_helper.cc", + "../public/test/simple_url_loader_test_helper.h", "../public/test/test_browser_context.cc", "../public/test/test_browser_context.h", "../public/test/test_browser_thread.cc",
diff --git a/content/test/test_navigation_url_loader.cc b/content/test/test_navigation_url_loader.cc index 1c07a2f3..367e0f90 100644 --- a/content/test/test_navigation_url_loader.cc +++ b/content/test/test_navigation_url_loader.cc
@@ -49,7 +49,7 @@ } void TestNavigationURLLoader::SimulateError(int error_code) { - delegate_->OnRequestFailed(false, error_code); + delegate_->OnRequestFailed(false, error_code, base::nullopt, false); } void TestNavigationURLLoader::CallOnRequestRedirected(
diff --git a/content/test/test_navigation_url_loader_delegate.cc b/content/test/test_navigation_url_loader_delegate.cc index 26ec48c..7097a81 100644 --- a/content/test/test_navigation_url_loader_delegate.cc +++ b/content/test/test_navigation_url_loader_delegate.cc
@@ -73,9 +73,14 @@ response_started_->Quit(); } -void TestNavigationURLLoaderDelegate::OnRequestFailed(bool in_cache, - int net_error) { +void TestNavigationURLLoaderDelegate::OnRequestFailed( + bool in_cache, + int net_error, + const base::Optional<net::SSLInfo>& ssl_info, + bool should_ssl_errors_be_fatal) { net_error_ = net_error; + ssl_info_ = ssl_info; + should_ssl_errors_be_fatal_ = should_ssl_errors_be_fatal; if (request_failed_) request_failed_->Quit(); }
diff --git a/content/test/test_navigation_url_loader_delegate.h b/content/test/test_navigation_url_loader_delegate.h index 8289309..b3723960 100644 --- a/content/test/test_navigation_url_loader_delegate.h +++ b/content/test/test_navigation_url_loader_delegate.h
@@ -9,6 +9,7 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" +#include "base/optional.h" #include "base/time/time.h" #include "content/browser/loader/navigation_url_loader_delegate.h" #include "mojo/public/cpp/system/data_pipe.h" @@ -38,6 +39,10 @@ ResourceResponse* response() const { return response_.get(); } StreamHandle* body() const { return body_.get(); } int net_error() const { return net_error_; } + base::Optional<net::SSLInfo> ssl_info() const { return ssl_info_; } + bool should_ssl_errors_be_fatal() const { + return should_ssl_errors_be_fatal_; + } int on_request_handled_counter() const { return on_request_handled_counter_; } // Waits for various navigation events. @@ -65,7 +70,10 @@ bool is_download, bool is_stream, mojom::URLLoaderFactoryPtrInfo loader_factory_ptr_info) override; - void OnRequestFailed(bool in_cache, int net_error) override; + void OnRequestFailed(bool in_cache, + int net_error, + const base::Optional<net::SSLInfo>& ssl_info, + bool should_ssl_errors_be_fatal) override; void OnRequestStarted(base::TimeTicks timestamp) override; private: @@ -75,6 +83,8 @@ std::unique_ptr<StreamHandle> body_; mojo::ScopedDataPipeConsumerHandle handle_; int net_error_; + base::Optional<net::SSLInfo> ssl_info_; + bool should_ssl_errors_be_fatal_; int on_request_handled_counter_; std::unique_ptr<base::RunLoop> request_redirected_;
diff --git a/device/hid/BUILD.gn b/device/hid/BUILD.gn index 6a958172..ae135754 100644 --- a/device/hid/BUILD.gn +++ b/device/hid/BUILD.gn
@@ -21,8 +21,6 @@ "hid_device_filter.h", "hid_device_info.cc", "hid_device_info.h", - "hid_device_info_linux.cc", - "hid_device_info_linux.h", "hid_report_descriptor.cc", "hid_report_descriptor.h", "hid_report_descriptor_item.cc", @@ -44,6 +42,10 @@ "//net", ] + public_deps = [ + "//device/hid/public/interfaces", + ] + if (is_linux && use_udev) { sources += [ "fake_input_service_linux.cc",
diff --git a/device/hid/hid_connection_unittest.cc b/device/hid/hid_connection_unittest.cc index 96f2194..806ccc7 100644 --- a/device/hid/hid_connection_unittest.cc +++ b/device/hid/hid_connection_unittest.cc
@@ -18,6 +18,7 @@ #include "base/test/scoped_task_environment.h" #include "base/test/test_io_thread.h" #include "device/hid/hid_service.h" +#include "device/hid/public/interfaces/hid.mojom.h" #include "device/test/test_device_client.h" #include "device/test/usb_test_gadget.h" #include "device/usb/usb_device.h" @@ -54,10 +55,10 @@ private: void OnEnumerationComplete( HidService* hid_service, - const std::vector<scoped_refptr<HidDeviceInfo>>& devices) { - for (const scoped_refptr<HidDeviceInfo>& device_info : devices) { - if (device_info->serial_number() == serial_number_) { - device_guid_ = device_info->device_guid(); + std::vector<device::mojom::HidDeviceInfoPtr> devices) { + for (auto& device_info : devices) { + if (device_info->serial_number == serial_number_) { + device_guid_ = device_info->guid; run_loop_.Quit(); break; } @@ -65,9 +66,9 @@ observer_.Add(hid_service); } - void OnDeviceAdded(scoped_refptr<HidDeviceInfo> device_info) override { - if (device_info->serial_number() == serial_number_) { - device_guid_ = device_info->device_guid(); + void OnDeviceAdded(device::mojom::HidDeviceInfoPtr device_info) override { + if (device_info->serial_number == serial_number_) { + device_guid_ = device_info->guid; run_loop_.Quit(); } }
diff --git a/device/hid/hid_device_filter.cc b/device/hid/hid_device_filter.cc index 3be57ab..9917fd5 100644 --- a/device/hid/hid_device_filter.cc +++ b/device/hid/hid_device_filter.cc
@@ -39,20 +39,20 @@ } bool HidDeviceFilter::Matches( - scoped_refptr<const HidDeviceInfo> device_info) const { + const device::mojom::HidDeviceInfo& device_info) const { if (vendor_id_set_) { - if (device_info->vendor_id() != vendor_id_) { + if (device_info.vendor_id != vendor_id_) { return false; } - if (product_id_set_ && device_info->product_id() != product_id_) { + if (product_id_set_ && device_info.product_id != product_id_) { return false; } } if (usage_page_set_) { bool found_matching_collection = false; - for (const HidCollectionInfo& collection : device_info->collections()) { + for (const HidCollectionInfo& collection : device_info.collections) { if (collection.usage.usage_page != usage_page_) { continue; } @@ -70,8 +70,9 @@ } // static -bool HidDeviceFilter::MatchesAny(scoped_refptr<const HidDeviceInfo> device_info, - const std::vector<HidDeviceFilter>& filters) { +bool HidDeviceFilter::MatchesAny( + const device::mojom::HidDeviceInfo& device_info, + const std::vector<HidDeviceFilter>& filters) { for (const HidDeviceFilter& filter : filters) { if (filter.Matches(device_info)) { return true;
diff --git a/device/hid/hid_device_filter.h b/device/hid/hid_device_filter.h index fbffd2b..98ae6fc4 100644 --- a/device/hid/hid_device_filter.h +++ b/device/hid/hid_device_filter.h
@@ -9,11 +9,10 @@ #include <vector> #include "base/memory/ref_counted.h" +#include "device/hid/public/interfaces/hid.mojom.h" namespace device { -class HidDeviceInfo; - class HidDeviceFilter { public: HidDeviceFilter(); @@ -24,9 +23,9 @@ void SetUsagePage(uint16_t usage_page); void SetUsage(uint16_t usage); - bool Matches(scoped_refptr<const HidDeviceInfo> device_info) const; + bool Matches(const device::mojom::HidDeviceInfo& device_info) const; - static bool MatchesAny(scoped_refptr<const HidDeviceInfo> device_info, + static bool MatchesAny(const device::mojom::HidDeviceInfo& device_info, const std::vector<HidDeviceFilter>& filters); private:
diff --git a/device/hid/hid_device_filter_unittest.cc b/device/hid/hid_device_filter_unittest.cc index c19a7346..3a8eff3 100644 --- a/device/hid/hid_device_filter_unittest.cc +++ b/device/hid/hid_device_filter_unittest.cc
@@ -7,6 +7,7 @@ #include "build/build_config.h" #include "device/hid/hid_device_filter.h" #include "device/hid/hid_device_info.h" +#include "device/hid/public/interfaces/hid.mojom.h" #include "device/hid/test_report_descriptors.h" #include "testing/gtest/include/gtest/gtest.h" @@ -27,7 +28,7 @@ void SetUp() override { device_info_ = new HidDeviceInfo( kTestDeviceId, 0x046d, 0xc31c, "Test Keyboard", "123ABC", - kHIDBusTypeUSB, + device::mojom::HidBusType::kHIDBusTypeUSB, std::vector<uint8_t>(kKeyboard, kKeyboard + kKeyboardSize)); } @@ -37,71 +38,71 @@ TEST_F(HidFilterTest, MatchAny) { HidDeviceFilter filter; - ASSERT_TRUE(filter.Matches(device_info_)); + ASSERT_TRUE(filter.Matches(*device_info_->device())); } TEST_F(HidFilterTest, MatchVendorId) { HidDeviceFilter filter; filter.SetVendorId(0x046d); - ASSERT_TRUE(filter.Matches(device_info_)); + ASSERT_TRUE(filter.Matches(*device_info_->device())); } TEST_F(HidFilterTest, MatchVendorIdNegative) { HidDeviceFilter filter; filter.SetVendorId(0x18d1); - ASSERT_FALSE(filter.Matches(device_info_)); + ASSERT_FALSE(filter.Matches(*device_info_->device())); } TEST_F(HidFilterTest, MatchProductId) { HidDeviceFilter filter; filter.SetVendorId(0x046d); filter.SetProductId(0xc31c); - ASSERT_TRUE(filter.Matches(device_info_)); + ASSERT_TRUE(filter.Matches(*device_info_->device())); } TEST_F(HidFilterTest, MatchProductIdNegative) { HidDeviceFilter filter; filter.SetVendorId(0x046d); filter.SetProductId(0x0801); - ASSERT_FALSE(filter.Matches(device_info_)); + ASSERT_FALSE(filter.Matches(*device_info_->device())); } TEST_F(HidFilterTest, MatchUsagePage) { HidDeviceFilter filter; filter.SetUsagePage(HidUsageAndPage::kPageGenericDesktop); - ASSERT_TRUE(filter.Matches(device_info_)); + ASSERT_TRUE(filter.Matches(*device_info_->device())); } TEST_F(HidFilterTest, MatchUsagePageNegative) { HidDeviceFilter filter; filter.SetUsagePage(HidUsageAndPage::kPageLed); - ASSERT_FALSE(filter.Matches(device_info_)); + ASSERT_FALSE(filter.Matches(*device_info_->device())); } TEST_F(HidFilterTest, MatchVendorAndUsagePage) { HidDeviceFilter filter; filter.SetVendorId(0x046d); filter.SetUsagePage(HidUsageAndPage::kPageGenericDesktop); - ASSERT_TRUE(filter.Matches(device_info_)); + ASSERT_TRUE(filter.Matches(*device_info_->device())); } TEST_F(HidFilterTest, MatchUsageAndPage) { HidDeviceFilter filter; filter.SetUsagePage(HidUsageAndPage::kPageGenericDesktop); filter.SetUsage(HidUsageAndPage::kGenericDesktopKeyboard); - ASSERT_TRUE(filter.Matches(device_info_)); + ASSERT_TRUE(filter.Matches(*device_info_->device())); } TEST_F(HidFilterTest, MatchUsageAndPageNegative) { HidDeviceFilter filter; filter.SetUsagePage(HidUsageAndPage::kPageGenericDesktop); filter.SetUsage(0x02); - ASSERT_FALSE(filter.Matches(device_info_)); + ASSERT_FALSE(filter.Matches(*device_info_->device())); } TEST_F(HidFilterTest, MatchEmptyFilterListNegative) { std::vector<HidDeviceFilter> filters; - ASSERT_FALSE(HidDeviceFilter::MatchesAny(device_info_, filters)); + ASSERT_FALSE(HidDeviceFilter::MatchesAny(*device_info_->device(), filters)); } TEST_F(HidFilterTest, MatchFilterList) { @@ -109,7 +110,7 @@ HidDeviceFilter filter; filter.SetUsagePage(HidUsageAndPage::kPageGenericDesktop); filters.push_back(filter); - ASSERT_TRUE(HidDeviceFilter::MatchesAny(device_info_, filters)); + ASSERT_TRUE(HidDeviceFilter::MatchesAny(*device_info_->device(), filters)); } TEST_F(HidFilterTest, MatchFilterListNegative) { @@ -117,7 +118,7 @@ HidDeviceFilter filter; filter.SetUsagePage(HidUsageAndPage::kPageLed); filters.push_back(filter); - ASSERT_FALSE(HidDeviceFilter::MatchesAny(device_info_, filters)); + ASSERT_FALSE(HidDeviceFilter::MatchesAny(*device_info_->device(), filters)); } } // namespace device
diff --git a/device/hid/hid_device_info.cc b/device/hid/hid_device_info.cc index 8369f11..fd787ec 100644 --- a/device/hid/hid_device_info.cc +++ b/device/hid/hid_device_info.cc
@@ -15,20 +15,26 @@ uint16_t product_id, const std::string& product_name, const std::string& serial_number, - HidBusType bus_type, - const std::vector<uint8_t> report_descriptor) - : guid_(base::GenerateGUID()), - platform_device_id_(platform_device_id), - vendor_id_(vendor_id), - product_id_(product_id), - product_name_(product_name), - serial_number_(serial_number), - bus_type_(bus_type), - report_descriptor_(report_descriptor) { - HidReportDescriptor descriptor_parser(report_descriptor_); - descriptor_parser.GetDetails( - &collections_, &has_report_id_, &max_input_report_size_, - &max_output_report_size_, &max_feature_report_size_); + device::mojom::HidBusType bus_type, + const std::vector<uint8_t> report_descriptor, + std::string device_node) + : platform_device_id_(platform_device_id) { + std::vector<HidCollectionInfo> collections; + bool has_report_id; + size_t max_input_report_size; + size_t max_output_report_size; + size_t max_feature_report_size; + + HidReportDescriptor descriptor_parser(report_descriptor); + descriptor_parser.GetDetails(&collections, &has_report_id, + &max_input_report_size, &max_output_report_size, + &max_feature_report_size); + + device_ = device::mojom::HidDeviceInfo::New( + base::GenerateGUID(), vendor_id, product_id, product_name, serial_number, + bus_type, report_descriptor, collections, has_report_id, + max_input_report_size, max_output_report_size, max_feature_report_size, + device_node); } HidDeviceInfo::HidDeviceInfo(const HidPlatformDeviceId& platform_device_id, @@ -36,23 +42,22 @@ uint16_t product_id, const std::string& product_name, const std::string& serial_number, - HidBusType bus_type, + device::mojom::HidBusType bus_type, const HidCollectionInfo& collection, size_t max_input_report_size, size_t max_output_report_size, size_t max_feature_report_size) - : guid_(base::GenerateGUID()), - platform_device_id_(platform_device_id), - vendor_id_(vendor_id), - product_id_(product_id), - product_name_(product_name), - serial_number_(serial_number), - bus_type_(bus_type), - max_input_report_size_(max_input_report_size), - max_output_report_size_(max_output_report_size), - max_feature_report_size_(max_feature_report_size) { - collections_.push_back(collection); - has_report_id_ = !collection.report_ids.empty(); + : platform_device_id_(platform_device_id) { + std::vector<HidCollectionInfo> collections; + collections.push_back(collection); + bool has_report_id = !collection.report_ids.empty(); + + std::vector<uint8_t> report_descriptor; + device_ = device::mojom::HidDeviceInfo::New( + base::GenerateGUID(), vendor_id, product_id, product_name, serial_number, + bus_type, report_descriptor, collections, has_report_id, + max_input_report_size, max_output_report_size, max_feature_report_size, + ""); } HidDeviceInfo::~HidDeviceInfo() {}
diff --git a/device/hid/hid_device_info.h b/device/hid/hid_device_info.h index 8e856b59..632bbeb 100644 --- a/device/hid/hid_device_info.h +++ b/device/hid/hid_device_info.h
@@ -15,14 +15,10 @@ #include "base/memory/ref_counted.h" #include "build/build_config.h" #include "device/hid/hid_collection_info.h" +#include "device/hid/public/interfaces/hid.mojom.h" namespace device { -enum HidBusType { - kHIDBusTypeUSB = 0, - kHIDBusTypeBluetooth = 1, -}; - #if defined(OS_MACOSX) typedef uint64_t HidPlatformDeviceId; #else @@ -36,44 +32,54 @@ uint16_t product_id, const std::string& product_name, const std::string& serial_number, - HidBusType bus_type, - const std::vector<uint8_t> report_descriptor); + device::mojom::HidBusType bus_type, + const std::vector<uint8_t> report_descriptor, + std::string device_node = ""); HidDeviceInfo(const HidPlatformDeviceId& platform_device_id, uint16_t vendor_id, uint16_t product_id, const std::string& product_name, const std::string& serial_number, - HidBusType bus_type, + device::mojom::HidBusType bus_type, const HidCollectionInfo& collection, size_t max_input_report_size, size_t max_output_report_size, size_t max_feature_report_size); + const device::mojom::HidDeviceInfoPtr& device() { return device_; } + // Device identification. - const std::string& device_guid() const { return guid_; } + const std::string& device_guid() const { return device_->guid; } const HidPlatformDeviceId& platform_device_id() const { return platform_device_id_; } - uint16_t vendor_id() const { return vendor_id_; } - uint16_t product_id() const { return product_id_; } - const std::string& product_name() const { return product_name_; } - const std::string& serial_number() const { return serial_number_; } - HidBusType bus_type() const { return bus_type_; } + uint16_t vendor_id() const { return device_->vendor_id; } + uint16_t product_id() const { return device_->product_id; } + const std::string& product_name() const { return device_->product_name; } + const std::string& serial_number() const { return device_->serial_number; } + device::mojom::HidBusType bus_type() const { return device_->bus_type; } // Top-Level Collections information. const std::vector<HidCollectionInfo>& collections() const { - return collections_; + return device_->collections; } - bool has_report_id() const { return has_report_id_; }; - size_t max_input_report_size() const { return max_input_report_size_; } - size_t max_output_report_size() const { return max_output_report_size_; } - size_t max_feature_report_size() const { return max_feature_report_size_; } + bool has_report_id() const { return device_->has_report_id; }; + size_t max_input_report_size() const { + return device_->max_input_report_size; + } + size_t max_output_report_size() const { + return device_->max_output_report_size; + } + size_t max_feature_report_size() const { + return device_->max_feature_report_size; + } // The raw HID report descriptor is not available on Windows. const std::vector<uint8_t>& report_descriptor() const { - return report_descriptor_; + return device_->report_descriptor; } + const std::string& device_node() const { return device_->device_node; } protected: virtual ~HidDeviceInfo(); @@ -81,22 +87,8 @@ private: friend class base::RefCountedThreadSafe<HidDeviceInfo>; - // Device identification for client. - std::string guid_; HidPlatformDeviceId platform_device_id_; - uint16_t vendor_id_; - uint16_t product_id_; - std::string product_name_; - std::string serial_number_; - HidBusType bus_type_; - std::vector<uint8_t> report_descriptor_; - - // Top-Level Collections information. - std::vector<HidCollectionInfo> collections_; - bool has_report_id_; - size_t max_input_report_size_; - size_t max_output_report_size_; - size_t max_feature_report_size_; + device::mojom::HidDeviceInfoPtr device_; DISALLOW_COPY_AND_ASSIGN(HidDeviceInfo); };
diff --git a/device/hid/hid_device_info_linux.cc b/device/hid/hid_device_info_linux.cc deleted file mode 100644 index a3e53bd..0000000 --- a/device/hid/hid_device_info_linux.cc +++ /dev/null
@@ -1,30 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "hid_device_info_linux.h" - -namespace device { - -HidDeviceInfoLinux::HidDeviceInfoLinux( - const HidPlatformDeviceId& platform_device_id, - const std::string& device_node, - uint16_t vendor_id, - uint16_t product_id, - const std::string& product_name, - const std::string& serial_number, - HidBusType bus_type, - const std::vector<uint8_t> report_descriptor) - : HidDeviceInfo(platform_device_id, - vendor_id, - product_id, - product_name, - serial_number, - bus_type, - report_descriptor), - device_node_(device_node) {} - -HidDeviceInfoLinux::~HidDeviceInfoLinux() { -} - -} // namespace device
diff --git a/device/hid/hid_device_info_linux.h b/device/hid/hid_device_info_linux.h deleted file mode 100644 index 86839f5..0000000 --- a/device/hid/hid_device_info_linux.h +++ /dev/null
@@ -1,35 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef DEVICE_HID_HID_DEVICE_INFO_LINUX_H_ -#define DEVICE_HID_HID_DEVICE_INFO_LINUX_H_ - -#include <stdint.h> - -#include "device/hid/hid_device_info.h" - -namespace device { - -class HidDeviceInfoLinux : public HidDeviceInfo { - public: - HidDeviceInfoLinux(const HidPlatformDeviceId& platform_device_id, - const std::string& device_node, - uint16_t vendor_id, - uint16_t product_id, - const std::string& product_name, - const std::string& serial_number, - HidBusType bus_type, - const std::vector<uint8_t> report_descriptor); - - const std::string& device_node() const { return device_node_; } - - private: - ~HidDeviceInfoLinux() override; - - std::string device_node_; -}; - -} // namespace device - -#endif // DEVICE_HID_HID_DEVICE_INFO_LINUX_H_
diff --git a/device/hid/hid_service.cc b/device/hid/hid_service.cc index 325cc1b..8f3b40a 100644 --- a/device/hid/hid_service.cc +++ b/device/hid/hid_service.cc
@@ -25,12 +25,10 @@ namespace device { void HidService::Observer::OnDeviceAdded( - scoped_refptr<HidDeviceInfo> device_info) { -} + device::mojom::HidDeviceInfoPtr device_info) {} void HidService::Observer::OnDeviceRemoved( - scoped_refptr<HidDeviceInfo> device_info) { -} + device::mojom::HidDeviceInfoPtr device_info) {} // static constexpr base::TaskTraits HidService::kBlockingTaskTraits; @@ -67,16 +65,6 @@ observer_list_.RemoveObserver(observer); } -scoped_refptr<HidDeviceInfo> HidService::GetDeviceInfo( - const std::string& device_guid) const { - DCHECK(thread_checker_.CalledOnValidThread()); - DeviceMap::const_iterator it = devices_.find(device_guid); - if (it == devices_.end()) { - return nullptr; - } - return it->second; -} - HidService::HidService() = default; HidService::~HidService() { @@ -101,7 +89,7 @@ if (enumeration_ready_) { for (auto& observer : observer_list_) - observer.OnDeviceAdded(device_info); + observer.OnDeviceAdded(device_info->device()->Clone()); } } } @@ -115,10 +103,10 @@ << "'"; DCHECK(base::ContainsKey(devices_, device_guid)); - scoped_refptr<HidDeviceInfo> device = devices_[device_guid]; + scoped_refptr<HidDeviceInfo> device_info = devices_[device_guid]; if (enumeration_ready_) { for (auto& observer : observer_list_) - observer.OnDeviceRemoved(device); + observer.OnDeviceRemoved(device_info->device()->Clone()); } devices_.erase(device_guid); } @@ -128,14 +116,16 @@ DCHECK(enumeration_ready_); DCHECK(!pending_enumerations_.empty()); - std::vector<scoped_refptr<HidDeviceInfo>> devices; - for (const auto& map_entry : devices_) - devices.push_back(map_entry.second); - std::vector<GetDevicesCallback> callbacks; callbacks.swap(pending_enumerations_); - for (const auto& callback : callbacks) - callback.Run(devices); + + // Clone and pass device::mojom::HidDeviceInfoPtr vector for each clients. + for (const auto& callback : callbacks) { + std::vector<device::mojom::HidDeviceInfoPtr> devices; + for (const auto& map_entry : devices_) + devices.push_back(map_entry.second->device()->Clone()); + callback.Run(std::move(devices)); + } } void HidService::FirstEnumerationComplete() {
diff --git a/device/hid/hid_service.h b/device/hid/hid_service.h index 7cc9454f..906db27 100644 --- a/device/hid/hid_service.h +++ b/device/hid/hid_service.h
@@ -20,6 +20,7 @@ #include "base/task_scheduler/task_traits.h" #include "base/threading/thread_checker.h" #include "device/hid/hid_device_info.h" +#include "device/hid/public/interfaces/hid.mojom.h" namespace device { @@ -38,15 +39,15 @@ // the observer immediately after calling the GetDevicesCallback. class Observer { public: - virtual void OnDeviceAdded(scoped_refptr<HidDeviceInfo> info); + virtual void OnDeviceAdded(device::mojom::HidDeviceInfoPtr info); // Notifies all observers that a device is being removed, called before // removing the device from HidService. Observers should not depend on the // order in which they are notified of the OnDeviceRemove event. - virtual void OnDeviceRemoved(scoped_refptr<HidDeviceInfo> info); + virtual void OnDeviceRemoved(device::mojom::HidDeviceInfoPtr info); }; using GetDevicesCallback = - base::Callback<void(const std::vector<scoped_refptr<HidDeviceInfo>>&)>; + base::Callback<void(std::vector<device::mojom::HidDeviceInfoPtr>)>; using ConnectCallback = base::Callback<void(scoped_refptr<HidConnection> connection)>; @@ -66,9 +67,6 @@ void AddObserver(Observer* observer); void RemoveObserver(Observer* observer); - scoped_refptr<HidDeviceInfo> GetDeviceInfo( - const std::string& device_guid) const; - // Opens a connection to a device. The callback will be run with null on // failure. virtual void Connect(const std::string& device_guid,
diff --git a/device/hid/hid_service_linux.cc b/device/hid/hid_service_linux.cc index ede6113..1e26493 100644 --- a/device/hid/hid_service_linux.cc +++ b/device/hid/hid_service_linux.cc
@@ -30,7 +30,6 @@ #include "build/build_config.h" #include "components/device_event_log/device_event_log.h" #include "device/hid/hid_connection_linux.h" -#include "device/hid/hid_device_info_linux.h" #include "device/udev_linux/scoped_udev.h" #include "device/udev_linux/udev_watcher.h" @@ -53,7 +52,7 @@ } // namespace struct HidServiceLinux::ConnectParams { - ConnectParams(scoped_refptr<HidDeviceInfoLinux> device_info, + ConnectParams(scoped_refptr<HidDeviceInfo> device_info, const ConnectCallback& callback) : device_info(std::move(device_info)), callback(callback), @@ -62,7 +61,7 @@ base::CreateSequencedTaskRunnerWithTraits(kBlockingTaskTraits)) {} ~ConnectParams() {} - scoped_refptr<HidDeviceInfoLinux> device_info; + scoped_refptr<HidDeviceInfo> device_info; ConnectCallback callback; scoped_refptr<base::SequencedTaskRunner> task_runner; scoped_refptr<base::SequencedTaskRunner> blocking_task_runner; @@ -155,12 +154,13 @@ if (!base::ReadFileToString(report_descriptor_path, &report_descriptor_str)) return; - scoped_refptr<HidDeviceInfo> device_info(new HidDeviceInfoLinux( - platform_device_id, device_node, vendor_id, product_id, product_name, - serial_number, - kHIDBusTypeUSB, // TODO(reillyg): Detect Bluetooth. crbug.com/443335 + scoped_refptr<HidDeviceInfo> device_info(new HidDeviceInfo( + platform_device_id, vendor_id, product_id, product_name, serial_number, + // TODO(reillyg): Detect Bluetooth. crbug.com/443335 + device::mojom::HidBusType::kHIDBusTypeUSB, std::vector<uint8_t>(report_descriptor_str.begin(), - report_descriptor_str.end()))); + report_descriptor_str.end()), + device_node)); task_runner_->PostTask(FROM_HERE, base::Bind(&HidServiceLinux::AddDevice, service_, device_info)); @@ -214,8 +214,7 @@ FROM_HERE, base::Bind(callback, nullptr)); return; } - scoped_refptr<HidDeviceInfoLinux> device_info = - static_cast<HidDeviceInfoLinux*>(map_entry->second.get()); + scoped_refptr<HidDeviceInfo> device_info = map_entry->second; auto params = std::make_unique<ConnectParams>(device_info, callback);
diff --git a/device/hid/hid_service_mac.cc b/device/hid/hid_service_mac.cc index a394ec2..7ecedb7 100644 --- a/device/hid/hid_service_mac.cc +++ b/device/hid/hid_service_mac.cc
@@ -85,8 +85,8 @@ GetIntProperty(service, CFSTR(kIOHIDProductIDKey)), GetStringProperty(service, CFSTR(kIOHIDProductKey)), GetStringProperty(service, CFSTR(kIOHIDSerialNumberKey)), - kHIDBusTypeUSB, // TODO(reillyg): Detect Bluetooth. crbug.com/443335 - report_descriptor); + // TODO(reillyg): Detect Bluetooth. crbug.com/443335 + device::mojom::HidBusType::kHIDBusTypeUSB, report_descriptor); } } // namespace
diff --git a/device/hid/hid_service_unittest.cc b/device/hid/hid_service_unittest.cc index 4da84d48..17ac871 100644 --- a/device/hid/hid_service_unittest.cc +++ b/device/hid/hid_service_unittest.cc
@@ -6,6 +6,7 @@ #include "base/bind.h" #include "base/run_loop.h" #include "base/test/scoped_task_environment.h" +#include "device/hid/public/interfaces/hid.mojom.h" #include "device/test/test_device_client.h" #include "testing/gtest/include/gtest/gtest.h" @@ -25,7 +26,7 @@ }; void OnGetDevices(const base::Closure& quit_closure, - const std::vector<scoped_refptr<HidDeviceInfo>>& devices) { + std::vector<device::mojom::HidDeviceInfoPtr> devices) { // Since there's no guarantee that any devices are connected at the moment // this test doesn't assume anything about the result but it at least verifies // that devices can be enumerated without the application crashing.
diff --git a/device/hid/hid_service_win.cc b/device/hid/hid_service_win.cc index 9be84112..0357ea7 100644 --- a/device/hid/hid_service_win.cc +++ b/device/hid/hid_service_win.cc
@@ -260,9 +260,9 @@ scoped_refptr<HidDeviceInfo> device_info(new HidDeviceInfo( device_path, attrib.VendorID, attrib.ProductID, product_name, serial_number, - kHIDBusTypeUSB, // TODO(reillyg): Detect Bluetooth. crbug.com/443335 - collection_info, max_input_report_size, max_output_report_size, - max_feature_report_size)); + // TODO(reillyg): Detect Bluetooth. crbug.com/443335 + device::mojom::HidBusType::kHIDBusTypeUSB, collection_info, + max_input_report_size, max_output_report_size, max_feature_report_size)); HidD_FreePreparsedData(preparsed_data); task_runner->PostTask(
diff --git a/device/hid/hid_usage_and_page.h b/device/hid/hid_usage_and_page.h index 1015854..2ed9113 100644 --- a/device/hid/hid_usage_and_page.h +++ b/device/hid/hid_usage_and_page.h
@@ -119,6 +119,7 @@ kGenericDesktopSystemDisplaySwap = 0xb6, }; + HidUsageAndPage() {} HidUsageAndPage(uint16_t usage, Page usage_page) : usage(usage), usage_page(usage_page) {} ~HidUsageAndPage() {}
diff --git a/device/hid/public/interfaces/BUILD.gn b/device/hid/public/interfaces/BUILD.gn new file mode 100644 index 0000000..3791874 --- /dev/null +++ b/device/hid/public/interfaces/BUILD.gn
@@ -0,0 +1,11 @@ +# 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("//mojo/public/tools/bindings/mojom.gni") + +mojom("interfaces") { + sources = [ + "hid.mojom", + ] +}
diff --git a/device/hid/public/interfaces/OWNERS b/device/hid/public/interfaces/OWNERS new file mode 100644 index 0000000..51ec2e6 --- /dev/null +++ b/device/hid/public/interfaces/OWNERS
@@ -0,0 +1,8 @@ +# Changes to Mojo interfaces require a security review to avoid +# introducing new sandbox escapes. +per-file *.mojom=set noparent +per-file *.mojom=file://ipc/SECURITY_OWNERS +per-file *_struct_traits*.*=set noparent +per-file *_struct_traits*.*=file://ipc/SECURITY_OWNERS +per-file *.typemap=set noparent +per-file *.typemap=file://ipc/SECURITY_OWNERS
diff --git a/device/hid/public/interfaces/hid.mojom b/device/hid/public/interfaces/hid.mojom new file mode 100644 index 0000000..25cf4cdb --- /dev/null +++ b/device/hid/public/interfaces/hid.mojom
@@ -0,0 +1,72 @@ +// 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. + +module device.mojom; + +enum HidBusType { + kHIDBusTypeUSB = 0, + kHIDBusTypeBluetooth = 1, +}; + +enum HidPage { + PageUndefined = 0x00, + PageGenericDesktop = 0x01, + PageSimulation = 0x02, + PageVirtualReality = 0x03, + PageSport = 0x04, + PageGame = 0x05, + PageKeyboard = 0x07, + PageLed = 0x08, + PageButton = 0x09, + PageOrdinal = 0x0A, + PageTelephony = 0x0B, + PageConsumer = 0x0C, + PageDigitizer = 0x0D, + PagePidPage = 0x0F, + PageUnicode = 0x10, + PageAlphanumericDisplay = 0x14, + PageMedicalInstruments = 0x40, + PageMonitor0 = 0x80, + PageMonitor1 = 0x81, + PageMonitor2 = 0x82, + PageMonitor3 = 0x83, + PagePower0 = 0x84, + PagePower1 = 0x85, + PagePower2 = 0x86, + PagePower3 = 0x87, + PageBarCodeScanner = 0x8C, + PageScale = 0x8D, + PageMagneticStripeReader = 0x8E, + PageReservedPointOfSale = 0x8F, + PageCameraControl = 0x90, + PageArcade = 0x91, + PageVendor = 0xFF00, + PageMediaCenter = 0xFFBC +}; + +struct HidUsageAndPage { + uint16 usage; + HidPage usage_page; +}; + +struct HidCollectionInfo { + HidUsageAndPage usage; + array<int32> report_ids; +}; + +struct HidDeviceInfo { + string guid; + uint16 vendor_id; + uint16 product_id; + string product_name; + string serial_number; + HidBusType bus_type; + array<uint8> report_descriptor; + array<HidCollectionInfo> collections; + bool has_report_id; + uint64 max_input_report_size; + uint64 max_output_report_size; + uint64 max_feature_report_size; + string device_node; +};
diff --git a/device/hid/public/interfaces/hid.typemap b/device/hid/public/interfaces/hid.typemap new file mode 100644 index 0000000..4ef18a05 --- /dev/null +++ b/device/hid/public/interfaces/hid.typemap
@@ -0,0 +1,22 @@ +# 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. + +mojom = "//device/hid/public/interfaces/hid.mojom" +public_headers = [ + "//device/hid/hid_collection_info.h", + "//device/hid/hid_usage_and_page.h", +] +traits_headers = [ "//device/hid/public/interfaces/hid_struct_traits.h" ] +sources = [ + "//device/hid/public/interfaces/hid_struct_traits.cc", +] +deps = [ + "//mojo/public/cpp/bindings", +] + +type_mappings = [ + "device.mojom.HidPage=device::HidUsageAndPage::Page", + "device.mojom.HidUsageAndPage=device::HidUsageAndPage", + "device.mojom.HidCollectionInfo=device::HidCollectionInfo", +]
diff --git a/device/hid/public/interfaces/hid_struct_traits.cc b/device/hid/public/interfaces/hid_struct_traits.cc new file mode 100644 index 0000000..6c56ca8 --- /dev/null +++ b/device/hid/public/interfaces/hid_struct_traits.cc
@@ -0,0 +1,226 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "device/hid/public/interfaces/hid_struct_traits.h" + +namespace mojo { + +// static +device::mojom::HidPage +EnumTraits<device::mojom::HidPage, device::HidUsageAndPage::Page>::ToMojom( + device::HidUsageAndPage::Page input) { + switch (input) { + case device::HidUsageAndPage::Page::kPageUndefined: + return device::mojom::HidPage::PageUndefined; + case device::HidUsageAndPage::Page::kPageGenericDesktop: + return device::mojom::HidPage::PageGenericDesktop; + case device::HidUsageAndPage::Page::kPageSimulation: + return device::mojom::HidPage::PageSimulation; + case device::HidUsageAndPage::Page::kPageVirtualReality: + return device::mojom::HidPage::PageVirtualReality; + case device::HidUsageAndPage::Page::kPageSport: + return device::mojom::HidPage::PageSport; + case device::HidUsageAndPage::Page::kPageGame: + return device::mojom::HidPage::PageGame; + case device::HidUsageAndPage::Page::kPageKeyboard: + return device::mojom::HidPage::PageKeyboard; + case device::HidUsageAndPage::Page::kPageLed: + return device::mojom::HidPage::PageLed; + case device::HidUsageAndPage::Page::kPageButton: + return device::mojom::HidPage::PageButton; + case device::HidUsageAndPage::Page::kPageOrdinal: + return device::mojom::HidPage::PageOrdinal; + case device::HidUsageAndPage::Page::kPageTelephony: + return device::mojom::HidPage::PageTelephony; + case device::HidUsageAndPage::Page::kPageConsumer: + return device::mojom::HidPage::PageConsumer; + case device::HidUsageAndPage::Page::kPageDigitizer: + return device::mojom::HidPage::PageDigitizer; + case device::HidUsageAndPage::Page::kPagePidPage: + return device::mojom::HidPage::PagePidPage; + case device::HidUsageAndPage::Page::kPageUnicode: + return device::mojom::HidPage::PageUnicode; + case device::HidUsageAndPage::Page::kPageAlphanumericDisplay: + return device::mojom::HidPage::PageAlphanumericDisplay; + case device::HidUsageAndPage::Page::kPageMedicalInstruments: + return device::mojom::HidPage::PageMedicalInstruments; + case device::HidUsageAndPage::Page::kPageMonitor0: + return device::mojom::HidPage::PageMonitor0; + case device::HidUsageAndPage::Page::kPageMonitor1: + return device::mojom::HidPage::PageMonitor1; + case device::HidUsageAndPage::Page::kPageMonitor2: + return device::mojom::HidPage::PageMonitor2; + case device::HidUsageAndPage::Page::kPageMonitor3: + return device::mojom::HidPage::PageMonitor3; + case device::HidUsageAndPage::Page::kPagePower0: + return device::mojom::HidPage::PagePower0; + case device::HidUsageAndPage::Page::kPagePower1: + return device::mojom::HidPage::PagePower1; + case device::HidUsageAndPage::Page::kPagePower2: + return device::mojom::HidPage::PagePower2; + case device::HidUsageAndPage::Page::kPagePower3: + return device::mojom::HidPage::PagePower3; + case device::HidUsageAndPage::Page::kPageBarCodeScanner: + return device::mojom::HidPage::PageBarCodeScanner; + case device::HidUsageAndPage::Page::kPageScale: + return device::mojom::HidPage::PageScale; + case device::HidUsageAndPage::Page::kPageMagneticStripeReader: + return device::mojom::HidPage::PageMagneticStripeReader; + case device::HidUsageAndPage::Page::kPageReservedPointOfSale: + return device::mojom::HidPage::PageReservedPointOfSale; + case device::HidUsageAndPage::Page::kPageCameraControl: + return device::mojom::HidPage::PageCameraControl; + case device::HidUsageAndPage::Page::kPageArcade: + return device::mojom::HidPage::PageArcade; + case device::HidUsageAndPage::Page::kPageVendor: + return device::mojom::HidPage::PageVendor; + case device::HidUsageAndPage::Page::kPageMediaCenter: + return device::mojom::HidPage::PageMediaCenter; + } + + NOTREACHED(); + return device::mojom::HidPage::PageUndefined; +} + +// static +bool EnumTraits<device::mojom::HidPage, device::HidUsageAndPage::Page>:: + FromMojom(device::mojom::HidPage input, + device::HidUsageAndPage::Page* output) { + switch (input) { + case device::mojom::HidPage::PageUndefined: + *output = device::HidUsageAndPage::Page::kPageUndefined; + return true; + case device::mojom::HidPage::PageGenericDesktop: + *output = device::HidUsageAndPage::Page::kPageGenericDesktop; + return true; + case device::mojom::HidPage::PageSimulation: + *output = device::HidUsageAndPage::Page::kPageSimulation; + return true; + case device::mojom::HidPage::PageVirtualReality: + *output = device::HidUsageAndPage::Page::kPageVirtualReality; + return true; + case device::mojom::HidPage::PageSport: + *output = device::HidUsageAndPage::Page::kPageSport; + return true; + case device::mojom::HidPage::PageGame: + *output = device::HidUsageAndPage::Page::kPageGame; + return true; + case device::mojom::HidPage::PageKeyboard: + *output = device::HidUsageAndPage::Page::kPageKeyboard; + return true; + case device::mojom::HidPage::PageLed: + *output = device::HidUsageAndPage::Page::kPageLed; + return true; + case device::mojom::HidPage::PageButton: + *output = device::HidUsageAndPage::Page::kPageButton; + return true; + case device::mojom::HidPage::PageOrdinal: + *output = device::HidUsageAndPage::Page::kPageOrdinal; + return true; + case device::mojom::HidPage::PageTelephony: + *output = device::HidUsageAndPage::Page::kPageTelephony; + return true; + case device::mojom::HidPage::PageConsumer: + *output = device::HidUsageAndPage::Page::kPageConsumer; + return true; + case device::mojom::HidPage::PageDigitizer: + *output = device::HidUsageAndPage::Page::kPageDigitizer; + return true; + case device::mojom::HidPage::PagePidPage: + *output = device::HidUsageAndPage::Page::kPagePidPage; + return true; + case device::mojom::HidPage::PageUnicode: + *output = device::HidUsageAndPage::Page::kPageUnicode; + return true; + case device::mojom::HidPage::PageAlphanumericDisplay: + *output = device::HidUsageAndPage::Page::kPageAlphanumericDisplay; + return true; + case device::mojom::HidPage::PageMedicalInstruments: + *output = device::HidUsageAndPage::Page::kPageMedicalInstruments; + return true; + case device::mojom::HidPage::PageMonitor0: + *output = device::HidUsageAndPage::Page::kPageMonitor0; + return true; + case device::mojom::HidPage::PageMonitor1: + *output = device::HidUsageAndPage::Page::kPageMonitor1; + return true; + case device::mojom::HidPage::PageMonitor2: + *output = device::HidUsageAndPage::Page::kPageMonitor2; + return true; + case device::mojom::HidPage::PageMonitor3: + *output = device::HidUsageAndPage::Page::kPageMonitor3; + return true; + case device::mojom::HidPage::PagePower0: + *output = device::HidUsageAndPage::Page::kPagePower0; + return true; + case device::mojom::HidPage::PagePower1: + *output = device::HidUsageAndPage::Page::kPagePower1; + return true; + case device::mojom::HidPage::PagePower2: + *output = device::HidUsageAndPage::Page::kPagePower2; + return true; + case device::mojom::HidPage::PagePower3: + *output = device::HidUsageAndPage::Page::kPagePower3; + return true; + case device::mojom::HidPage::PageBarCodeScanner: + *output = device::HidUsageAndPage::Page::kPageBarCodeScanner; + return true; + case device::mojom::HidPage::PageScale: + *output = device::HidUsageAndPage::Page::kPageScale; + return true; + case device::mojom::HidPage::PageMagneticStripeReader: + *output = device::HidUsageAndPage::Page::kPageMagneticStripeReader; + return true; + case device::mojom::HidPage::PageReservedPointOfSale: + *output = device::HidUsageAndPage::Page::kPageReservedPointOfSale; + return true; + case device::mojom::HidPage::PageCameraControl: + *output = device::HidUsageAndPage::Page::kPageCameraControl; + return true; + case device::mojom::HidPage::PageArcade: + *output = device::HidUsageAndPage::Page::kPageArcade; + return true; + case device::mojom::HidPage::PageVendor: + *output = device::HidUsageAndPage::Page::kPageVendor; + return true; + case device::mojom::HidPage::PageMediaCenter: + *output = device::HidUsageAndPage::Page::kPageMediaCenter; + return true; + } + + NOTREACHED(); + return false; +} + +// static +bool StructTraits< + device::mojom::HidUsageAndPageDataView, + device::HidUsageAndPage>::Read(device::mojom::HidUsageAndPageDataView data, + device::HidUsageAndPage* out) { + out->usage = data.usage(); + + if (!data.ReadUsagePage(&out->usage_page)) + return false; + + return true; +} + +// static +bool StructTraits<device::mojom::HidCollectionInfoDataView, + device::HidCollectionInfo>:: + Read(device::mojom::HidCollectionInfoDataView data, + device::HidCollectionInfo* out) { + if (!data.ReadUsage(&out->usage)) + return false; + + std::vector<int> vec; + if (!data.ReadReportIds(&vec)) + return false; + + out->report_ids.clear(); + out->report_ids.insert(vec.begin(), vec.end()); + return true; +} + +} // namespace mojo
diff --git a/device/hid/public/interfaces/hid_struct_traits.h b/device/hid/public/interfaces/hid_struct_traits.h new file mode 100644 index 0000000..ff46a4f4 --- /dev/null +++ b/device/hid/public/interfaces/hid_struct_traits.h
@@ -0,0 +1,55 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef DEVICE_HID_PUBLIC_INTERFACES_HID_STRUCT_TRAITS_H_ +#define DEVICE_HID_PUBLIC_INTERFACES_HID_STRUCT_TRAITS_H_ + +#include <stddef.h> + +#include "device/hid/hid_collection_info.h" +#include "device/hid/hid_usage_and_page.h" +#include "device/hid/public/interfaces/hid.mojom.h" +#include "mojo/public/cpp/bindings/array_traits_stl.h" +#include "mojo/public/cpp/bindings/struct_traits.h" + +namespace mojo { + +template <> +struct EnumTraits<device::mojom::HidPage, device::HidUsageAndPage::Page> { + static device::mojom::HidPage ToMojom(device::HidUsageAndPage::Page input); + static bool FromMojom(device::mojom::HidPage input, + device::HidUsageAndPage::Page* output); +}; + +template <> +struct StructTraits<device::mojom::HidUsageAndPageDataView, + device::HidUsageAndPage> { + static uint16_t usage(const device::HidUsageAndPage& r) { return r.usage; } + static const device::HidUsageAndPage::Page& usage_page( + const device::HidUsageAndPage& r) { + return r.usage_page; + } + static bool Read(device::mojom::HidUsageAndPageDataView data, + device::HidUsageAndPage* out); +}; + +template <> +struct StructTraits<device::mojom::HidCollectionInfoDataView, + device::HidCollectionInfo> { + static const device::HidUsageAndPage& usage( + const device::HidCollectionInfo& r) { + return r.usage; + } + + static const std::set<int>& report_ids(const device::HidCollectionInfo& r) { + return r.report_ids; + } + + static bool Read(device::mojom::HidCollectionInfoDataView data, + device::HidCollectionInfo* out); +}; + +} // namespace mojo + +#endif // DEVICE_HID_PUBLIC_INTERFACES_HID_STRUCT_TRAITS_H_
diff --git a/device/hid/public/interfaces/typemaps.gni b/device/hid/public/interfaces/typemaps.gni new file mode 100644 index 0000000..0a40a67 --- /dev/null +++ b/device/hid/public/interfaces/typemaps.gni
@@ -0,0 +1,5 @@ +# 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. + +typemaps = [ "//device/hid/public/interfaces/hid.typemap" ]
diff --git a/device/u2f/u2f_hid_device.cc b/device/u2f/u2f_hid_device.cc index 4e625673..e418667 100644 --- a/device/u2f/u2f_hid_device.cc +++ b/device/u2f/u2f_hid_device.cc
@@ -20,12 +20,11 @@ static constexpr char kEnableU2fHidTest[] = "enable-u2f-hid-tests"; } // namespace switches -U2fHidDevice::U2fHidDevice(scoped_refptr<HidDeviceInfo> device_info) +U2fHidDevice::U2fHidDevice(device::mojom::HidDeviceInfoPtr device_info) : U2fDevice(), state_(State::INIT), - device_info_(device_info), - weak_factory_(this) { -} + device_info_(std::move(device_info)), + weak_factory_(this) {} U2fHidDevice::~U2fHidDevice() { // Cleanup connection @@ -85,7 +84,7 @@ void U2fHidDevice::Connect(const HidService::ConnectCallback& callback) { HidService* hid_service = DeviceClient::Get()->GetHidService(); - hid_service->Connect(device_info_->device_guid(), callback); + hid_service->Connect(device_info_->guid, callback); } void U2fHidDevice::OnConnect(std::unique_ptr<U2fApduCommand> command, @@ -332,7 +331,7 @@ std::string U2fHidDevice::GetId() { std::ostringstream id("hid:", std::ios::ate); - id << device_info_->device_guid(); + id << device_info_->guid; return id.str(); }
diff --git a/device/u2f/u2f_hid_device.h b/device/u2f/u2f_hid_device.h index 64bc0f2..f84030c 100644 --- a/device/u2f/u2f_hid_device.h +++ b/device/u2f/u2f_hid_device.h
@@ -9,6 +9,7 @@ #include "base/cancelable_callback.h" #include "device/hid/hid_service.h" +#include "device/hid/public/interfaces/hid.mojom.h" #include "u2f_device.h" namespace net { @@ -19,11 +20,10 @@ class U2fMessage; class HidConnection; -class HidDeviceInfo; class U2fHidDevice : public U2fDevice { public: - U2fHidDevice(scoped_refptr<HidDeviceInfo>); + U2fHidDevice(device::mojom::HidDeviceInfoPtr); ~U2fHidDevice() final; // Send a U2f command to this device @@ -96,7 +96,7 @@ base::CancelableClosure timeout_callback_; std::list<std::pair<std::unique_ptr<U2fApduCommand>, DeviceCallback>> pending_transactions_; - scoped_refptr<HidDeviceInfo> device_info_; + device::mojom::HidDeviceInfoPtr device_info_; scoped_refptr<HidConnection> connection_; base::WeakPtrFactory<U2fHidDevice> weak_factory_;
diff --git a/device/u2f/u2f_hid_device_unittest.cc b/device/u2f/u2f_hid_device_unittest.cc index fab33990..7d3d556 100644 --- a/device/u2f/u2f_hid_device_unittest.cc +++ b/device/u2f/u2f_hid_device_unittest.cc
@@ -74,13 +74,13 @@ run_loop_() {} ~U2fDeviceEnumerate() {} - void ReceivedCallback( - const std::vector<scoped_refptr<HidDeviceInfo>>& devices) { + void ReceivedCallback(std::vector<device::mojom::HidDeviceInfoPtr> devices) { std::list<std::unique_ptr<U2fHidDevice>> u2f_devices; filter_.SetUsagePage(0xf1d0); - for (auto device_info : devices) { - if (filter_.Matches(device_info)) - u2f_devices.push_front(std::make_unique<U2fHidDevice>(device_info)); + for (auto& device_info : devices) { + if (filter_.Matches(*device_info)) + u2f_devices.push_front( + std::make_unique<U2fHidDevice>(std::move(device_info))); } devices_ = std::move(u2f_devices); closure_.Run(); @@ -220,9 +220,9 @@ MockHidService* hid_service = client->hid_service(); HidCollectionInfo c_info; c_info.usage = HidUsageAndPage(1, static_cast<HidUsageAndPage::Page>(0xf1d0)); - scoped_refptr<HidDeviceInfo> device0 = - new HidDeviceInfo(kTestDeviceId, 0, 0, "Test Fido Device", "123FIDO", - kHIDBusTypeUSB, c_info, 64, 64, 0); + scoped_refptr<HidDeviceInfo> device0 = new HidDeviceInfo( + kTestDeviceId, 0, 0, "Test Fido Device", "123FIDO", + device::mojom::HidBusType::kHIDBusTypeUSB, c_info, 64, 64, 0); hid_service->AddDevice(device0); hid_service->FirstEnumerationComplete(); hid_service->GetDevices(callback.callback()); @@ -265,9 +265,9 @@ MockHidService* hid_service = client->hid_service(); HidCollectionInfo c_info; c_info.usage = HidUsageAndPage(1, static_cast<HidUsageAndPage::Page>(0xf1d0)); - scoped_refptr<HidDeviceInfo> device0 = - new HidDeviceInfo(kTestDeviceId, 0, 0, "Test Fido Device", "123FIDO", - kHIDBusTypeUSB, c_info, 64, 64, 0); + scoped_refptr<HidDeviceInfo> device0 = new HidDeviceInfo( + kTestDeviceId, 0, 0, "Test Fido Device", "123FIDO", + device::mojom::HidBusType::kHIDBusTypeUSB, c_info, 64, 64, 0); hid_service->AddDevice(device0); hid_service->FirstEnumerationComplete(); hid_service->GetDevices(callback.callback());
diff --git a/device/u2f/u2f_request.cc b/device/u2f/u2f_request.cc index efd470b..7fa5472 100644 --- a/device/u2f/u2f_request.cc +++ b/device/u2f/u2f_request.cc
@@ -57,10 +57,11 @@ void U2fRequest::OnEnumerate( HidService* hid_service, - const std::vector<scoped_refptr<HidDeviceInfo>>& devices) { - for (auto device_info : devices) { - if (filter_.Matches(device_info)) - devices_.push_back(std::make_unique<U2fHidDevice>(device_info)); + std::vector<device::mojom::HidDeviceInfoPtr> devices) { + for (auto& device_info : devices) { + if (filter_.Matches(*device_info)) + devices_.push_back( + std::make_unique<U2fHidDevice>(std::move(device_info))); } hid_service_observer_.Add(hid_service); @@ -69,21 +70,21 @@ Transition(); } -void U2fRequest::OnDeviceAdded(scoped_refptr<HidDeviceInfo> device_info) { +void U2fRequest::OnDeviceAdded(device::mojom::HidDeviceInfoPtr device_info) { // Ignore non-U2F devices - if (!filter_.Matches(device_info)) + if (!filter_.Matches(*device_info)) return; - auto device = std::make_unique<U2fHidDevice>(device_info); + auto device = std::make_unique<U2fHidDevice>(std::move(device_info)); AddDevice(std::move(device)); } -void U2fRequest::OnDeviceRemoved(scoped_refptr<HidDeviceInfo> device_info) { +void U2fRequest::OnDeviceRemoved(device::mojom::HidDeviceInfoPtr device_info) { // Ignore non-U2F devices - if (!filter_.Matches(device_info)) + if (!filter_.Matches(*device_info)) return; - auto device = std::make_unique<U2fHidDevice>(device_info); + auto device = std::make_unique<U2fHidDevice>(std::move(device_info)); // Check if the active device was removed if (current_device_ && current_device_->GetId() == device->GetId()) {
diff --git a/device/u2f/u2f_request.h b/device/u2f/u2f_request.h index 6ba2b09..49cec99 100644 --- a/device/u2f/u2f_request.h +++ b/device/u2f/u2f_request.h
@@ -9,6 +9,7 @@ #include "base/scoped_observer.h" #include "device/hid/hid_device_filter.h" #include "device/hid/hid_service.h" +#include "device/hid/public/interfaces/hid.mojom.h" #include "u2f_device.h" namespace device { @@ -50,10 +51,10 @@ void IterateDevice(); void OnWaitComplete(); void AddDevice(std::unique_ptr<U2fDevice> device); - void OnDeviceAdded(scoped_refptr<HidDeviceInfo> device_info) override; - void OnDeviceRemoved(scoped_refptr<HidDeviceInfo> device_info) override; + void OnDeviceAdded(device::mojom::HidDeviceInfoPtr device_info) override; + void OnDeviceRemoved(device::mojom::HidDeviceInfoPtr device_info) override; void OnEnumerate(HidService* hid_service, - const std::vector<scoped_refptr<HidDeviceInfo>>& devices); + std::vector<device::mojom::HidDeviceInfoPtr> devices); std::list<std::unique_ptr<U2fDevice>> devices_; std::list<std::unique_ptr<U2fDevice>> attempted_devices_;
diff --git a/device/u2f/u2f_request_unittest.cc b/device/u2f/u2f_request_unittest.cc index dab7e92..03261a301 100644 --- a/device/u2f/u2f_request_unittest.cc +++ b/device/u2f/u2f_request_unittest.cc
@@ -10,6 +10,7 @@ #include "base/test/test_io_thread.h" #include "device/base/mock_device_client.h" #include "device/hid/mock_hid_service.h" +#include "device/hid/public/interfaces/hid.mojom.h" #include "device/test/test_device_client.h" #include "device/test/usb_test_gadget.h" #include "device/u2f/u2f_hid_device.h" @@ -87,9 +88,10 @@ request.Enumerate(); c_info.usage = HidUsageAndPage(1, static_cast<HidUsageAndPage::Page>(0xf1d0)); - scoped_refptr<HidDeviceInfo> u2f_device_0 = make_scoped_refptr( - new HidDeviceInfo(kTestDeviceId0, 0, 0, "Test Fido Device", "123FIDO", - kHIDBusTypeUSB, c_info, 64, 64, 0)); + scoped_refptr<HidDeviceInfo> u2f_device_0 = + make_scoped_refptr(new HidDeviceInfo( + kTestDeviceId0, 0, 0, "Test Fido Device", "123FIDO", + device::mojom::HidBusType::kHIDBusTypeUSB, c_info, 64, 64, 0)); hid_service->AddDevice(u2f_device_0); // Make sure the enumeration is finshed, so HidService is ready to send @@ -98,16 +100,18 @@ EXPECT_EQ(static_cast<size_t>(0), request.devices_.size()); // Add one U2F device - scoped_refptr<HidDeviceInfo> u2f_device_1 = make_scoped_refptr( - new HidDeviceInfo(kTestDeviceId1, 0, 0, "Test Fido Device", "123FIDO", - kHIDBusTypeUSB, c_info, 64, 64, 0)); + scoped_refptr<HidDeviceInfo> u2f_device_1 = + make_scoped_refptr(new HidDeviceInfo( + kTestDeviceId1, 0, 0, "Test Fido Device", "123FIDO", + device::mojom::HidBusType::kHIDBusTypeUSB, c_info, 64, 64, 0)); hid_service->AddDevice(u2f_device_1); EXPECT_EQ(static_cast<size_t>(1), request.devices_.size()); // Add one non-U2F device. Verify that it is not added to our device list. - scoped_refptr<HidDeviceInfo> other_device = make_scoped_refptr( - new HidDeviceInfo(kTestDeviceId2, 0, 0, "Other Device", "OtherDevice", - kHIDBusTypeUSB, std::vector<uint8_t>())); + scoped_refptr<HidDeviceInfo> other_device = + make_scoped_refptr(new HidDeviceInfo( + kTestDeviceId2, 0, 0, "Other Device", "OtherDevice", + device::mojom::HidBusType::kHIDBusTypeUSB, std::vector<uint8_t>())); hid_service->AddDevice(other_device); EXPECT_EQ(static_cast<size_t>(1), request.devices_.size()); @@ -126,14 +130,16 @@ HidCollectionInfo c_info; // Add one U2F device and one non-U2f device c_info.usage = HidUsageAndPage(1, static_cast<HidUsageAndPage::Page>(0xf1d0)); - scoped_refptr<HidDeviceInfo> device0 = make_scoped_refptr( - new HidDeviceInfo(kTestDeviceId0, 0, 0, "Test Fido Device", "123FIDO", - kHIDBusTypeUSB, c_info, 64, 64, 0)); - request.devices_.push_back(std::make_unique<U2fHidDevice>(device0)); - scoped_refptr<HidDeviceInfo> device1 = make_scoped_refptr( - new HidDeviceInfo(kTestDeviceId1, 0, 0, "Test Fido Device", "123FIDO", - kHIDBusTypeUSB, c_info, 64, 64, 0)); - request.devices_.push_back(std::make_unique<U2fHidDevice>(device1)); + scoped_refptr<HidDeviceInfo> device0 = make_scoped_refptr(new HidDeviceInfo( + kTestDeviceId0, 0, 0, "Test Fido Device", "123FIDO", + device::mojom::HidBusType::kHIDBusTypeUSB, c_info, 64, 64, 0)); + request.devices_.push_back( + std::make_unique<U2fHidDevice>(device0->device()->Clone())); + scoped_refptr<HidDeviceInfo> device1 = make_scoped_refptr(new HidDeviceInfo( + kTestDeviceId1, 0, 0, "Test Fido Device", "123FIDO", + device::mojom::HidBusType::kHIDBusTypeUSB, c_info, 64, 64, 0)); + request.devices_.push_back( + std::make_unique<U2fHidDevice>(device1->device()->Clone())); // Move first device to current request.IterateDevice(); @@ -162,9 +168,10 @@ // Add one U2F device HidCollectionInfo c_info; c_info.usage = HidUsageAndPage(1, static_cast<HidUsageAndPage::Page>(0xf1d0)); - scoped_refptr<HidDeviceInfo> u2f_device = make_scoped_refptr( - new HidDeviceInfo(kTestDeviceId0, 0, 0, "Test Fido Device", "123FIDO", - kHIDBusTypeUSB, c_info, 64, 64, 0)); + scoped_refptr<HidDeviceInfo> u2f_device = + make_scoped_refptr(new HidDeviceInfo( + kTestDeviceId0, 0, 0, "Test Fido Device", "123FIDO", + device::mojom::HidBusType::kHIDBusTypeUSB, c_info, 64, 64, 0)); hid_service->AddDevice(u2f_device); cb.WaitForCallback(); EXPECT_EQ(U2fRequest::State::BUSY, request.state_);
diff --git a/extensions/browser/api/device_permissions_manager.cc b/extensions/browser/api/device_permissions_manager.cc index bfb10dd..b6dda62 100644 --- a/extensions/browser/api/device_permissions_manager.cc +++ b/extensions/browser/api/device_permissions_manager.cc
@@ -17,8 +17,6 @@ #include "components/keyed_service/content/browser_context_dependency_manager.h" #include "content/public/browser/browser_thread.h" #include "device/base/device_client.h" -#include "device/hid/hid_device_info.h" -#include "device/hid/hid_service.h" #include "device/usb/usb_device.h" #include "device/usb/usb_ids.h" #include "extensions/browser/api/hid/hid_device_manager.h" @@ -33,7 +31,6 @@ using content::BrowserContext; using content::BrowserThread; -using device::HidDeviceInfo; using device::HidService; using device::UsbDevice; using device::UsbService; @@ -279,14 +276,13 @@ } DevicePermissionEntry::DevicePermissionEntry( - scoped_refptr<HidDeviceInfo> device) - : hid_device_(device), + const device::mojom::HidDeviceInfo& device) + : hid_device_guid_(device.guid), type_(Type::HID), - vendor_id_(device->vendor_id()), - product_id_(device->product_id()), - serial_number_(base::UTF8ToUTF16(device->serial_number())), - product_string_(base::UTF8ToUTF16(device->product_name())) { -} + vendor_id_(device.vendor_id), + product_id_(device.product_id), + serial_number_(base::UTF8ToUTF16(device.serial_number)), + product_string_(base::UTF8ToUTF16(device.product_name)) {} DevicePermissionEntry::DevicePermissionEntry( Type type, @@ -374,21 +370,20 @@ } scoped_refptr<DevicePermissionEntry> DevicePermissions::FindHidDeviceEntry( - scoped_refptr<HidDeviceInfo> device) const { - const auto& ephemeral_device_entry = - ephemeral_hid_devices_.find(device.get()); + const device::mojom::HidDeviceInfo& device) const { + const auto& ephemeral_device_entry = ephemeral_hid_devices_.find(device.guid); if (ephemeral_device_entry != ephemeral_hid_devices_.end()) { return ephemeral_device_entry->second; } - if (device->serial_number().empty()) { + if (device.serial_number.empty()) { return nullptr; } - base::string16 serial_number = base::UTF8ToUTF16(device->serial_number()); + base::string16 serial_number = base::UTF8ToUTF16(device.serial_number); for (const auto& entry : entries_) { - if (entry->IsPersistent() && entry->vendor_id() == device->vendor_id() && - entry->product_id() == device->product_id() && + if (entry->IsPersistent() && entry->vendor_id() == device.vendor_id && + entry->product_id() == device.product_id && entry->serial_number() == serial_number) { return entry; } @@ -563,7 +558,7 @@ void DevicePermissionsManager::AllowHidDevice( const std::string& extension_id, - scoped_refptr<HidDeviceInfo> device) { + const device::mojom::HidDeviceInfo& device) { DCHECK(thread_checker_.CalledOnValidThread()); DevicePermissions* device_permissions = GetForExtension(extension_id); @@ -582,12 +577,12 @@ device_permissions->entries_.insert(device_entry); SaveDevicePermissionEntry(context_, extension_id, device_entry); } else if (!ContainsKey(device_permissions->ephemeral_hid_devices_, - device.get())) { + device.guid)) { // Non-persistent devices cannot be reliably identified when they are // reconnected so such devices are only remembered until disconnect. // Register an observer here so that this set doesn't grow undefinitely. device_permissions->entries_.insert(device_entry); - device_permissions->ephemeral_hid_devices_[device.get()] = device_entry; + device_permissions->ephemeral_hid_devices_[device.guid] = device_entry; // Make sure the HidDeviceManager is active. HidDeviceManager is // responsible for removing the permission entry for an ephemeral hid @@ -621,7 +616,7 @@ } else if (entry->type_ == DevicePermissionEntry::Type::USB) { device_permissions->ephemeral_usb_devices_.erase(entry->usb_device_.get()); } else if (entry->type_ == DevicePermissionEntry::Type::HID) { - device_permissions->ephemeral_hid_devices_.erase(entry->hid_device_.get()); + device_permissions->ephemeral_hid_devices_.erase(entry->hid_device_guid_); } else { NOTREACHED(); } @@ -676,15 +671,15 @@ } } -void DevicePermissionsManager::RemoveEntryForEphemeralHidDevice( - scoped_refptr<device::HidDeviceInfo> device) { +void DevicePermissionsManager::RemoveEntryByHidDeviceGUID( + const std::string& guid) { DCHECK(thread_checker_.CalledOnValidThread()); for (const auto& map_entry : extension_id_to_device_permissions_) { // An ephemeral device cannot be identified if it is reconnected and so // permission to access it is cleared on disconnect. DevicePermissions* device_permissions = map_entry.second; const auto& device_entry = - device_permissions->ephemeral_hid_devices_.find(device.get()); + device_permissions->ephemeral_hid_devices_.find(guid); if (device_entry != device_permissions->ephemeral_hid_devices_.end()) { device_permissions->entries_.erase(device_entry->second); device_permissions->ephemeral_hid_devices_.erase(device_entry);
diff --git a/extensions/browser/api/device_permissions_manager.h b/extensions/browser/api/device_permissions_manager.h index 4d5dce4..72e68128 100644 --- a/extensions/browser/api/device_permissions_manager.h +++ b/extensions/browser/api/device_permissions_manager.h
@@ -21,6 +21,7 @@ #include "components/keyed_service/content/browser_context_keyed_service_factory.h" #include "components/keyed_service/core/keyed_service.h" #include "device/hid/hid_service.h" +#include "device/hid/public/interfaces/hid.mojom.h" #include "device/usb/usb_service.h" namespace base { @@ -44,7 +45,8 @@ }; DevicePermissionEntry(scoped_refptr<device::UsbDevice> device); - DevicePermissionEntry(scoped_refptr<device::HidDeviceInfo> device); + + DevicePermissionEntry(const device::mojom::HidDeviceInfo& device); DevicePermissionEntry(Type type, uint16_t vendor_id, uint16_t product_id, @@ -84,10 +86,9 @@ // The USB device tracked by this entry. Will be nullptr if this entry was // restored from ExtensionPrefs or type_ is not Type::USB. scoped_refptr<device::UsbDevice> usb_device_; - // The HID device tracked by this entry. Will be nullptr if this entry was - // restored from ExtensionPrefs or type_ is not Type::HID. - scoped_refptr<device::HidDeviceInfo> hid_device_; + // The device guid of hid device tracked by this entry. + std::string hid_device_guid_; // The type of device this entry represents. Type type_; // The vendor ID of this device. @@ -113,7 +114,7 @@ scoped_refptr<DevicePermissionEntry> FindUsbDeviceEntry( scoped_refptr<device::UsbDevice> device) const; scoped_refptr<DevicePermissionEntry> FindHidDeviceEntry( - scoped_refptr<device::HidDeviceInfo> device) const; + const device::mojom::HidDeviceInfo& device) const; const std::set<scoped_refptr<DevicePermissionEntry>>& entries() const { return entries_; @@ -129,7 +130,7 @@ std::set<scoped_refptr<DevicePermissionEntry>> entries_; std::map<device::UsbDevice*, scoped_refptr<DevicePermissionEntry>> ephemeral_usb_devices_; - std::map<device::HidDeviceInfo*, scoped_refptr<DevicePermissionEntry>> + std::map<std::string, scoped_refptr<DevicePermissionEntry>> ephemeral_hid_devices_; DISALLOW_COPY_AND_ASSIGN(DevicePermissions); @@ -137,8 +138,7 @@ // Manages saved device permissions for all extensions. class DevicePermissionsManager : public KeyedService, - public device::UsbService::Observer, - public device::HidService::Observer { + public device::UsbService::Observer { public: static DevicePermissionsManager* Get(content::BrowserContext* context); @@ -161,7 +161,7 @@ void AllowUsbDevice(const std::string& extension_id, scoped_refptr<device::UsbDevice> device); void AllowHidDevice(const std::string& extension_id, - scoped_refptr<device::HidDeviceInfo> device); + const device::mojom::HidDeviceInfo& device); // Updates the "last used" timestamp on the given device entry and writes it // out to ExtensionPrefs. @@ -172,9 +172,9 @@ void RemoveEntry(const std::string& extension_id, scoped_refptr<DevicePermissionEntry> entry); - // Revokes permission for an ephemeral hid device. - void RemoveEntryForEphemeralHidDevice( - scoped_refptr<device::HidDeviceInfo> device); + // Revokes permission for an ephemeral hid device by its guid. + + void RemoveEntryByHidDeviceGUID(const std::string& guid); // Revokes permission for the extension to access all allowed devices. void Clear(const std::string& extension_id);
diff --git a/extensions/browser/api/device_permissions_prompt.cc b/extensions/browser/api/device_permissions_prompt.cc index 139492e..9b3cbe8 100644 --- a/extensions/browser/api/device_permissions_prompt.cc +++ b/extensions/browser/api/device_permissions_prompt.cc
@@ -14,8 +14,8 @@ #include "build/build_config.h" #include "device/base/device_client.h" #include "device/hid/hid_device_filter.h" -#include "device/hid/hid_device_info.h" #include "device/hid/hid_service.h" +#include "device/hid/public/interfaces/hid.mojom.h" #include "device/usb/public/cpp/filter_utils.h" #include "device/usb/usb_device.h" #include "device/usb/usb_ids.h" @@ -27,7 +27,6 @@ #if defined(OS_CHROMEOS) #include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/dbus/permission_broker_client.h" -#include "device/hid/hid_device_info_linux.h" #endif // defined(OS_CHROMEOS) using device::HidDeviceFilter; @@ -40,8 +39,7 @@ namespace { -void NoopHidCallback(const std::vector<scoped_refptr<device::HidDeviceInfo>>&) { -} +void NoopHidCallback(std::vector<device::mojom::HidDeviceInfoPtr>) {} void NoopUsbCallback(const std::vector<scoped_refptr<device::UsbDevice>>&) {} @@ -158,23 +156,23 @@ class HidDeviceInfo : public DevicePermissionsPrompt::Prompt::DeviceInfo { public: - explicit HidDeviceInfo(scoped_refptr<device::HidDeviceInfo> device) - : device_(device) { + explicit HidDeviceInfo(device::mojom::HidDeviceInfoPtr device) + : device_(std::move(device)) { name_ = DevicePermissionsManager::GetPermissionMessage( - device->vendor_id(), device->product_id(), + device_->vendor_id, device_->product_id, base::string16(), // HID devices include manufacturer in product name. - base::UTF8ToUTF16(device->product_name()), + base::UTF8ToUTF16(device_->product_name), base::string16(), // Serial number is displayed separately. false); - serial_number_ = base::UTF8ToUTF16(device->serial_number()); + serial_number_ = base::UTF8ToUTF16(device_->serial_number); } ~HidDeviceInfo() override {} - const scoped_refptr<device::HidDeviceInfo>& device() const { return device_; } + device::mojom::HidDeviceInfoPtr& device() { return device_; } private: - scoped_refptr<device::HidDeviceInfo> device_; + device::mojom::HidDeviceInfoPtr device_; }; class HidDevicePermissionsPrompt : public DevicePermissionsPrompt::Prompt, @@ -211,36 +209,34 @@ void Dismissed() override { DevicePermissionsManager* permissions_manager = DevicePermissionsManager::Get(browser_context()); - std::vector<scoped_refptr<device::HidDeviceInfo>> devices; + std::vector<device::mojom::HidDeviceInfoPtr> devices; for (const auto& device : devices_) { if (device->granted()) { - const HidDeviceInfo* hid_device = - static_cast<const HidDeviceInfo*>(device.get()); - devices.push_back(hid_device->device()); + HidDeviceInfo* hid_device = static_cast<HidDeviceInfo*>(device.get()); if (permissions_manager) { + DCHECK(hid_device->device()); permissions_manager->AllowHidDevice(extension()->id(), - hid_device->device()); + *(hid_device->device())); } + devices.push_back(std::move(hid_device->device())); } } DCHECK(multiple() || devices.size() <= 1); - callback_.Run(devices); + callback_.Run(std::move(devices)); callback_.Reset(); } // device::HidService::Observer implementation: - void OnDeviceAdded(scoped_refptr<device::HidDeviceInfo> device) override { - if (HasUnprotectedCollections(device) && - (filters_.empty() || HidDeviceFilter::MatchesAny(device, filters_))) { - std::unique_ptr<DeviceInfo> device_info(new HidDeviceInfo(device)); + void OnDeviceAdded(device::mojom::HidDeviceInfoPtr device) override { + if (HasUnprotectedCollections(*device) && + (filters_.empty() || HidDeviceFilter::MatchesAny(*device, filters_))) { + auto device_info = base::MakeUnique<HidDeviceInfo>(std::move(device)); #if defined(OS_CHROMEOS) chromeos::PermissionBrokerClient* client = chromeos::DBusThreadManager::Get()->GetPermissionBrokerClient(); DCHECK(client) << "Could not get permission broker client."; - device::HidDeviceInfoLinux* linux_device_info = - static_cast<device::HidDeviceInfoLinux*>(device.get()); client->CheckPathAccess( - linux_device_info->device_node(), + device_info.get()->device()->device_node, base::Bind(&HidDevicePermissionsPrompt::AddCheckedDevice, this, base::Passed(&device_info))); #else @@ -249,11 +245,10 @@ } } - void OnDeviceRemoved(scoped_refptr<device::HidDeviceInfo> device) override { + void OnDeviceRemoved(device::mojom::HidDeviceInfoPtr device) override { for (auto it = devices_.begin(); it != devices_.end(); ++it) { - const HidDeviceInfo* entry = - static_cast<const HidDeviceInfo*>((*it).get()); - if (entry->device() == device) { + HidDeviceInfo* entry = static_cast<HidDeviceInfo*>((*it).get()); + if (entry->device()->guid == device->guid) { size_t index = it - devices_.begin(); base::string16 device_name = (*it)->name(); devices_.erase(it); @@ -266,15 +261,15 @@ void OnDevicesEnumerated( HidService* service, - const std::vector<scoped_refptr<device::HidDeviceInfo>>& devices) { - for (const auto& device : devices) { - OnDeviceAdded(device); + std::vector<device::mojom::HidDeviceInfoPtr> devices) { + for (auto& device : devices) { + OnDeviceAdded(std::move(device)); } service_observer_.Add(service); } - bool HasUnprotectedCollections(scoped_refptr<device::HidDeviceInfo> device) { - for (const auto& collection : device->collections()) { + bool HasUnprotectedCollections(const device::mojom::HidDeviceInfo& device) { + for (const auto& collection : device.collections) { if (!collection.usage.IsProtected()) { return true; }
diff --git a/extensions/browser/api/device_permissions_prompt.h b/extensions/browser/api/device_permissions_prompt.h index d2502f5..0d47060 100644 --- a/extensions/browser/api/device_permissions_prompt.h +++ b/extensions/browser/api/device_permissions_prompt.h
@@ -15,6 +15,7 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/strings/string16.h" +#include "device/hid/public/interfaces/hid.mojom.h" #include "device/usb/public/interfaces/device_manager.mojom.h" namespace content { @@ -24,7 +25,6 @@ namespace device { class HidDeviceFilter; -class HidDeviceInfo; class UsbDevice; } @@ -38,8 +38,8 @@ public: using UsbDevicesCallback = base::Callback<void( const std::vector<scoped_refptr<device::UsbDevice>>&)>; - using HidDevicesCallback = base::Callback<void( - const std::vector<scoped_refptr<device::HidDeviceInfo>>&)>; + using HidDevicesCallback = + base::Callback<void(std::vector<device::mojom::HidDeviceInfoPtr>)>; // Context information available to the UI implementation. class Prompt : public base::RefCounted<Prompt> {
diff --git a/extensions/browser/api/hid/hid_api.cc b/extensions/browser/api/hid/hid_api.cc index 1c283b68..3f64ca56 100644 --- a/extensions/browser/api/hid/hid_api.cc +++ b/extensions/browser/api/hid/hid_api.cc
@@ -15,7 +15,6 @@ #include "device/base/device_client.h" #include "device/hid/hid_connection.h" #include "device/hid/hid_device_filter.h" -#include "device/hid/hid_device_info.h" #include "device/hid/hid_service.h" #include "extensions/browser/api/api_resource_manager.h" #include "extensions/browser/api/device_permissions_prompt.h" @@ -27,7 +26,6 @@ using device::HidConnection; using device::HidDeviceFilter; -using device::HidDeviceInfo; using device::HidService; namespace { @@ -144,10 +142,11 @@ } void HidGetUserSelectedDevicesFunction::OnDevicesChosen( - const std::vector<scoped_refptr<HidDeviceInfo>>& devices) { + std::vector<device::mojom::HidDeviceInfoPtr> devices) { HidDeviceManager* device_manager = HidDeviceManager::Get(browser_context()); CHECK(device_manager); - Respond(OneArgument(device_manager->GetApiDevicesFromList(devices))); + Respond( + OneArgument(device_manager->GetApiDevicesFromList(std::move(devices)))); } HidConnectFunction::HidConnectFunction() : connection_manager_(nullptr) { @@ -167,13 +166,13 @@ ApiResourceManager<HidConnectionResource>::Get(browser_context()); CHECK(connection_manager_); - scoped_refptr<HidDeviceInfo> device_info = + const device::mojom::HidDeviceInfo* device_info = device_manager->GetDeviceInfo(parameters->device_id); if (!device_info) { return RespondNow(Error(kErrorInvalidDeviceId)); } - if (!device_manager->HasPermission(extension(), device_info, true)) { + if (!device_manager->HasPermission(extension(), *device_info, true)) { return RespondNow(Error(kErrorPermissionDenied)); } @@ -181,7 +180,7 @@ CHECK(hid_service); hid_service->Connect( - device_info->device_guid(), + device_info->guid, base::Bind(&HidConnectFunction::OnConnectComplete, this)); return RespondLater(); }
diff --git a/extensions/browser/api/hid/hid_api.h b/extensions/browser/api/hid/hid_api.h index 1d00566..8b53659 100644 --- a/extensions/browser/api/hid/hid_api.h +++ b/extensions/browser/api/hid/hid_api.h
@@ -12,6 +12,7 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" +#include "device/hid/public/interfaces/hid.mojom.h" #include "extensions/browser/api/api_resource_manager.h" #include "extensions/browser/api/hid/hid_connection_resource.h" #include "extensions/browser/api/hid/hid_device_manager.h" @@ -20,7 +21,6 @@ namespace device { class HidConnection; -class HidDeviceInfo; } // namespace device namespace net { @@ -61,8 +61,7 @@ // ExtensionFunction: ResponseAction Run() override; - void OnDevicesChosen( - const std::vector<scoped_refptr<device::HidDeviceInfo>>& devices); + void OnDevicesChosen(std::vector<device::mojom::HidDeviceInfoPtr> devices); std::unique_ptr<DevicePermissionsPrompt> prompt_;
diff --git a/extensions/browser/api/hid/hid_apitest.cc b/extensions/browser/api/hid/hid_apitest.cc index b9360fe..2067ccaf 100644 --- a/extensions/browser/api/hid/hid_apitest.cc +++ b/extensions/browser/api/hid/hid_apitest.cc
@@ -17,6 +17,7 @@ #include "device/hid/hid_device_info.h" #include "device/hid/hid_usage_and_page.h" #include "device/hid/mock_hid_service.h" +#include "device/hid/public/interfaces/hid.mojom.h" #include "extensions/browser/api/device_permissions_prompt.h" #include "extensions/shell/browser/shell_extensions_api_client.h" #include "extensions/shell/test/shell_apitest.h" @@ -225,7 +226,7 @@ } device_client_->hid_service()->AddDevice(new HidDeviceInfo( platform_device_id, vendor_id, product_id, "Test Device", serial_number, - device::kHIDBusTypeUSB, report_descriptor)); + device::mojom::HidBusType::kHIDBusTypeUSB, report_descriptor)); } protected:
diff --git a/extensions/browser/api/hid/hid_device_manager.cc b/extensions/browser/api/hid/hid_device_manager.cc index bb584cbd0..6dd60dc 100644 --- a/extensions/browser/api/hid/hid_device_manager.cc +++ b/extensions/browser/api/hid/hid_device_manager.cc
@@ -25,7 +25,6 @@ namespace hid = extensions::api::hid; using device::HidDeviceFilter; -using device::HidDeviceInfo; using device::HidService; namespace extensions { @@ -33,16 +32,16 @@ namespace { void PopulateHidDeviceInfo(hid::HidDeviceInfo* output, - scoped_refptr<const HidDeviceInfo> input) { - output->vendor_id = input->vendor_id(); - output->product_id = input->product_id(); - output->product_name = input->product_name(); - output->serial_number = input->serial_number(); - output->max_input_report_size = input->max_input_report_size(); - output->max_output_report_size = input->max_output_report_size(); - output->max_feature_report_size = input->max_feature_report_size(); + const device::mojom::HidDeviceInfo& input) { + output->vendor_id = input.vendor_id; + output->product_id = input.product_id; + output->product_name = input.product_name; + output->serial_number = input.serial_number; + output->max_input_report_size = input.max_input_report_size; + output->max_output_report_size = input.max_output_report_size; + output->max_feature_report_size = input.max_feature_report_size; - for (const device::HidCollectionInfo& collection : input->collections()) { + for (const device::HidCollectionInfo& collection : input.collections) { // Don't expose sensitive data. if (collection.usage.IsProtected()) { continue; @@ -59,7 +58,7 @@ output->collections.push_back(std::move(api_collection)); } - const std::vector<uint8_t>& report_descriptor = input->report_descriptor(); + const std::vector<uint8_t>& report_descriptor = input.report_descriptor; if (report_descriptor.size() > 0) { output->report_descriptor.assign(report_descriptor.begin(), report_descriptor.end()); @@ -67,7 +66,7 @@ } bool WillDispatchDeviceEvent(base::WeakPtr<HidDeviceManager> device_manager, - scoped_refptr<device::HidDeviceInfo> device_info, + const device::mojom::HidDeviceInfo& device_info, content::BrowserContext* context, const Extension* extension, Event* event, @@ -135,38 +134,38 @@ } std::unique_ptr<base::ListValue> HidDeviceManager::GetApiDevicesFromList( - const std::vector<scoped_refptr<HidDeviceInfo>>& devices) { + std::vector<device::mojom::HidDeviceInfoPtr> devices) { DCHECK(thread_checker_.CalledOnValidThread()); std::unique_ptr<base::ListValue> device_list(new base::ListValue()); for (const auto& device : devices) { - const auto device_entry = resource_ids_.find(device->device_guid()); + const auto device_entry = resource_ids_.find(device->guid); DCHECK(device_entry != resource_ids_.end()); hid::HidDeviceInfo device_info; device_info.device_id = device_entry->second; - PopulateHidDeviceInfo(&device_info, device); + PopulateHidDeviceInfo(&device_info, *device); device_list->Append(device_info.ToValue()); } return device_list; } -scoped_refptr<HidDeviceInfo> HidDeviceManager::GetDeviceInfo(int resource_id) { +const device::mojom::HidDeviceInfo* HidDeviceManager::GetDeviceInfo( + int resource_id) { DCHECK(thread_checker_.CalledOnValidThread()); - HidService* hid_service = device::DeviceClient::Get()->GetHidService(); - DCHECK(hid_service); - ResourceIdToDeviceIdMap::const_iterator device_iter = - device_ids_.find(resource_id); - if (device_iter == device_ids_.end()) { + ResourceIdToDeviceInfoMap::const_iterator device_iter = + devices_.find(resource_id); + if (device_iter == devices_.end()) { return nullptr; } - return hid_service->GetDeviceInfo(device_iter->second); + return device_iter->second.get(); } -bool HidDeviceManager::HasPermission(const Extension* extension, - scoped_refptr<HidDeviceInfo> device_info, - bool update_last_used) { +bool HidDeviceManager::HasPermission( + const Extension* extension, + const device::mojom::HidDeviceInfo& device_info, + bool update_last_used) { DevicePermissionsManager* permissions_manager = DevicePermissionsManager::Get(browser_context_); CHECK(permissions_manager); @@ -184,7 +183,7 @@ std::unique_ptr<UsbDevicePermission::CheckParam> usb_param = UsbDevicePermission::CheckParam::ForHidDevice( - extension, device_info->vendor_id(), device_info->product_id()); + extension, device_info.vendor_id, device_info.product_id); if (extension->permissions_data()->CheckAPIPermissionWithParam( APIPermission::kUsbDevice, usb_param.get())) { return true; @@ -211,55 +210,53 @@ void HidDeviceManager::OnListenerAdded(const EventListenerInfo& details) { LazyInitialize(); } - -void HidDeviceManager::OnDeviceAdded(scoped_refptr<HidDeviceInfo> device_info) { +void HidDeviceManager::OnDeviceAdded(device::mojom::HidDeviceInfoPtr device) { DCHECK(thread_checker_.CalledOnValidThread()); DCHECK_LT(next_resource_id_, std::numeric_limits<int>::max()); int new_id = next_resource_id_++; - DCHECK(!base::ContainsKey(resource_ids_, device_info->device_guid())); - resource_ids_[device_info->device_guid()] = new_id; - device_ids_[new_id] = device_info->device_guid(); + DCHECK(!base::ContainsKey(resource_ids_, device->guid)); + resource_ids_[device->guid] = new_id; + devices_[new_id] = std::move(device); // Don't generate events during the initial enumeration. if (enumeration_ready_ && event_router_) { api::hid::HidDeviceInfo api_device_info; api_device_info.device_id = new_id; - PopulateHidDeviceInfo(&api_device_info, device_info); + + PopulateHidDeviceInfo(&api_device_info, *devices_[new_id]); if (api_device_info.collections.size() > 0) { std::unique_ptr<base::ListValue> args( hid::OnDeviceAdded::Create(api_device_info)); DispatchEvent(events::HID_ON_DEVICE_ADDED, hid::OnDeviceAdded::kEventName, - std::move(args), device_info); + std::move(args), *devices_[new_id]); } } } -void HidDeviceManager::OnDeviceRemoved( - scoped_refptr<HidDeviceInfo> device_info) { +void HidDeviceManager::OnDeviceRemoved(device::mojom::HidDeviceInfoPtr device) { DCHECK(thread_checker_.CalledOnValidThread()); - const auto& resource_entry = resource_ids_.find(device_info->device_guid()); + const auto& resource_entry = resource_ids_.find(device->guid); DCHECK(resource_entry != resource_ids_.end()); int resource_id = resource_entry->second; - const auto& device_entry = device_ids_.find(resource_id); - DCHECK(device_entry != device_ids_.end()); + const auto& device_entry = devices_.find(resource_id); + DCHECK(device_entry != devices_.end()); resource_ids_.erase(resource_entry); - device_ids_.erase(device_entry); + devices_.erase(device_entry); if (event_router_) { DCHECK(enumeration_ready_); std::unique_ptr<base::ListValue> args( hid::OnDeviceRemoved::Create(resource_id)); DispatchEvent(events::HID_ON_DEVICE_REMOVED, - hid::OnDeviceRemoved::kEventName, std::move(args), - device_info); + hid::OnDeviceRemoved::kEventName, std::move(args), *device); } // Remove permission entry for ephemeral hid device. DevicePermissionsManager* permissions_manager = DevicePermissionsManager::Get(browser_context_); DCHECK(permissions_manager); - permissions_manager->RemoveEntryForEphemeralHidDevice(device_info); + permissions_manager->RemoveEntryByHidDeviceGUID(device->guid); } void HidDeviceManager::LazyInitialize() { @@ -280,32 +277,23 @@ std::unique_ptr<base::ListValue> HidDeviceManager::CreateApiDeviceList( const Extension* extension, const std::vector<HidDeviceFilter>& filters) { - HidService* hid_service = device::DeviceClient::Get()->GetHidService(); - DCHECK(hid_service); - std::unique_ptr<base::ListValue> api_devices(new base::ListValue()); - for (const ResourceIdToDeviceIdMap::value_type& map_entry : device_ids_) { + for (const ResourceIdToDeviceInfoMap::value_type& map_entry : devices_) { int resource_id = map_entry.first; - const std::string& device_guid = map_entry.second; - - scoped_refptr<HidDeviceInfo> device_info = - hid_service->GetDeviceInfo(device_guid); - if (!device_info) { - continue; - } + auto& device_info = map_entry.second; if (!filters.empty() && - !HidDeviceFilter::MatchesAny(device_info, filters)) { + !HidDeviceFilter::MatchesAny(*device_info, filters)) { continue; } - if (!HasPermission(extension, device_info, false)) { + if (!HasPermission(extension, *device_info, false)) { continue; } hid::HidDeviceInfo api_device_info; api_device_info.device_id = resource_id; - PopulateHidDeviceInfo(&api_device_info, device_info); + PopulateHidDeviceInfo(&api_device_info, *device_info); // Expose devices with which user can communicate. if (api_device_info.collections.size() > 0) { @@ -318,11 +306,11 @@ void HidDeviceManager::OnEnumerationComplete( HidService* hid_service, - const std::vector<scoped_refptr<HidDeviceInfo>>& devices) { + std::vector<device::mojom::HidDeviceInfoPtr> devices) { DCHECK(resource_ids_.empty()); - DCHECK(device_ids_.empty()); - for (const scoped_refptr<HidDeviceInfo>& device_info : devices) { - OnDeviceAdded(device_info); + DCHECK(devices_.empty()); + for (auto& device_info : devices) { + OnDeviceAdded(std::move(device_info)); } enumeration_ready_ = true; @@ -340,11 +328,14 @@ events::HistogramValue histogram_value, const std::string& event_name, std::unique_ptr<base::ListValue> event_args, - scoped_refptr<HidDeviceInfo> device_info) { + const device::mojom::HidDeviceInfo& device_info) { std::unique_ptr<Event> event( new Event(histogram_value, event_name, std::move(event_args))); - event->will_dispatch_callback = base::Bind( - &WillDispatchDeviceEvent, weak_factory_.GetWeakPtr(), device_info); + // The |event->will_dispatch_callback| will be called synchronously, it is + // safe to pass |device_info| by reference. + event->will_dispatch_callback = + base::Bind(&WillDispatchDeviceEvent, weak_factory_.GetWeakPtr(), + base::ConstRef(device_info)); event_router_->BroadcastEvent(std::move(event)); }
diff --git a/extensions/browser/api/hid/hid_device_manager.h b/extensions/browser/api/hid/hid_device_manager.h index 5197a4b..a311381 100644 --- a/extensions/browser/api/hid/hid_device_manager.h +++ b/extensions/browser/api/hid/hid_device_manager.h
@@ -14,6 +14,7 @@ #include "base/scoped_observer.h" #include "base/threading/thread_checker.h" #include "device/hid/hid_service.h" +#include "device/hid/public/interfaces/hid.mojom.h" #include "extensions/browser/browser_context_keyed_api_factory.h" #include "extensions/browser/event_router.h" #include "extensions/browser/extension_event_histogram_value.h" @@ -21,7 +22,6 @@ namespace device { class HidDeviceFilter; -class HidDeviceInfo; } namespace extensions { @@ -56,17 +56,17 @@ const std::vector<device::HidDeviceFilter>& filters, const GetApiDevicesCallback& callback); - // Converts a list of HidDeviceInfo objects into a value that can be returned - // through the API. + // Converts a list of device::mojom::HidDeviceInfo objects into a value that + // can be returned through the API. std::unique_ptr<base::ListValue> GetApiDevicesFromList( - const std::vector<scoped_refptr<device::HidDeviceInfo>>& devices); + std::vector<device::mojom::HidDeviceInfoPtr> devices); - scoped_refptr<device::HidDeviceInfo> GetDeviceInfo(int resource_id); + const device::mojom::HidDeviceInfo* GetDeviceInfo(int resource_id); // Checks if |extension| has permission to open |device_info|. Set // |update_last_used| to update the timestamp in the DevicePermissionsManager. bool HasPermission(const Extension* extension, - scoped_refptr<device::HidDeviceInfo> device_info, + const device::mojom::HidDeviceInfo& device_info, bool update_last_used); // Wait to perform an initial enumeration and register a HidService::Observer @@ -77,7 +77,8 @@ private: friend class BrowserContextKeyedAPIFactory<HidDeviceManager>; - typedef std::map<int, std::string> ResourceIdToDeviceIdMap; + typedef std::map<int, device::mojom::HidDeviceInfoPtr> + ResourceIdToDeviceInfoMap; typedef std::map<std::string, int> DeviceIdToResourceIdMap; struct GetApiDevicesParams; @@ -94,9 +95,8 @@ void OnListenerAdded(const EventListenerInfo& details) override; // HidService::Observer: - void OnDeviceAdded(scoped_refptr<device::HidDeviceInfo> device_info) override; - void OnDeviceRemoved( - scoped_refptr<device::HidDeviceInfo> device_info) override; + void OnDeviceAdded(device::mojom::HidDeviceInfoPtr device) override; + void OnDeviceRemoved(device::mojom::HidDeviceInfoPtr device) override; // Builds a list of device info objects representing the currently enumerated // devices, taking into account the permissions held by the given extension @@ -106,12 +106,12 @@ const std::vector<device::HidDeviceFilter>& filters); void OnEnumerationComplete( device::HidService* hid_service, - const std::vector<scoped_refptr<device::HidDeviceInfo>>& devices); + std::vector<device::mojom::HidDeviceInfoPtr> devices); void DispatchEvent(events::HistogramValue histogram_value, const std::string& event_name, std::unique_ptr<base::ListValue> event_args, - scoped_refptr<device::HidDeviceInfo> device_info); + const device::mojom::HidDeviceInfo& device_info); base::ThreadChecker thread_checker_; content::BrowserContext* browser_context_ = nullptr; @@ -122,7 +122,7 @@ bool enumeration_ready_ = false; std::vector<std::unique_ptr<GetApiDevicesParams>> pending_enumerations_; int next_resource_id_ = 0; - ResourceIdToDeviceIdMap device_ids_; + ResourceIdToDeviceInfoMap devices_; DeviceIdToResourceIdMap resource_ids_; base::WeakPtrFactory<HidDeviceManager> weak_factory_;
diff --git a/ios/chrome/app/strings/ios_strings.grd b/ios/chrome/app/strings/ios_strings.grd index e90ac72..079c69d 100644 --- a/ios/chrome/app/strings/ios_strings.grd +++ b/ios/chrome/app/strings/ios_strings.grd
@@ -1576,6 +1576,9 @@ <message name="IDS_IOS_CHOOSE_EMAIL_CLIENT_APP" desc="Title for action sheet to select an email client app when user taps on an URL that has a mailto: URL scheme. [Length: 50em]"> Create email with: </message> + <message name="IDS_IOS_CHOOSE_EMAIL_ASK_TOGGLE" desc="Title for toggle switch to set whether to ask user which Mail client app to use every time a mailto:// URL is tapped. [Length: 50]"> + Ask me which app to use every time + </message> </messages> </release> </grit>
diff --git a/ios/web/navigation/crw_session_controller_unittest.mm b/ios/web/navigation/crw_session_controller_unittest.mm index aa019f2..ad65daa4 100644 --- a/ios/web/navigation/crw_session_controller_unittest.mm +++ b/ios/web/navigation/crw_session_controller_unittest.mm
@@ -1267,7 +1267,7 @@ } // Tests that |-backwardItems| returns all committed items if there is a -// transient item. This can happen if an intersitial was loaded for SSL error. +// transient item. This can happen if an interstitial was loaded for SSL error. // See crbug.com/691311. TEST_F(CRWSessionControllerTest, BackwardItemsShouldContainAllCommittedIfCurrentIsTransient) {
diff --git a/ios/web/navigation/navigation_manager_impl_unittest.mm b/ios/web/navigation/navigation_manager_impl_unittest.mm index 3f19264..e425f4c 100644 --- a/ios/web/navigation/navigation_manager_impl_unittest.mm +++ b/ios/web/navigation/navigation_manager_impl_unittest.mm
@@ -1964,7 +1964,7 @@ } // Tests that all committed items are considered history if there is a transient -// item. This can happen if an intersitial was loaded for SSL error. +// item. This can happen if an interstitial was loaded for SSL error. // See crbug.com/691311. TEST_P(NavigationManagerTest, BackwardItemsShouldContainAllCommittedIfCurrentIsTransient) {
diff --git a/ios/web/public/test/earl_grey/web_view_matchers.h b/ios/web/public/test/earl_grey/web_view_matchers.h index 583a25a..ae8700c 100644 --- a/ios/web/public/test/earl_grey/web_view_matchers.h +++ b/ios/web/public/test/earl_grey/web_view_matchers.h
@@ -26,9 +26,6 @@ id<GREYMatcher> WebViewContainingLoadedImage(std::string image_id, WebState* web_state); -// Matcher for WKWebView containing an html element which matches |selector|. -id<GREYMatcher> WebViewCssSelector(std::string selector, WebState* web_state); - // Matcher for WKWebView's scroll view. id<GREYMatcher> WebViewScrollView(WebState* web_state);
diff --git a/ios/web/public/test/earl_grey/web_view_matchers.mm b/ios/web/public/test/earl_grey/web_view_matchers.mm index 5c53385f..558b434f 100644 --- a/ios/web/public/test/earl_grey/web_view_matchers.mm +++ b/ios/web/public/test/earl_grey/web_view_matchers.mm
@@ -58,8 +58,6 @@ // Script that returns document.body as a string. char kGetDocumentBodyJavaScript[] = "document.body ? document.body.textContent : null"; -// Script that tests presence of css selector. -char kTestCssSelectorJavaScriptTemplate[] = "!!document.querySelector(\"%s\");"; // Fetches the image from |image_url|. UIImage* LoadImage(const GURL& image_url) { @@ -195,33 +193,6 @@ return WebViewContainingImage(image_id, web_state, IMAGE_STATE_LOADED); } -id<GREYMatcher> WebViewCssSelector(std::string selector, WebState* web_state) { - MatchesBlock matches = ^BOOL(WKWebView*) { - std::string script = base::StringPrintf(kTestCssSelectorJavaScriptTemplate, - selector.c_str()); - return WaitUntilConditionOrTimeout(testing::kWaitForUIElementTimeout, ^{ - bool did_succeed = false; - std::unique_ptr<base::Value> value = - web::test::ExecuteJavaScript(web_state, script); - if (value) { - value->GetAsBoolean(&did_succeed); - } - return did_succeed; - }); - }; - - DescribeToBlock describe = ^(id<GREYDescription> description) { - [description appendText:@"web view selector "]; - [description appendText:base::SysUTF8ToNSString(selector)]; - }; - - return grey_allOf( - WebViewInWebState(web_state), - [[GREYElementMatcherBlock alloc] initWithMatchesBlock:matches - descriptionBlock:describe], - nil); -} - id<GREYMatcher> WebViewScrollView(WebState* web_state) { MatchesBlock matches = ^BOOL(UIView* view) { return [view isKindOfClass:[UIScrollView class]] &&
diff --git a/ios/web/public/test/web_view_content_test_util.h b/ios/web/public/test/web_view_content_test_util.h index 160abbaf..1fc0a72 100644 --- a/ios/web/public/test/web_view_content_test_util.h +++ b/ios/web/public/test/web_view_content_test_util.h
@@ -32,6 +32,12 @@ bool WaitForWebViewContainingImage(std::string image_id, web::WebState* web_state, ImageStateElement image_state); + +// Returns true if there is a web view for |web_state| that contains the CSS +// selector |css_selector|. +bool IsWebViewContainingCssSelector(web::WebState* web_state, + const std::string& css_selector); + } // namespace test } // namespace web
diff --git a/ios/web/public/test/web_view_content_test_util.mm b/ios/web/public/test/web_view_content_test_util.mm index 3a6863d..4c1db3b 100644 --- a/ios/web/public/test/web_view_content_test_util.mm +++ b/ios/web/public/test/web_view_content_test_util.mm
@@ -9,6 +9,7 @@ #include "base/strings/stringprintf.h" #include "base/strings/sys_string_conversions.h" +#include "base/values.h" #import "ios/testing/wait_util.h" #import "ios/web/public/test/web_view_interaction_test_util.h" #import "net/base/mac/url_conversions.h" @@ -147,5 +148,22 @@ }); } +bool IsWebViewContainingCssSelector(web::WebState* web_state, + const std::string& css_selector) { + // Script that tests presence of css selector. + char testCssSelectorJavaScriptTemplate[] = + "!!document.querySelector(\"%s\");"; + std::string script = base::StringPrintf(testCssSelectorJavaScriptTemplate, + css_selector.c_str()); + + bool did_succeed = false; + std::unique_ptr<base::Value> value = + web::test::ExecuteJavaScript(web_state, script); + if (value) { + value->GetAsBoolean(&did_succeed); + } + return did_succeed; +} + } // namespace test } // namespace web
diff --git a/ios/web/shell/test/earl_grey/shell_earl_grey.h b/ios/web/shell/test/earl_grey/shell_earl_grey.h index a1f7a4b..1b49272 100644 --- a/ios/web/shell/test/earl_grey/shell_earl_grey.h +++ b/ios/web/shell/test/earl_grey/shell_earl_grey.h
@@ -23,6 +23,15 @@ // within a timeout, a GREYAssert is induced. + (void)waitForWebViewContainingText:(const std::string)text; +// Waits for the current web view to contain a css selector matching |selector|. +// If the condition is not met within a timeout, a GREYAssert is induced. ++ (void)waitForWebViewContainingCSSSelector:(std::string)selector; + +// Waits for the current web view to not contain a css selector matching +// |selector|. If the condition is not met within a timeout, a GREYAssert is +// induced. ++ (void)waitForWebViewNotContainingCSSSelector:(std::string)selector; + @end #endif // IOS_WEB_SHELL_TEST_EARL_GREY_SHELL_EARL_GREY_H_
diff --git a/ios/web/shell/test/earl_grey/shell_earl_grey.mm b/ios/web/shell/test/earl_grey/shell_earl_grey.mm index 4a08d771..a4427ef 100644 --- a/ios/web/shell/test/earl_grey/shell_earl_grey.mm +++ b/ios/web/shell/test/earl_grey/shell_earl_grey.mm
@@ -9,6 +9,7 @@ #import "ios/testing/wait_util.h" #import "ios/web/public/test/earl_grey/js_test_util.h" #import "ios/web/public/test/web_view_content_test_util.h" +#import "ios/web/public/test/web_view_interaction_test_util.h" #include "ios/web/shell/test/app/navigation_test_util.h" #import "ios/web/shell/test/app/web_shell_test_util.h" @@ -49,4 +50,28 @@ @"Failed waiting for web view containing %s", text.c_str()); } ++ (void)waitForWebViewContainingCSSSelector:(std::string)selector { + GREYCondition* condition = [GREYCondition + conditionWithName:@"Wait for web view containing text" + block:^BOOL { + return web::test::IsWebViewContainingCssSelector( + web::shell_test_util::GetCurrentWebState(), selector); + }]; + GREYAssert([condition waitWithTimeout:testing::kWaitForUIElementTimeout], + @"Failed waiting for web view containing css selector: %s", + selector.c_str()); +} + ++ (void)waitForWebViewNotContainingCSSSelector:(std::string)selector { + GREYCondition* condition = [GREYCondition + conditionWithName:@"Wait for web view not containing text" + block:^BOOL { + return !web::test::IsWebViewContainingCssSelector( + web::shell_test_util::GetCurrentWebState(), selector); + }]; + GREYAssert([condition waitWithTimeout:testing::kWaitForUIElementTimeout], + @"Failed waiting for web view not containing css selector: %s", + selector.c_str()); +} + @end
diff --git a/ios/web/shell/test/earl_grey/shell_matchers.h b/ios/web/shell/test/earl_grey/shell_matchers.h index 396eafc..bd2a3d67 100644 --- a/ios/web/shell/test/earl_grey/shell_matchers.h +++ b/ios/web/shell/test/earl_grey/shell_matchers.h
@@ -11,9 +11,6 @@ namespace web { -// Matcher for WKWebView containing an html element which matches |selector|. -id<GREYMatcher> WebViewCssSelector(const std::string& selector); - // Matcher for the WKWebView. id<GREYMatcher> WebView();
diff --git a/ios/web/shell/test/earl_grey/shell_matchers.mm b/ios/web/shell/test/earl_grey/shell_matchers.mm index 1e71a85..85561a3 100644 --- a/ios/web/shell/test/earl_grey/shell_matchers.mm +++ b/ios/web/shell/test/earl_grey/shell_matchers.mm
@@ -19,11 +19,6 @@ namespace web { -id<GREYMatcher> WebViewCssSelector(const std::string& selector) { - WebState* web_state = shell_test_util::GetCurrentWebState(); - return WebViewCssSelector(std::move(selector), web_state); -} - id<GREYMatcher> WebView() { return WebViewInWebState(shell_test_util::GetCurrentWebState()); }
diff --git a/ios/web/shell/test/plugin_placeholder_egtest.mm b/ios/web/shell/test/plugin_placeholder_egtest.mm index 7e39fa57..4145aa9 100644 --- a/ios/web/shell/test/plugin_placeholder_egtest.mm +++ b/ios/web/shell/test/plugin_placeholder_egtest.mm
@@ -20,8 +20,6 @@ #error "This file requires ARC support." #endif -using web::WebViewCssSelector; - namespace { // Loads a web page with given content. @@ -58,8 +56,7 @@ // Verify that placeholder image is not displayed. [ShellEarlGrey waitForWebViewContainingText:kPageDescription]; [ShellEarlGrey waitForWebViewContainingText:kFallbackText]; - [[EarlGrey selectElementWithMatcher:WebViewCssSelector("img")] - assertWithMatcher:grey_nil()]; + [ShellEarlGrey waitForWebViewNotContainingCSSSelector:"img"]; } // Tests placeholder for a large <applet> with no fallback. @@ -76,8 +73,7 @@ // Verify that plugin object is replaced with placeholder image. [ShellEarlGrey waitForWebViewContainingText:kPageDescription]; - [[EarlGrey selectElementWithMatcher:WebViewCssSelector("img[src*='data']")] - assertWithMatcher:grey_notNil()]; + [ShellEarlGrey waitForWebViewContainingCSSSelector:"img[src*='data']"]; } // Tests placeholder for a large <object> with an embed fallback. @@ -98,8 +94,7 @@ // Verify that plugin object is replaced with placeholder image. [ShellEarlGrey waitForWebViewContainingText:kPageDescription]; - [[EarlGrey selectElementWithMatcher:WebViewCssSelector("img[src*='data']")] - assertWithMatcher:grey_notNil()]; + [ShellEarlGrey waitForWebViewContainingCSSSelector:"img[src*='data']"]; } // Tests that a large <object> with text fallback is untouched. @@ -121,8 +116,7 @@ // Verify that placeholder image is not displayed. [ShellEarlGrey waitForWebViewContainingText:kPageDescription]; [ShellEarlGrey waitForWebViewContainingText:kFallbackText]; - [[EarlGrey selectElementWithMatcher:WebViewCssSelector("img")] - assertWithMatcher:grey_nil()]; + [ShellEarlGrey waitForWebViewNotContainingCSSSelector:"img"]; } // Tests placeholder for a large <object> with no fallback. @@ -140,8 +134,7 @@ // Verify that plugin object is replaced with placeholder image. [ShellEarlGrey waitForWebViewContainingText:kPageDescription]; - [[EarlGrey selectElementWithMatcher:WebViewCssSelector("img[src*='data']")] - assertWithMatcher:grey_notNil()]; + [ShellEarlGrey waitForWebViewContainingCSSSelector:"img[src*='data']"]; } // Tests that a large png <object> is untouched. @@ -158,8 +151,7 @@ // Verify that placeholder image is not displayed. [ShellEarlGrey waitForWebViewContainingText:kPageDescription]; - [[EarlGrey selectElementWithMatcher:WebViewCssSelector("img")] - assertWithMatcher:grey_nil()]; + [ShellEarlGrey waitForWebViewNotContainingCSSSelector:"img"]; } // Test that non-major plugins (e.g., top/side ads) don't get placeholders. @@ -195,8 +187,7 @@ // Verify that placeholder image is not displayed. [ShellEarlGrey waitForWebViewContainingText:kPageDescription]; - [[EarlGrey selectElementWithMatcher:WebViewCssSelector("img")] - assertWithMatcher:grey_nil()]; + [ShellEarlGrey waitForWebViewNotContainingCSSSelector:"img"]; } @end
diff --git a/ipc/ipc_sync_channel.cc b/ipc/ipc_sync_channel.cc index 16a6878..dd636b5 100644 --- a/ipc/ipc_sync_channel.cc +++ b/ipc/ipc_sync_channel.cc
@@ -646,15 +646,14 @@ bool dispatch = false; bool send_done = false; bool should_pump_messages = false; - bool registered = registry->RegisterEvent( - context->GetSendDoneEvent(), base::Bind(&OnEventReady, &send_done)); - DCHECK(registered); + base::Closure on_send_done_callback = base::Bind(&OnEventReady, &send_done); + registry->RegisterEvent(context->GetSendDoneEvent(), on_send_done_callback); + base::Closure on_pump_messages_callback; if (pump_messages_event) { - registered = registry->RegisterEvent( - pump_messages_event, - base::Bind(&OnEventReady, &should_pump_messages)); - DCHECK(registered); + on_pump_messages_callback = + base::Bind(&OnEventReady, &should_pump_messages); + registry->RegisterEvent(pump_messages_event, on_pump_messages_callback); } const bool* stop_flags[] = { &dispatch, &send_done, &should_pump_messages }; @@ -662,9 +661,10 @@ registry->Wait(stop_flags, 3); context->received_sync_msgs()->UnblockDispatch(); - registry->UnregisterEvent(context->GetSendDoneEvent()); + registry->UnregisterEvent(context->GetSendDoneEvent(), + on_send_done_callback); if (pump_messages_event) - registry->UnregisterEvent(pump_messages_event); + registry->UnregisterEvent(pump_messages_event, on_pump_messages_callback); if (dispatch) { // We're waiting for a reply, but we received a blocking synchronous call.
diff --git a/ipc/ipc_sync_message_filter.cc b/ipc/ipc_sync_message_filter.cc index 15ffdbc..86d4ce1 100644 --- a/ipc/ipc_sync_message_filter.cc +++ b/ipc/ipc_sync_message_filter.cc
@@ -73,9 +73,10 @@ bool shutdown = false; scoped_refptr<mojo::SyncHandleRegistry> registry = mojo::SyncHandleRegistry::current(); - registry->RegisterEvent(shutdown_event_, - base::Bind(&OnEventReady, &shutdown)); - registry->RegisterEvent(&done_event, base::Bind(&OnEventReady, &done)); + auto on_shutdown_callback = base::Bind(&OnEventReady, &shutdown); + auto on_done_callback = base::Bind(&OnEventReady, &done); + registry->RegisterEvent(shutdown_event_, on_shutdown_callback); + registry->RegisterEvent(&done_event, on_done_callback); const bool* stop_flags[] = { &done, &shutdown }; registry->Wait(stop_flags, 2); @@ -84,8 +85,8 @@ "SyncMessageFilter::Send", &done_event); } - registry->UnregisterEvent(shutdown_event_); - registry->UnregisterEvent(&done_event); + registry->UnregisterEvent(shutdown_event_, on_shutdown_callback); + registry->UnregisterEvent(&done_event, on_done_callback); { base::AutoLock auto_lock(lock_);
diff --git a/media/BUILD.gn b/media/BUILD.gn index 49fc34f..d1ee33b 100644 --- a/media/BUILD.gn +++ b/media/BUILD.gn
@@ -160,21 +160,6 @@ "filters/vp8_parser_unittest.cc", "filters/vp9_parser_unittest.cc", "filters/vp9_raw_bits_reader_unittest.cc", - "formats/ac3/ac3_util_unittest.cc", - "formats/common/offset_byte_queue_unittest.cc", - "formats/webm/cluster_builder.cc", - "formats/webm/cluster_builder.h", - "formats/webm/opus_packet_builder.cc", - "formats/webm/opus_packet_builder.h", - "formats/webm/tracks_builder.cc", - "formats/webm/tracks_builder.h", - "formats/webm/webm_cluster_parser_unittest.cc", - "formats/webm/webm_content_encodings_client_unittest.cc", - "formats/webm/webm_crypto_helpers_unittest.cc", - "formats/webm/webm_parser_unittest.cc", - "formats/webm/webm_stream_parser_unittest.cc", - "formats/webm/webm_tracks_parser_unittest.cc", - "formats/webm/webm_webvtt_parser_unittest.cc", "muxers/webm_muxer_unittest.cc", ] @@ -256,32 +241,7 @@ } if (proprietary_codecs) { - sources += [ - "filters/h264_to_annex_b_bitstream_converter_unittest.cc", - "formats/common/stream_parser_test_base.cc", - "formats/common/stream_parser_test_base.h", - "formats/mp4/aac_unittest.cc", - "formats/mp4/avc_unittest.cc", - "formats/mp4/box_reader_unittest.cc", - "formats/mp4/es_descriptor_unittest.cc", - "formats/mp4/mp4_stream_parser_unittest.cc", - "formats/mp4/sample_to_group_iterator_unittest.cc", - "formats/mp4/track_run_iterator_unittest.cc", - "formats/mpeg/adts_stream_parser_unittest.cc", - "formats/mpeg/mpeg1_audio_stream_parser_unittest.cc", - ] - if (enable_mse_mpeg2ts_stream_parser) { - sources += [ - "formats/mp2t/es_adapter_video_unittest.cc", - "formats/mp2t/es_parser_adts_unittest.cc", - "formats/mp2t/es_parser_h264_unittest.cc", - "formats/mp2t/es_parser_mpeg1audio_unittest.cc", - "formats/mp2t/es_parser_test_base.cc", - "formats/mp2t/es_parser_test_base.h", - "formats/mp2t/mp2t_stream_parser_unittest.cc", - "formats/mp2t/timestamp_unroller_unittest.cc", - ] - } + sources += [ "filters/h264_to_annex_b_bitstream_converter_unittest.cc" ] if (media_use_ffmpeg) { sources += [ "filters/ffmpeg_aac_bitstream_converter_unittest.cc", @@ -291,9 +251,6 @@ if (enable_hls_sample_aes) { deps += [ "//third_party/boringssl" ] } - if (enable_dolby_vision_demuxing) { - sources += [ "formats/mp4/dolby_vision_unittest.cc" ] - } } if (is_mac || is_ios) { @@ -317,6 +274,7 @@ "//media/audio:test_support", "//media/base:test_support", "//media/base/android:test_support", + "//media/formats:test_support", "//media/video:test_support", ] } @@ -330,6 +288,7 @@ "//media/base:unit_tests", "//media/cdm:unit_tests", "//media/device_monitors:unit_tests", + "//media/formats:unit_tests", "//media/gpu:unit_tests", "//media/mojo:unit_tests", "//media/renderers:unit_tests",
diff --git a/media/base/BUILD.gn b/media/base/BUILD.gn index 224264f..762f5ac8 100644 --- a/media/base/BUILD.gn +++ b/media/base/BUILD.gn
@@ -364,6 +364,7 @@ "//media:test_support", "//media/audio:test_support", "//media/base/android:test_support", + "//media/formats:test_support", "//media/video:test_support", ] testonly = true
diff --git a/media/base/android/android_cdm_factory.cc b/media/base/android/android_cdm_factory.cc index 539ddada..1cd8030 100644 --- a/media/base/android/android_cdm_factory.cc +++ b/media/base/android/android_cdm_factory.cc
@@ -15,7 +15,7 @@ #include "media/base/media_switches.h" #include "media/cdm/aes_decryptor.h" #include "third_party/widevine/cdm/widevine_cdm_common.h" -#include "url/gurl.h" +#include "url/origin.h" namespace media { namespace { @@ -46,7 +46,7 @@ void AndroidCdmFactory::Create( const std::string& key_system, - const GURL& security_origin, + const url::Origin& security_origin, const CdmConfig& cdm_config, const SessionMessageCB& session_message_cb, const SessionClosedCB& session_closed_cb, @@ -56,7 +56,7 @@ // Bound |cdm_created_cb| so we always fire it asynchronously. CdmCreatedCB bound_cdm_created_cb = BindToCurrentLoop(cdm_created_cb); - if (!security_origin.is_valid()) { + if (security_origin.unique()) { bound_cdm_created_cb.Run(nullptr, "Invalid origin."); return; }
diff --git a/media/base/android/android_cdm_factory.h b/media/base/android/android_cdm_factory.h index 5285efcf..d28300f 100644 --- a/media/base/android/android_cdm_factory.h +++ b/media/base/android/android_cdm_factory.h
@@ -23,7 +23,7 @@ // CdmFactory implementation. void Create(const std::string& key_system, - const GURL& security_origin, + const url::Origin& security_origin, const CdmConfig& cdm_config, const SessionMessageCB& session_message_cb, const SessionClosedCB& session_closed_cb,
diff --git a/media/base/android/media_drm_bridge.cc b/media/base/android/media_drm_bridge.cc index 661050a..85f7c55 100644 --- a/media/base/android/media_drm_bridge.cc +++ b/media/base/android/media_drm_bridge.cc
@@ -363,7 +363,7 @@ // static void MediaDrmBridge::Create( const std::string& key_system, - const GURL& security_origin, + const url::Origin& security_origin, SecurityLevel security_level, const CreateFetcherCB& create_fetcher_cb, const CreateStorageCB& create_storage_cb, @@ -395,7 +395,7 @@ session_closed_cb, session_keys_change_cb, session_expiration_update_cb); if (IsPersistentLicenseTypeSupported(key_system) && - !security_origin.is_empty() && !create_storage_cb.is_null()) { + !security_origin.unique() && !create_storage_cb.is_null()) { raw_storage->Initialize( create_storage_cb, base::BindOnce(&OnStorageInitialized, std::move(create_media_drm_bridge_cb),
diff --git a/media/base/android/media_drm_bridge.h b/media/base/android/media_drm_bridge.h index d12f3628..1869c986 100644 --- a/media/base/android/media_drm_bridge.h +++ b/media/base/android/media_drm_bridge.h
@@ -29,7 +29,7 @@ #include "media/base/player_tracker.h" #include "media/base/provision_fetcher.h" #include "media/cdm/player_tracker_impl.h" -#include "url/gurl.h" +#include "url/origin.h" namespace base { class SingleThreadTaskRunner; @@ -95,7 +95,7 @@ // if |security_level| is SECURITY_LEVEL_DEFAULT. static void Create( const std::string& key_system, - const GURL& security_origin, + const url::Origin& security_origin, SecurityLevel security_level, const CreateFetcherCB& create_fetcher_cb, const CreateStorageCB& create_storage_cb,
diff --git a/media/base/cdm_factory.h b/media/base/cdm_factory.h index f7a72fa..36056a4 100644 --- a/media/base/cdm_factory.h +++ b/media/base/cdm_factory.h
@@ -11,7 +11,9 @@ #include "media/base/content_decryption_module.h" #include "media/base/media_export.h" -class GURL; +namespace url { +class Origin; +} namespace media { @@ -32,7 +34,7 @@ // asynchronously. virtual void Create( const std::string& key_system, - const GURL& security_origin, + const url::Origin& security_origin, const CdmConfig& cdm_config, const SessionMessageCB& session_message_cb, const SessionClosedCB& session_closed_cb,
diff --git a/media/base/mock_filters.cc b/media/base/mock_filters.cc index 4c5d5f8..1eb8659 100644 --- a/media/base/mock_filters.cc +++ b/media/base/mock_filters.cc
@@ -258,8 +258,8 @@ void MockCdmFactory::Create( const std::string& key_system, - const GURL& security_origin, - const CdmConfig& cdm_config, + const url::Origin& /* security_origin */, + const CdmConfig& /* cdm_config */, const SessionMessageCB& session_message_cb, const SessionClosedCB& session_closed_cb, const SessionKeysChangeCB& session_keys_change_cb,
diff --git a/media/base/mock_filters.h b/media/base/mock_filters.h index 2264be19..c11da37e 100644 --- a/media/base/mock_filters.h +++ b/media/base/mock_filters.h
@@ -547,7 +547,7 @@ // created CDM is passed to |cdm_created_cb|, a copy is kept (and available // using Cdm()). If |key_system| is empty, no CDM will be created. void Create(const std::string& key_system, - const GURL& security_origin, + const url::Origin& security_origin, const CdmConfig& cdm_config, const SessionMessageCB& session_message_cb, const SessionClosedCB& session_closed_cb,
diff --git a/media/blink/cdm_session_adapter.cc b/media/blink/cdm_session_adapter.cc index 3837820..a025df3 100644 --- a/media/blink/cdm_session_adapter.cc +++ b/media/blink/cdm_session_adapter.cc
@@ -20,7 +20,7 @@ #include "media/base/key_systems.h" #include "media/blink/webcontentdecryptionmodule_impl.h" #include "media/blink/webcontentdecryptionmodulesession_impl.h" -#include "url/gurl.h" +#include "url/origin.h" namespace media { @@ -38,7 +38,7 @@ void CdmSessionAdapter::CreateCdm( CdmFactory* cdm_factory, const std::string& key_system, - const GURL& security_origin, + const url::Origin& security_origin, const CdmConfig& cdm_config, std::unique_ptr<blink::WebContentDecryptionModuleResult> result) { TRACE_EVENT_ASYNC_BEGIN0("media", "CdmSessionAdapter::CreateCdm",
diff --git a/media/blink/cdm_session_adapter.h b/media/blink/cdm_session_adapter.h index 1c7aefa..8d4da1b 100644 --- a/media/blink/cdm_session_adapter.h +++ b/media/blink/cdm_session_adapter.h
@@ -19,7 +19,9 @@ #include "third_party/WebKit/public/platform/WebContentDecryptionModuleResult.h" #include "third_party/WebKit/public/platform/WebContentDecryptionModuleSession.h" -class GURL; +namespace url { +class Origin; +} namespace media { @@ -40,7 +42,7 @@ void CreateCdm( CdmFactory* cdm_factory, const std::string& key_system, - const GURL& security_origin, + const url::Origin& security_origin, const CdmConfig& cdm_config, std::unique_ptr<blink::WebContentDecryptionModuleResult> result);
diff --git a/media/blink/webcontentdecryptionmodule_impl.cc b/media/blink/webcontentdecryptionmodule_impl.cc index d2c56c3a..ed7a1ca 100644 --- a/media/blink/webcontentdecryptionmodule_impl.cc +++ b/media/blink/webcontentdecryptionmodule_impl.cc
@@ -20,7 +20,6 @@ #include "third_party/WebKit/public/platform/URLConversion.h" #include "third_party/WebKit/public/platform/WebSecurityOrigin.h" #include "third_party/WebKit/public/platform/WebString.h" -#include "url/gurl.h" #include "url/origin.h" namespace media { @@ -101,15 +100,13 @@ return; } - GURL security_origin_as_gurl(url::Origin(security_origin).GetURL()); - // CdmSessionAdapter::CreateCdm() will keep a reference to |adapter|. Then // if WebContentDecryptionModuleImpl is successfully created (returned in // |result|), it will keep a reference to |adapter|. Otherwise, |adapter| will // be destructed. scoped_refptr<CdmSessionAdapter> adapter(new CdmSessionAdapter()); - adapter->CreateCdm(cdm_factory, key_system_ascii, security_origin_as_gurl, - cdm_config, std::move(result)); + adapter->CreateCdm(cdm_factory, key_system_ascii, security_origin, cdm_config, + std::move(result)); } WebContentDecryptionModuleImpl::WebContentDecryptionModuleImpl(
diff --git a/media/blink/webmediaplayer_impl.cc b/media/blink/webmediaplayer_impl.cc index a02e7dff..fcda8cd 100644 --- a/media/blink/webmediaplayer_impl.cc +++ b/media/blink/webmediaplayer_impl.cc
@@ -1347,6 +1347,7 @@ renderer_factory_selector_->SetUseMediaPlayer(true); pipeline_controller_.Stop(); + SetMemoryReportingState(false); main_task_runner_->PostTask( FROM_HERE, base::Bind(&WebMediaPlayerImpl::StartPipeline, AsWeakPtr())); @@ -2409,7 +2410,7 @@ // It's not critical if some cases where memory usage can change are missed, // since media memory changes are usually gradual. result.is_memory_reporting_enabled = - can_play && !result.is_suspended && (!paused_ || seeking_); + !has_error && can_play && !result.is_suspended && (!paused_ || seeking_); return result; } @@ -2421,8 +2422,12 @@ // thread. Before that, however, ~WebMediaPlayerImpl() posts a task to the // media thread and waits for it to finish. Hence, the GetMemoryUsage() task // posted here must finish earlier. - - if (demuxer_) { + // + // The exception to the above is when OnError() has been called. If we're in + // the error state we've already shut down the pipeline and can't rely on it + // to cycle the media thread before we destroy |demuxer_|. In this case skip + // collection of the demuxer memory stats. + if (demuxer_ && !IsNetworkStateError(network_state_)) { base::PostTaskAndReplyWithResult( media_task_runner_.get(), FROM_HERE, base::Bind(&Demuxer::GetMemoryUsage, base::Unretained(demuxer_.get())),
diff --git a/media/blink/webmediaplayer_impl_unittest.cc b/media/blink/webmediaplayer_impl_unittest.cc index f9fcfac..db7b42803 100644 --- a/media/blink/webmediaplayer_impl_unittest.cc +++ b/media/blink/webmediaplayer_impl_unittest.cc
@@ -318,6 +318,10 @@ TestAudioConfig::Normal(); } + void SetError(PipelineStatus status = PIPELINE_ERROR_DECODE) { + wmpi_->OnError(status); + } + void OnMetadata(PipelineMetadata metadata) { wmpi_->OnMetadata(metadata); } void OnVideoNaturalSizeChange(const gfx::Size& size) { @@ -527,6 +531,24 @@ EXPECT_FALSE(state.is_memory_reporting_enabled); } +// Ensure memory reporting is not running after an error. +TEST_F(WebMediaPlayerImplTest, ComputePlayState_PlayingError) { + InitializeWebMediaPlayerImpl(); + SetMetadata(true, true); + SetReadyState(blink::WebMediaPlayer::kReadyStateHaveFutureData); + SetPaused(false); + WebMediaPlayerImpl::PlayState state = ComputePlayState(); + EXPECT_EQ(WebMediaPlayerImpl::DelegateState::PLAYING, state.delegate_state); + EXPECT_FALSE(state.is_idle); + EXPECT_FALSE(state.is_suspended); + EXPECT_TRUE(state.is_memory_reporting_enabled); + SetError(); + state = ComputePlayState(); + EXPECT_TRUE(state.is_idle); + EXPECT_FALSE(state.is_suspended); + EXPECT_FALSE(state.is_memory_reporting_enabled); +} + TEST_F(WebMediaPlayerImplTest, ComputePlayState_Playing) { InitializeWebMediaPlayerImpl(); SetMetadata(true, true);
diff --git a/media/cdm/aes_decryptor.cc b/media/cdm/aes_decryptor.cc index 7fdeb8f..61dd1a285 100644 --- a/media/cdm/aes_decryptor.cc +++ b/media/cdm/aes_decryptor.cc
@@ -270,7 +270,7 @@ } AesDecryptor::AesDecryptor( - const GURL& /* security_origin */, + const url::Origin& /* security_origin */, const SessionMessageCB& session_message_cb, const SessionClosedCB& session_closed_cb, const SessionKeysChangeCB& session_keys_change_cb,
diff --git a/media/cdm/aes_decryptor.h b/media/cdm/aes_decryptor.h index ddab596f..e9b23a86 100644 --- a/media/cdm/aes_decryptor.h +++ b/media/cdm/aes_decryptor.h
@@ -23,12 +23,14 @@ #include "media/base/decryptor.h" #include "media/base/media_export.h" -class GURL; - namespace crypto { class SymmetricKey; } +namespace url { +class Origin; +} + namespace media { // Decrypts an AES encrypted buffer into an unencrypted buffer. The AES @@ -37,7 +39,7 @@ public CdmContext, public Decryptor { public: - AesDecryptor(const GURL& security_origin, + AesDecryptor(const url::Origin& security_origin, const SessionMessageCB& session_message_cb, const SessionClosedCB& session_closed_cb, const SessionKeysChangeCB& session_keys_change_cb,
diff --git a/media/cdm/aes_decryptor_unittest.cc b/media/cdm/aes_decryptor_unittest.cc index c4a72d96..67f3cc4 100644 --- a/media/cdm/aes_decryptor_unittest.cc +++ b/media/cdm/aes_decryptor_unittest.cc
@@ -31,7 +31,7 @@ #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest-param-test.h" #include "testing/gtest/include/gtest/gtest.h" -#include "url/gurl.h" +#include "url/origin.h" #if BUILDFLAG(ENABLE_LIBRARY_CDMS) #include "media/cdm/api/content_decryption_module.h" @@ -260,7 +260,7 @@ void SetUp() override { if (GetParam() == TestType::kAesDecryptor) { OnCdmCreated( - new AesDecryptor(GURL::EmptyGURL(), + new AesDecryptor(url::Origin(), base::Bind(&MockCdmClient::OnSessionMessage, base::Unretained(&cdm_client_)), base::Bind(&MockCdmClient::OnSessionClosed,
diff --git a/media/cdm/cdm_adapter_factory.cc b/media/cdm/cdm_adapter_factory.cc index 7b7ef7e..166519ae 100644 --- a/media/cdm/cdm_adapter_factory.cc +++ b/media/cdm/cdm_adapter_factory.cc
@@ -8,6 +8,7 @@ #include "base/threading/thread_task_runner_handle.h" #include "media/base/cdm_factory.h" #include "media/cdm/cdm_adapter.h" +#include "url/origin.h" namespace media { @@ -21,7 +22,7 @@ void CdmAdapterFactory::Create( const std::string& key_system, - const GURL& security_origin, + const url::Origin& security_origin, const CdmConfig& cdm_config, const SessionMessageCB& session_message_cb, const SessionClosedCB& session_closed_cb, @@ -30,7 +31,7 @@ const CdmCreatedCB& cdm_created_cb) { DVLOG(1) << __FUNCTION__ << ": key_system=" << key_system; - if (!security_origin.is_valid()) { + if (security_origin.unique()) { LOG(ERROR) << "Invalid Origin: " << security_origin; base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::Bind(cdm_created_cb, nullptr, "Invalid origin."));
diff --git a/media/cdm/cdm_adapter_factory.h b/media/cdm/cdm_adapter_factory.h index cc0d498a0..3cc5390 100644 --- a/media/cdm/cdm_adapter_factory.h +++ b/media/cdm/cdm_adapter_factory.h
@@ -19,7 +19,7 @@ // CdmFactory implementation. void Create(const std::string& key_system, - const GURL& security_origin, + const url::Origin& security_origin, const CdmConfig& cdm_config, const SessionMessageCB& session_message_cb, const SessionClosedCB& session_closed_cb,
diff --git a/media/cdm/default_cdm_factory.cc b/media/cdm/default_cdm_factory.cc index 7a150df4..a735906c 100644 --- a/media/cdm/default_cdm_factory.cc +++ b/media/cdm/default_cdm_factory.cc
@@ -14,7 +14,7 @@ #include "media/base/key_systems.h" #include "media/base/media_switches.h" #include "media/cdm/aes_decryptor.h" -#include "url/gurl.h" +#include "url/origin.h" namespace media { @@ -36,14 +36,14 @@ void DefaultCdmFactory::Create( const std::string& key_system, - const GURL& security_origin, + const url::Origin& security_origin, const CdmConfig& cdm_config, const SessionMessageCB& session_message_cb, const SessionClosedCB& session_closed_cb, const SessionKeysChangeCB& session_keys_change_cb, const SessionExpirationUpdateCB& session_expiration_update_cb, const CdmCreatedCB& cdm_created_cb) { - if (!security_origin.is_valid()) { + if (security_origin.unique()) { base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::Bind(cdm_created_cb, nullptr, "Invalid origin.")); return;
diff --git a/media/cdm/default_cdm_factory.h b/media/cdm/default_cdm_factory.h index 3274373..234e194 100644 --- a/media/cdm/default_cdm_factory.h +++ b/media/cdm/default_cdm_factory.h
@@ -20,7 +20,7 @@ // CdmFactory implementation. void Create(const std::string& key_system, - const GURL& security_origin, + const url::Origin& security_origin, const CdmConfig& cdm_config, const SessionMessageCB& session_message_cb, const SessionClosedCB& session_closed_cb,
diff --git a/media/cdm/ppapi/external_clear_key/clear_key_cdm.cc b/media/cdm/ppapi/external_clear_key/clear_key_cdm.cc index 0b73a4b..165636f0 100644 --- a/media/cdm/ppapi/external_clear_key/clear_key_cdm.cc +++ b/media/cdm/ppapi/external_clear_key/clear_key_cdm.cc
@@ -24,7 +24,7 @@ #include "media/cdm/json_web_key.h" #include "media/cdm/ppapi/cdm_file_io_test.h" #include "media/cdm/ppapi/external_clear_key/cdm_video_decoder.h" -#include "url/gurl.h" +#include "url/origin.h" #if defined(CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER) const int64_t kNoTimestamp = INT64_MIN; @@ -271,8 +271,7 @@ return nullptr; // TODO(jrummell): Obtain the proper origin for this instance. - GURL empty_origin; - return new media::ClearKeyCdm(host, key_system_string, empty_origin); + return new media::ClearKeyCdm(host, key_system_string, url::Origin()); } const char* GetCdmVersion() { @@ -337,7 +336,7 @@ ClearKeyCdm::ClearKeyCdm(ClearKeyCdmHost* host, const std::string& key_system, - const GURL& origin) + const url::Origin& origin) : cdm_(new ClearKeyPersistentSessionCdm( origin, host,
diff --git a/media/cdm/ppapi/external_clear_key/clear_key_cdm.h b/media/cdm/ppapi/external_clear_key/clear_key_cdm.h index 4059d68..af17128 100644 --- a/media/cdm/ppapi/external_clear_key/clear_key_cdm.h +++ b/media/cdm/ppapi/external_clear_key/clear_key_cdm.h
@@ -26,7 +26,9 @@ #define CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER #endif -class GURL; +namespace url { +class Origin; +} namespace media { class CdmVideoDecoder; @@ -37,7 +39,9 @@ // Clear key implementation of the cdm::ContentDecryptionModule interface. class ClearKeyCdm : public ClearKeyCdmInterface { public: - ClearKeyCdm(Host* host, const std::string& key_system, const GURL& origin); + ClearKeyCdm(Host* host, + const std::string& key_system, + const url::Origin& origin); ~ClearKeyCdm() override; // ClearKeyCdmInterface implementation.
diff --git a/media/cdm/ppapi/external_clear_key/clear_key_persistent_session_cdm.cc b/media/cdm/ppapi/external_clear_key/clear_key_persistent_session_cdm.cc index c10b61b..c42b202 100644 --- a/media/cdm/ppapi/external_clear_key/clear_key_persistent_session_cdm.cc +++ b/media/cdm/ppapi/external_clear_key/clear_key_persistent_session_cdm.cc
@@ -10,6 +10,7 @@ #include "base/memory/ptr_util.h" #include "base/memory/ref_counted.h" #include "media/base/cdm_promise.h" +#include "url/origin.h" namespace media { @@ -87,7 +88,7 @@ } // namespace ClearKeyPersistentSessionCdm::ClearKeyPersistentSessionCdm( - const GURL& origin, + const url::Origin& origin, ClearKeyCdmHost* host, const SessionMessageCB& session_message_cb, const SessionClosedCB& session_closed_cb,
diff --git a/media/cdm/ppapi/external_clear_key/clear_key_persistent_session_cdm.h b/media/cdm/ppapi/external_clear_key/clear_key_persistent_session_cdm.h index 5fef3d3..fd0a8d8f 100644 --- a/media/cdm/ppapi/external_clear_key/clear_key_persistent_session_cdm.h +++ b/media/cdm/ppapi/external_clear_key/clear_key_persistent_session_cdm.h
@@ -20,7 +20,9 @@ #include "media/cdm/cdm_file_adapter.h" #include "media/cdm/ppapi/external_clear_key/clear_key_cdm_common.h" -class GURL; +namespace url { +class Origin; +} namespace media { @@ -30,7 +32,7 @@ class ClearKeyPersistentSessionCdm : public ContentDecryptionModule { public: ClearKeyPersistentSessionCdm( - const GURL& origin, + const url::Origin& origin, ClearKeyCdmHost* host, const SessionMessageCB& session_message_cb, const SessionClosedCB& session_closed_cb,
diff --git a/media/formats/BUILD.gn b/media/formats/BUILD.gn index 532dc9a..5569108 100644 --- a/media/formats/BUILD.gn +++ b/media/formats/BUILD.gn
@@ -149,3 +149,91 @@ ] } } + +static_library("test_support") { + testonly = true + visibility = [ "//media:test_support" ] + + sources = [ + "webm/cluster_builder.cc", + "webm/cluster_builder.h", + "webm/opus_packet_builder.cc", + "webm/opus_packet_builder.h", + "webm/tracks_builder.cc", + "webm/tracks_builder.h", + ] + + deps = [ + "//base/test:test_support", + "//media/base:test_support", + ] + + if (proprietary_codecs) { + sources += [ + "common/stream_parser_test_base.cc", + "common/stream_parser_test_base.h", + ] + + deps += [ "//testing/gtest" ] + + if (enable_mse_mpeg2ts_stream_parser) { + sources += [ + "mp2t/es_parser_test_base.cc", + "mp2t/es_parser_test_base.h", + ] + } + } +} + +source_set("unit_tests") { + testonly = true + sources = [ + "ac3/ac3_util_unittest.cc", + "common/offset_byte_queue_unittest.cc", + "webm/webm_cluster_parser_unittest.cc", + "webm/webm_content_encodings_client_unittest.cc", + "webm/webm_crypto_helpers_unittest.cc", + "webm/webm_parser_unittest.cc", + "webm/webm_stream_parser_unittest.cc", + "webm/webm_tracks_parser_unittest.cc", + "webm/webm_webvtt_parser_unittest.cc", + ] + + deps = [ + "//base/test:test_support", + "//media:test_support", + "//testing/gmock", + "//testing/gtest", + ] + + if (proprietary_codecs) { + sources += [ + "mp4/aac_unittest.cc", + "mp4/avc_unittest.cc", + "mp4/box_reader_unittest.cc", + "mp4/es_descriptor_unittest.cc", + "mp4/mp4_stream_parser_unittest.cc", + "mp4/sample_to_group_iterator_unittest.cc", + "mp4/track_run_iterator_unittest.cc", + "mpeg/adts_stream_parser_unittest.cc", + "mpeg/mpeg1_audio_stream_parser_unittest.cc", + ] + + deps += [ "//crypto" ] + + if (enable_mse_mpeg2ts_stream_parser) { + sources += [ + "mp2t/es_adapter_video_unittest.cc", + "mp2t/es_parser_adts_unittest.cc", + "mp2t/es_parser_h264_unittest.cc", + "mp2t/es_parser_mpeg1audio_unittest.cc", + "mp2t/mp2t_stream_parser_unittest.cc", + "mp2t/timestamp_unroller_unittest.cc", + ] + } + + if (enable_dolby_vision_demuxing) { + sources += [ "mp4/dolby_vision_unittest.cc" ] + } + } +}
diff --git a/media/gpu/rendering_helper.cc b/media/gpu/rendering_helper.cc index 31c9a6b..9ee290a 100644 --- a/media/gpu/rendering_helper.cc +++ b/media/gpu/rendering_helper.cc
@@ -27,33 +27,22 @@ #include "ui/gl/gl_context.h" #include "ui/gl/gl_implementation.h" #include "ui/gl/gl_surface.h" +#include "ui/gl/gl_surface_egl.h" #include "ui/gl/init/gl_factory.h" #if defined(OS_WIN) #include <windows.h> #endif -#if defined(USE_X11) -#include "ui/gfx/x/x11_types.h" // nogncheck -#endif - -#if defined(ARCH_CPU_X86_FAMILY) && defined(USE_X11) -#include "ui/gl/gl_surface_glx.h" -#define GL_VARIANT_GLX 1 -#else -#include "ui/gl/gl_surface_egl.h" -#define GL_VARIANT_EGL 1 -#endif - -#if defined(USE_OZONE) #if defined(OS_CHROMEOS) #include "ui/display/manager/chromeos/display_configurator.h" +#include "ui/display/types/display_mode.h" +#include "ui/display/types/display_snapshot.h" #include "ui/display/types/native_display_delegate.h" -#endif // defined(OS_CHROMEOS) #include "ui/ozone/public/ozone_platform.h" #include "ui/platform_window/platform_window.h" #include "ui/platform_window/platform_window_delegate.h" -#endif // defined(USE_OZONE) +#endif // defined(OS_CHROMEOS) // Helper for Shader creation. static void CreateShader(GLuint program, @@ -84,7 +73,7 @@ } // namespace -#if defined(USE_OZONE) +#if defined(OS_CHROMEOS) class DisplayConfiguratorObserver : public display::DisplayConfigurator::Observer { @@ -157,7 +146,7 @@ DISALLOW_COPY_AND_ASSIGN(StubOzoneDelegate); }; -#endif // defined(USE_OZONE) +#endif // defined(OS_CHROMEOS) RenderingHelperParams::RenderingHelperParams() : rendering_fps(0), warm_up_iterations(0), render_as_thumbnails(false) {} @@ -191,14 +180,9 @@ // static void RenderingHelper::InitializeOneOff(base::WaitableEvent* done) { base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess(); -#if GL_VARIANT_GLX - cmd_line->AppendSwitchASCII(switches::kUseGL, - gl::kGLImplementationDesktopName); -#else cmd_line->AppendSwitchASCII(switches::kUseGL, gl::kGLImplementationEGLName); -#endif -#if defined(USE_OZONE) +#if defined(OS_CHROMEOS) ui::OzonePlatform::InitParams params; params.single_process = true; ui::OzonePlatform::InitializeForGPU(params); @@ -220,34 +204,7 @@ } void RenderingHelper::Setup() { -#if defined(USE_X11) - Display* display = gfx::GetXDisplay(); - Screen* screen = DefaultScreenOfDisplay(display); - - CHECK(display); - - XSetWindowAttributes window_attributes; - memset(&window_attributes, 0, sizeof(window_attributes)); - window_attributes.background_pixel = - BlackPixel(display, DefaultScreen(display)); - window_attributes.override_redirect = true; - int depth = DefaultDepth(display, DefaultScreen(display)); - - window_ = XCreateWindow(display, - DefaultRootWindow(display), - 0, 0, - XWidthOfScreen(screen), - XHeightOfScreen(screen), - 0 /* border width */, - depth, - CopyFromParent /* class */, - CopyFromParent /* visual */, - (CWBackPixel | CWOverrideRedirect), - &window_attributes); - XStoreName(display, window_, "VideoDecodeAcceleratorTest"); - XSelectInput(display, window_, ExposureMask); - XMapWindow(display, window_); -#elif defined(USE_OZONE) +#if defined(OS_CHROMEOS) base::MessageLoop::ScopedNestableTaskAllower nest_loop( base::MessageLoop::current()); base::RunLoop wait_window_resize; @@ -258,13 +215,13 @@ // Ignore the vsync provider by default. On ChromeOS this will be set // accordingly based on the display configuration. ignore_vsync_ = true; -#if defined(OS_CHROMEOS) + // We hold onto the main loop here to wait for the DisplayController // to give us the size of the display so we can create a window of // the same size. base::RunLoop wait_display_setup; DisplayConfiguratorObserver display_setup_observer(&wait_display_setup); - display_configurator_.reset(new display::DisplayConfigurator()); + display_configurator_ = std::make_unique<display::DisplayConfigurator>(); display_configurator_->SetDelegateForTesting(0); display_configurator_->AddObserver(&display_setup_observer); display_configurator_->Init( @@ -274,12 +231,13 @@ wait_display_setup.Run(); display_configurator_->RemoveObserver(&display_setup_observer); - gfx::Size framebuffer_size = display_configurator_->framebuffer_size(); - if (!framebuffer_size.IsEmpty()) { - window_size = framebuffer_size; + auto& cached_displays = display_configurator_->cached_displays(); + if (!cached_displays.empty()) { + DCHECK(cached_displays[0]->current_mode()); + window_size = cached_displays[0]->current_mode()->size(); ignore_vsync_ = false; } -#endif + if (ignore_vsync_) DVLOG(1) << "Ignoring vsync provider"; @@ -300,19 +258,11 @@ } void RenderingHelper::TearDown() { -#if defined(USE_X11) - // Destroy resources acquired in Initialize, in reverse-acquisition order. - if (window_) { - CHECK(XUnmapWindow(gfx::GetXDisplay(), window_)); - CHECK(XDestroyWindow(gfx::GetXDisplay(), window_)); - } -#elif defined(USE_OZONE) - platform_window_delegate_.reset(); #if defined(OS_CHROMEOS) + platform_window_delegate_.reset(); display_configurator_->PrepareForExit(); display_configurator_.reset(); #endif -#endif window_ = gfx::kNullAcceleratedWidget; } @@ -345,10 +295,10 @@ task_runner_ = base::ThreadTaskRunnerHandle::Get(); gl_surface_ = gl::init::CreateViewGLSurface(window_); -#if defined(USE_OZONE) +#if defined(OS_CHROMEOS) gl_surface_->Resize(platform_window_delegate_->GetSize(), 1.f, gl::GLSurface::ColorSpace::UNSPECIFIED, true); -#endif // defined(USE_OZONE) +#endif // defined(OS_CHROMEOS) screen_size_ = gl_surface_->GetSize(); gl_context_ = gl::init::CreateGLContext(nullptr, gl_surface_.get(), @@ -431,7 +381,7 @@ gl_Position = in_pos; }); -#if GL_VARIANT_EGL && !defined(OS_WIN) +#if !defined(OS_WIN) static const char kFragmentShader[] = "#extension GL_OES_EGL_image_external : enable\n" "precision mediump float;\n" @@ -494,7 +444,7 @@ if (!frame_duration_.is_zero()) { int warm_up_iterations = params.warm_up_iterations; -#if defined(USE_OZONE) +#if defined(OS_CHROMEOS) // On Ozone the VSyncProvider can't provide a vsync interval until // we render at least a frame, so we warm up with at least one // frame. @@ -749,11 +699,11 @@ } int tex_flip = !gl_surface_->FlipsVertically(); -#if defined(USE_OZONE) +#if defined(OS_CHROMEOS) // Ozone surfaceless renders flipped from normal GL, so there's no need to // do an extra flip. tex_flip = 0; -#endif // defined(USE_OZONE) +#endif // defined(OS_CHROMEOS) glUniform1i(glGetUniformLocation(program_, "tex_flip"), tex_flip); // Frames that will be returned to the client (via the no_longer_needed_cb)
diff --git a/media/gpu/rendering_helper.h b/media/gpu/rendering_helper.h index 54dcbed..40a3263 100644 --- a/media/gpu/rendering_helper.h +++ b/media/gpu/rendering_helper.h
@@ -190,14 +190,11 @@ scoped_refptr<gl::GLContext> gl_context_; scoped_refptr<gl::GLSurface> gl_surface_; -#if defined(USE_OZONE) +#if defined(OS_CHROMEOS) class StubOzoneDelegate; std::unique_ptr<StubOzoneDelegate> platform_window_delegate_; - -#if defined(OS_CHROMEOS) std::unique_ptr<display::DisplayConfigurator> display_configurator_; #endif -#endif bool ignore_vsync_;
diff --git a/media/gpu/video_decode_accelerator_unittest.cc b/media/gpu/video_decode_accelerator_unittest.cc index 2545016d..fce044c 100644 --- a/media/gpu/video_decode_accelerator_unittest.cc +++ b/media/gpu/video_decode_accelerator_unittest.cc
@@ -78,12 +78,12 @@ #include "media/gpu/vaapi_wrapper.h" #endif // BUILDFLAG(USE_VAAPI) -#if defined(USE_OZONE) +#if defined(OS_CHROMEOS) #include "ui/gfx/native_pixmap.h" #include "ui/ozone/public/ozone_gpu_test_helper.h" #include "ui/ozone/public/ozone_platform.h" #include "ui/ozone/public/surface_factory_ozone.h" -#endif // defined(USE_OZONE) +#endif // defined(OS_CHROMEOS) namespace media { @@ -269,7 +269,7 @@ FROM_HERE, base::Bind(&RenderingHelper::InitializeOneOff, &done)); done.Wait(); -#if defined(USE_OZONE) +#if defined(OS_CHROMEOS) gpu_helper_.reset(new ui::OzoneGpuTestHelper()); // Need to initialize after the rendering side since the rendering side // initializes the "GPU" parts of Ozone. @@ -289,7 +289,7 @@ } void TearDown() override { -#if defined(USE_OZONE) +#if defined(OS_CHROMEOS) gpu_helper_.reset(); #endif rendering_thread_.Stop(); @@ -301,7 +301,7 @@ private: base::Thread rendering_thread_; -#if defined(USE_OZONE) +#if defined(OS_CHROMEOS) std::unique_ptr<ui::OzoneGpuTestHelper> gpu_helper_; #endif @@ -336,7 +336,7 @@ uint32_t texture_id_; base::Closure no_longer_needed_cb_; -#if defined(USE_OZONE) +#if defined(OS_CHROMEOS) scoped_refptr<gfx::NativePixmap> pixmap_; #endif }; @@ -352,7 +352,7 @@ return make_scoped_refptr(new TextureRef(texture_id, no_longer_needed_cb)); } -#if defined(USE_OZONE) +#if defined(OS_CHROMEOS) gfx::BufferFormat VideoPixelFormatToGfxBufferFormat( VideoPixelFormat pixel_format) { switch (pixel_format) { @@ -376,7 +376,7 @@ VideoPixelFormat pixel_format, const gfx::Size& size) { scoped_refptr<TextureRef> texture_ref; -#if defined(USE_OZONE) +#if defined(OS_CHROMEOS) texture_ref = TextureRef::Create(texture_id, no_longer_needed_cb); LOG_ASSERT(texture_ref); @@ -395,7 +395,7 @@ gfx::GpuMemoryBufferHandle TextureRef::ExportGpuMemoryBufferHandle() const { gfx::GpuMemoryBufferHandle handle; -#if defined(USE_OZONE) +#if defined(OS_CHROMEOS) CHECK(pixmap_); int duped_fd = HANDLE_EINTR(dup(pixmap_->GetDmaBufFd(0))); LOG_ASSERT(duped_fd != -1) << "Failed duplicating dmabuf fd"; @@ -1827,7 +1827,7 @@ VDATestSuite(int argc, char** argv) : base::TestSuite(argc, argv) {} int Run() { -#if defined(OS_WIN) || defined(USE_OZONE) +#if defined(OS_WIN) || defined(OS_CHROMEOS) // For windows the decoding thread initializes the media foundation decoder // which uses COM. We need the thread to be a UI thread. // On Ozone, the backend initializes the event system using a UI @@ -1836,14 +1836,14 @@ base::test::ScopedTaskEnvironment::MainThreadType::UI); #else base::test::ScopedTaskEnvironment scoped_task_environment; -#endif // OS_WIN || USE_OZONE +#endif // OS_WIN || OS_CHROMEOS media::g_env = reinterpret_cast<media::VideoDecodeAcceleratorTestEnvironment*>( testing::AddGlobalTestEnvironment( new media::VideoDecodeAcceleratorTestEnvironment())); -#if defined(USE_OZONE) +#if defined(OS_CHROMEOS) ui::OzonePlatform::InitializeForUI(); #endif
diff --git a/media/mojo/clients/mojo_cdm.cc b/media/mojo/clients/mojo_cdm.cc index 8e7f8ca..74a06437 100644 --- a/media/mojo/clients/mojo_cdm.cc +++ b/media/mojo/clients/mojo_cdm.cc
@@ -21,14 +21,14 @@ #include "media/mojo/interfaces/decryptor.mojom.h" #include "services/service_manager/public/cpp/connect.h" #include "services/service_manager/public/interfaces/interface_provider.mojom.h" -#include "url/gurl.h" +#include "url/origin.h" namespace media { // static void MojoCdm::Create( const std::string& key_system, - const GURL& security_origin, + const url::Origin& security_origin, const CdmConfig& cdm_config, mojom::ContentDecryptionModulePtr remote_cdm, const SessionMessageCB& session_message_cb, @@ -96,7 +96,7 @@ // error handler can't be invoked and callbacks won't be dispatched. void MojoCdm::InitializeCdm(const std::string& key_system, - const GURL& security_origin, + const url::Origin& security_origin, const CdmConfig& cdm_config, std::unique_ptr<CdmInitializedPromise> promise) { DVLOG(1) << __func__ << ": " << key_system; @@ -116,8 +116,11 @@ pending_init_promise_ = std::move(promise); + // TODO(jrummell): Pass |security_origin| as a url.mojom.Origin. + // http://crbug.com/639438. remote_cdm_->Initialize( - key_system, security_origin.spec(), mojom::CdmConfig::From(cdm_config), + key_system, security_origin.Serialize(), + mojom::CdmConfig::From(cdm_config), base::Bind(&MojoCdm::OnCdmInitialized, base::Unretained(this))); }
diff --git a/media/mojo/clients/mojo_cdm.h b/media/mojo/clients/mojo_cdm.h index 3c93313..d239c22 100644 --- a/media/mojo/clients/mojo_cdm.h +++ b/media/mojo/clients/mojo_cdm.h
@@ -27,6 +27,10 @@ class SingleThreadTaskRunner; } +namespace url { +class Origin; +} + namespace media { class MojoDecryptor; @@ -42,7 +46,7 @@ static void Create( const std::string& key_system, - const GURL& security_origin, + const url::Origin& security_origin, const CdmConfig& cdm_config, mojom::ContentDecryptionModulePtr remote_cdm, const SessionMessageCB& session_message_cb, @@ -88,7 +92,7 @@ ~MojoCdm() final; void InitializeCdm(const std::string& key_system, - const GURL& security_origin, + const url::Origin& security_origin, const CdmConfig& cdm_config, std::unique_ptr<CdmInitializedPromise> promise);
diff --git a/media/mojo/clients/mojo_cdm_factory.cc b/media/mojo/clients/mojo_cdm_factory.cc index 91d140d..2b9f400a 100644 --- a/media/mojo/clients/mojo_cdm_factory.cc +++ b/media/mojo/clients/mojo_cdm_factory.cc
@@ -15,6 +15,7 @@ #include "media/mojo/features.h" #include "media/mojo/interfaces/interface_factory.mojom.h" #include "mojo/public/cpp/bindings/interface_request.h" +#include "url/origin.h" namespace media { @@ -28,7 +29,7 @@ void MojoCdmFactory::Create( const std::string& key_system, - const GURL& security_origin, + const url::Origin& security_origin, const CdmConfig& cdm_config, const SessionMessageCB& session_message_cb, const SessionClosedCB& session_closed_cb, @@ -37,7 +38,7 @@ const CdmCreatedCB& cdm_created_cb) { DVLOG(2) << __func__ << ": " << key_system; - if (!security_origin.is_valid()) { + if (security_origin.unique()) { base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::Bind(cdm_created_cb, nullptr, "Invalid origin.")); return;
diff --git a/media/mojo/clients/mojo_cdm_factory.h b/media/mojo/clients/mojo_cdm_factory.h index d53987f0..a7abe21 100644 --- a/media/mojo/clients/mojo_cdm_factory.h +++ b/media/mojo/clients/mojo_cdm_factory.h
@@ -21,7 +21,7 @@ // CdmFactory implementation. void Create(const std::string& key_system, - const GURL& security_origin, + const url::Origin& security_origin, const CdmConfig& cdm_config, const SessionMessageCB& session_message_cb, const SessionClosedCB& session_closed_cb,
diff --git a/media/mojo/clients/mojo_cdm_unittest.cc b/media/mojo/clients/mojo_cdm_unittest.cc index d70f8a7f..ed448378 100644 --- a/media/mojo/clients/mojo_cdm_unittest.cc +++ b/media/mojo/clients/mojo_cdm_unittest.cc
@@ -21,6 +21,8 @@ #include "media/mojo/services/mojo_cdm_service_context.h" #include "mojo/public/cpp/bindings/interface_request.h" #include "testing/gtest/include/gtest/gtest.h" +#include "url/gurl.h" +#include "url/origin.h" using ::testing::_; using ::testing::DoAll; @@ -106,8 +108,8 @@ } } - MojoCdm::Create(key_system, GURL(kTestSecurityOrigin), CdmConfig(), - std::move(remote_cdm), + MojoCdm::Create(key_system, url::Origin(GURL(kTestSecurityOrigin)), + CdmConfig(), std::move(remote_cdm), base::Bind(&MockCdmClient::OnSessionMessage, base::Unretained(&cdm_client_)), base::Bind(&MockCdmClient::OnSessionClosed,
diff --git a/media/mojo/services/mojo_cdm_service.cc b/media/mojo/services/mojo_cdm_service.cc index 9487445..af835c5 100644 --- a/media/mojo/services/mojo_cdm_service.cc +++ b/media/mojo/services/mojo_cdm_service.cc
@@ -20,6 +20,7 @@ #include "media/mojo/common/media_type_converters.h" #include "media/mojo/services/mojo_cdm_service_context.h" #include "url/gurl.h" +#include "url/origin.h" namespace media { @@ -67,7 +68,8 @@ auto weak_this = weak_factory_.GetWeakPtr(); cdm_factory_->Create( - key_system, GURL(security_origin), cdm_config.To<CdmConfig>(), + key_system, url::Origin(GURL(security_origin)), + cdm_config.To<CdmConfig>(), base::Bind(&MojoCdmService::OnSessionMessage, weak_this), base::Bind(&MojoCdmService::OnSessionClosed, weak_this), base::Bind(&MojoCdmService::OnSessionKeysChange, weak_this),
diff --git a/media/remoting/BUILD.gn b/media/remoting/BUILD.gn index eb835ff..b98c682 100644 --- a/media/remoting/BUILD.gn +++ b/media/remoting/BUILD.gn
@@ -63,6 +63,7 @@ "//media/mojo/interfaces:remoting", "//mojo/public/cpp/bindings", "//ui/gfx", + "//url", ] if (enable_media_remoting_rpc) {
diff --git a/media/remoting/remoting_cdm_factory.cc b/media/remoting/remoting_cdm_factory.cc index 635036a..7f37539 100644 --- a/media/remoting/remoting_cdm_factory.cc +++ b/media/remoting/remoting_cdm_factory.cc
@@ -9,6 +9,7 @@ #include "base/single_thread_task_runner.h" #include "media/base/cdm_config.h" #include "media/remoting/remoting_cdm.h" +#include "url/origin.h" namespace media { namespace remoting { @@ -48,7 +49,7 @@ // TODO(xjz): Replace the callbacks with an interface. http://crbug.com/657940. void RemotingCdmFactory::Create( const std::string& key_system, - const GURL& security_origin, + const url::Origin& security_origin, const CdmConfig& cdm_config, const SessionMessageCB& session_message_cb, const SessionClosedCB& session_closed_cb, @@ -77,7 +78,7 @@ void RemotingCdmFactory::CreateCdm( const std::string& key_system, - const GURL& security_origin, + const url::Origin& security_origin, const CdmConfig& cdm_config, const SessionMessageCB& session_message_cb, const SessionClosedCB& session_closed_cb,
diff --git a/media/remoting/remoting_cdm_factory.h b/media/remoting/remoting_cdm_factory.h index eaba632..6c04344 100644 --- a/media/remoting/remoting_cdm_factory.h +++ b/media/remoting/remoting_cdm_factory.h
@@ -27,7 +27,7 @@ ~RemotingCdmFactory() override; void Create(const std::string& key_system, - const GURL& security_origin, + const url::Origin& security_origin, const CdmConfig& cdm_config, const SessionMessageCB& session_message_cb, const SessionClosedCB& session_closed_cb, @@ -38,7 +38,7 @@ private: std::unique_ptr<RemotingCdmController> CreateRemotingCdmController(); void CreateCdm(const std::string& key_system, - const GURL& security_origin, + const url::Origin& security_origin, const CdmConfig& cdm_config, const SessionMessageCB& session_message_cb, const SessionClosedCB& session_closed_cb,
diff --git a/media/test/fake_encrypted_media.cc b/media/test/fake_encrypted_media.cc index fabccc6..52968ca1 100644 --- a/media/test/fake_encrypted_media.cc +++ b/media/test/fake_encrypted_media.cc
@@ -7,6 +7,7 @@ #include "base/bind.h" #include "media/base/cdm_key_information.h" #include "media/cdm/aes_decryptor.h" +#include "url/origin.h" namespace media { @@ -23,7 +24,7 @@ FakeEncryptedMedia::FakeEncryptedMedia(AppBase* app) : decryptor_(new AesDecryptor( - GURL::EmptyGURL(), + url::Origin(), base::Bind(&FakeEncryptedMedia::OnSessionMessage, base::Unretained(this)), base::Bind(&FakeEncryptedMedia::OnSessionClosed,
diff --git a/mojo/public/cpp/bindings/lib/sync_event_watcher.cc b/mojo/public/cpp/bindings/lib/sync_event_watcher.cc index e64e604..19a41eb5 100644 --- a/mojo/public/cpp/bindings/lib/sync_event_watcher.cc +++ b/mojo/public/cpp/bindings/lib/sync_event_watcher.cc
@@ -18,7 +18,7 @@ SyncEventWatcher::~SyncEventWatcher() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (registered_) - registry_->UnregisterEvent(event_); + registry_->UnregisterEvent(event_, callback_); destroyed_->data = true; } @@ -51,15 +51,17 @@ void SyncEventWatcher::IncrementRegisterCount() { register_request_count_++; - if (!registered_) - registered_ = registry_->RegisterEvent(event_, callback_); + if (!registered_) { + registry_->RegisterEvent(event_, callback_); + registered_ = true; + } } void SyncEventWatcher::DecrementRegisterCount() { DCHECK_GT(register_request_count_, 0u); register_request_count_--; if (register_request_count_ == 0 && registered_) { - registry_->UnregisterEvent(event_); + registry_->UnregisterEvent(event_, callback_); registered_ = false; } }
diff --git a/mojo/public/cpp/bindings/lib/sync_handle_registry.cc b/mojo/public/cpp/bindings/lib/sync_handle_registry.cc index 8ac451c7..a7a5a6f 100644 --- a/mojo/public/cpp/bindings/lib/sync_handle_registry.cc +++ b/mojo/public/cpp/bindings/lib/sync_handle_registry.cc
@@ -4,6 +4,8 @@ #include "mojo/public/cpp/bindings/sync_handle_registry.h" +#include <algorithm> + #include "base/lazy_instance.h" #include "base/logging.h" #include "base/stl_util.h" @@ -62,23 +64,52 @@ handles_.erase(handle); } -bool SyncHandleRegistry::RegisterEvent(base::WaitableEvent* event, +void SyncHandleRegistry::RegisterEvent(base::WaitableEvent* event, const base::Closure& callback) { - auto result = events_.insert({event, callback}); - DCHECK(result.second); - MojoResult rv = wait_set_.AddEvent(event); - if (rv == MOJO_RESULT_OK) - return true; - DCHECK_EQ(MOJO_RESULT_ALREADY_EXISTS, rv); - return false; + auto it = events_.find(event); + if (it == events_.end()) { + auto result = events_.emplace(event, EventCallbackList{}); + it = result.first; + } + + auto& callbacks = it->second.container(); + if (callbacks.empty()) { + // AddEvent() must succeed since we only attempt it when there are + // previously no callbacks registered for this event. + MojoResult rv = wait_set_.AddEvent(event); + DCHECK_EQ(MOJO_RESULT_OK, rv); + } + + callbacks.push_back(callback); } -void SyncHandleRegistry::UnregisterEvent(base::WaitableEvent* event) { +void SyncHandleRegistry::UnregisterEvent(base::WaitableEvent* event, + const base::Closure& callback) { auto it = events_.find(event); - DCHECK(it != events_.end()); - events_.erase(it); - MojoResult rv = wait_set_.RemoveEvent(event); - DCHECK_EQ(MOJO_RESULT_OK, rv); + if (it == events_.end()) + return; + + auto& callbacks = it->second.container(); + if (is_dispatching_event_callbacks_) { + // Not safe to remove any elements from |callbacks| here since an outer + // stack frame is currently iterating over it in Wait(). + for (auto& cb : callbacks) { + if (cb.Equals(callback)) + cb.Reset(); + } + remove_invalid_event_callbacks_after_dispatch_ = true; + } else { + callbacks.erase(std::remove_if(callbacks.begin(), callbacks.end(), + [&callback](const base::Closure& cb) { + return cb.Equals(callback); + }), + callbacks.end()); + if (callbacks.empty()) { + events_.erase(it); + MojoResult rv = wait_set_.RemoveEvent(event); + DCHECK_EQ(MOJO_RESULT_OK, rv); + } + } } bool SyncHandleRegistry::Wait(const bool* should_stop[], size_t count) { @@ -109,7 +140,29 @@ if (ready_event) { const auto iter = events_.find(ready_event); DCHECK(iter != events_.end()); - iter->second.Run(); + bool was_dispatching_event_callbacks = is_dispatching_event_callbacks_; + is_dispatching_event_callbacks_ = true; + + // NOTE: It's possible for the container to be extended by any of these + // callbacks if they call RegisterEvent, so we are careful to iterate by + // index. Also note that conversely, elements cannot be *removed* from the + // container, by any of these callbacks, so it is safe to assume the size + // only stays the same or increases, with no elements changing position. + auto& callbacks = iter->second.container(); + for (size_t i = 0; i < callbacks.size(); ++i) { + auto& callback = callbacks[i]; + if (callback) + callback.Run(); + } + + is_dispatching_event_callbacks_ = was_dispatching_event_callbacks; + if (!was_dispatching_event_callbacks && + remove_invalid_event_callbacks_after_dispatch_) { + // If we've had events unregistered within any callback dispatch, now is + // a good time to prune them from the map. + RemoveInvalidEventCallbacks(); + remove_invalid_event_callbacks_after_dispatch_ = false; + } } }; @@ -120,4 +173,22 @@ SyncHandleRegistry::~SyncHandleRegistry() = default; +void SyncHandleRegistry::RemoveInvalidEventCallbacks() { + for (auto it = events_.begin(); it != events_.end();) { + auto& callbacks = it->second.container(); + callbacks.erase( + std::remove_if(callbacks.begin(), callbacks.end(), + [](const base::Closure& callback) { return !callback; }), + callbacks.end()); + if (callbacks.empty()) { + MojoResult rv = wait_set_.RemoveEvent(it->first); + DCHECK_EQ(MOJO_RESULT_OK, rv); + + events_.erase(it++); + } else { + ++it; + } + } +} + } // namespace mojo
diff --git a/mojo/public/cpp/bindings/sync_handle_registry.h b/mojo/public/cpp/bindings/sync_handle_registry.h index de766151..cd535aa 100644 --- a/mojo/public/cpp/bindings/sync_handle_registry.h +++ b/mojo/public/cpp/bindings/sync_handle_registry.h
@@ -6,9 +6,9 @@ #define MOJO_PUBLIC_CPP_BINDINGS_SYNC_HANDLE_REGISTRY_H_ #include <map> -#include <unordered_map> #include "base/callback.h" +#include "base/containers/stack_container.h" #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/sequence_checker.h" @@ -30,6 +30,10 @@ static scoped_refptr<SyncHandleRegistry> current(); using HandleCallback = base::Callback<void(MojoResult)>; + + // Registers a |Handle| to be watched for |handle_signals|. If any such + // signals are satisfied during a Wait(), the Wait() is woken up and + // |callback| is run. bool RegisterHandle(const Handle& handle, MojoHandleSignals handle_signals, const HandleCallback& callback); @@ -38,11 +42,13 @@ // Registers a |base::WaitableEvent| which can be used to wake up // Wait() before any handle signals. |event| is not owned, and if it signals - // during Wait(), |callback| is invoked. Returns |true| if registered - // successfully or |false| if |event| was already registered. - bool RegisterEvent(base::WaitableEvent* event, const base::Closure& callback); + // during Wait(), |callback| is invoked. Note that |event| may be registered + // multiple times with different callbacks. + void RegisterEvent(base::WaitableEvent* event, const base::Closure& callback); - void UnregisterEvent(base::WaitableEvent* event); + // Unregisters a specific |event|+|callback| pair. + void UnregisterEvent(base::WaitableEvent* event, + const base::Closure& callback); // Waits on all the registered handles and events and runs callbacks // synchronously for any that become ready. @@ -54,12 +60,26 @@ private: friend class base::RefCounted<SyncHandleRegistry>; + using EventCallbackList = base::StackVector<base::Closure, 1>; + using EventMap = std::map<base::WaitableEvent*, EventCallbackList>; + SyncHandleRegistry(); ~SyncHandleRegistry(); + void RemoveInvalidEventCallbacks(); + WaitSet wait_set_; std::map<Handle, HandleCallback> handles_; - std::map<base::WaitableEvent*, base::Closure> events_; + EventMap events_; + + // |true| iff this registry is currently dispatching event callbacks in + // Wait(). Used to allow for safe event registration/unregistration from event + // callbacks. + bool is_dispatching_event_callbacks_ = false; + + // Indicates if one or more event callbacks was unregistered during the most + // recent event callback dispatch. + bool remove_invalid_event_callbacks_after_dispatch_ = false; SEQUENCE_CHECKER(sequence_checker_);
diff --git a/mojo/public/tools/bindings/chromium_bindings_configuration.gni b/mojo/public/tools/bindings/chromium_bindings_configuration.gni index 0632a62..6fe236d 100644 --- a/mojo/public/tools/bindings/chromium_bindings_configuration.gni +++ b/mojo/public/tools/bindings/chromium_bindings_configuration.gni
@@ -19,6 +19,7 @@ "//content/public/common/typemaps.gni", "//device/bluetooth/public/interfaces/typemaps.gni", "//device/gamepad/public/interfaces/typemaps.gni", + "//device/hid/public/interfaces/typemaps.gni", "//extensions/common/typemaps.gni", "//gpu/ipc/common/typemaps.gni", "//media/capture/mojo/typemaps.gni",
diff --git a/net/quic/chromium/crypto/proof_source_chromium.cc b/net/quic/chromium/crypto/proof_source_chromium.cc index 4f5608a..1ce25217 100644 --- a/net/quic/chromium/crypto/proof_source_chromium.cc +++ b/net/quic/chromium/crypto/proof_source_chromium.cc
@@ -153,4 +153,45 @@ callback->Run(ok, chain, out_proof, nullptr /* details */); } +QuicReferenceCountedPointer<ProofSource::Chain> +ProofSourceChromium::GetCertChain(const QuicSocketAddress& server_address, + const std::string& hostname) { + return chain_; +} + +void ProofSourceChromium::ComputeTlsSignature( + const QuicSocketAddress& server_address, + const std::string& hostname, + uint16_t signature_algorithm, + QuicStringPiece in, + std::unique_ptr<SignatureCallback> callback) { + crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); + bssl::ScopedEVP_MD_CTX sign_context; + EVP_PKEY_CTX* pkey_ctx; + + size_t siglen; + string sig; + if (!EVP_DigestSignInit(sign_context.get(), &pkey_ctx, EVP_sha256(), nullptr, + private_key_->key()) || + !EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING) || + !EVP_PKEY_CTX_set_rsa_pss_saltlen(pkey_ctx, -1) || + !EVP_DigestSignUpdate(sign_context.get(), + reinterpret_cast<const uint8_t*>(in.data()), + in.size()) || + !EVP_DigestSignFinal(sign_context.get(), nullptr, &siglen)) { + callback->Run(false, sig); + return; + } + sig.resize(siglen); + if (!EVP_DigestSignFinal( + sign_context.get(), + reinterpret_cast<uint8_t*>(const_cast<char*>(sig.data())), &siglen)) { + callback->Run(false, sig); + return; + } + sig.resize(siglen); + + callback->Run(true, sig); +} + } // namespace net
diff --git a/net/quic/chromium/crypto/proof_source_chromium.h b/net/quic/chromium/crypto/proof_source_chromium.h index 00f6d3b..896ea5c 100644 --- a/net/quic/chromium/crypto/proof_source_chromium.h +++ b/net/quic/chromium/crypto/proof_source_chromium.h
@@ -22,6 +22,19 @@ // TODO(rtenneti): implement details of this class. class NET_EXPORT_PRIVATE ProofSourceChromium : public ProofSource { public: + // TODO(merge): Remove this class. + class SignatureCallback { + public: + SignatureCallback() {} + virtual ~SignatureCallback() = default; + + virtual void Run(bool ok, std::string signature) = 0; + + private: + SignatureCallback(const SignatureCallback&) = delete; + SignatureCallback& operator=(const SignatureCallback&) = delete; + }; + ProofSourceChromium(); ~ProofSourceChromium() override; @@ -41,6 +54,18 @@ const QuicTagVector& connection_options, std::unique_ptr<Callback> callback) override; + // TODO(merge): Change this from 'virtual' to 'override'. + virtual QuicReferenceCountedPointer<Chain> GetCertChain( + const QuicSocketAddress& server_address, + const std::string& hostname); + + // TODO(merge): Change this from 'virtual' to 'override'. + virtual void ComputeTlsSignature(const QuicSocketAddress& server_address, + const std::string& hostname, + uint16_t signature_algorithm, + QuicStringPiece in, + std::unique_ptr<SignatureCallback> callback); + private: bool GetProofInner(const QuicSocketAddress& server_ip, const std::string& hostname,
diff --git a/net/quic/chromium/crypto/proof_test_chromium.cc b/net/quic/chromium/crypto/proof_test_chromium.cc index f6bfd15..1d8bbed2 100644 --- a/net/quic/chromium/crypto/proof_test_chromium.cc +++ b/net/quic/chromium/crypto/proof_test_chromium.cc
@@ -11,12 +11,15 @@ #include "net/cert/cert_status_flags.h" #include "net/cert/cert_verify_result.h" #include "net/cert/x509_certificate.h" +// TODO(merge): Remove the following include. +#include "net/quic/chromium/crypto/proof_source_chromium.h" #include "net/quic/core/crypto/proof_source.h" #include "net/quic/core/crypto/proof_verifier.h" #include "net/quic/test_tools/crypto_test_utils.h" #include "net/test/cert_test_util.h" #include "net/test/test_data_directory.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/boringssl/src/include/openssl/ssl.h" using std::string; @@ -189,6 +192,84 @@ first_chlo_hash, wrong_certs, corrupt_signature, false); } +namespace { +// TODO(merge): Change ProofSourceChromium::SignatureCallback to +// ProofSource::SignatureCallback. +class TestingSignatureCallback : public ProofSourceChromium::SignatureCallback { + public: + TestingSignatureCallback(bool* ok_out, std::string* signature_out) + : ok_out_(ok_out), signature_out_(signature_out) {} + + void Run(bool ok, std::string signature) override { + *ok_out_ = ok; + *signature_out_ = std::move(signature); + } + + private: + bool* ok_out_; + std::string* signature_out_; +}; + +} // namespace + +TEST_P(ProofTest, TlsSignature) { + // TODO(merge): Change 'proof_source' to 'source' and remove the following + // static_cast. + std::unique_ptr<ProofSource> proof_source( + crypto_test_utils::ProofSourceForTesting()); + std::unique_ptr<ProofSourceChromium> source( + static_cast<ProofSourceChromium*>(proof_source.release())); + + QuicSocketAddress server_address; + const string hostname = "test.example.com"; + + QuicReferenceCountedPointer<ProofSource::Chain> chain = + source->GetCertChain(server_address, hostname); + ASSERT_GT(chain->certs.size(), 0ul); + + // Generate a value to be signed similar to the example in TLS 1.3 section + // 4.4.3. The value to be signed starts with octed 0x20 repeated 64 times, + // followed by the context string, followed by a single 0 byte, followed by + // the transcript hash. Since there's no TLS stack here, we're using 32 bytes + // of 01 as the transcript hash. + string to_be_signed(64, ' '); + to_be_signed.append("TLS 1.3, server CertificateVerify"); + to_be_signed.append(1, '\0'); + to_be_signed.append(32, 1); + + string sig; + bool success; + std::unique_ptr<TestingSignatureCallback> callback = + QuicMakeUnique<TestingSignatureCallback>(&success, &sig); + source->ComputeTlsSignature(server_address, hostname, SSL_SIGN_RSA_PSS_SHA256, + to_be_signed, std::move(callback)); + EXPECT_TRUE(success); + + // Verify that the signature from ComputeTlsSignature can be verified with the + // leaf cert from GetCertChain. + const uint8_t* data; + const uint8_t* orig_data; + orig_data = data = reinterpret_cast<const uint8_t*>(chain->certs[0].data()); + bssl::UniquePtr<X509> leaf(d2i_X509(nullptr, &data, chain->certs[0].size())); + ASSERT_NE(leaf.get(), nullptr); + EXPECT_EQ(data - orig_data, static_cast<ptrdiff_t>(chain->certs[0].size())); + bssl::UniquePtr<EVP_PKEY> pkey(X509_get_pubkey(leaf.get())); + bssl::ScopedEVP_MD_CTX md_ctx; + EVP_PKEY_CTX* ctx; + ASSERT_EQ(EVP_DigestVerifyInit(md_ctx.get(), &ctx, EVP_sha256(), nullptr, + pkey.get()), + 1); + ASSERT_EQ(EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PSS_PADDING), 1); + ASSERT_EQ(EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, -1), 1); + ASSERT_EQ(EVP_DigestVerifyUpdate(md_ctx.get(), to_be_signed.data(), + to_be_signed.size()), + 1); + EXPECT_EQ(EVP_DigestVerifyFinal(md_ctx.get(), + reinterpret_cast<const uint8_t*>(sig.data()), + sig.size()), + 1); +} + TEST_P(ProofTest, UseAfterFree) { std::unique_ptr<ProofSource> source( crypto_test_utils::ProofSourceForTesting());
diff --git a/ppapi/proxy/interface_proxy.h b/ppapi/proxy/interface_proxy.h index 6cfd7d76..ab62f1b 100644 --- a/ppapi/proxy/interface_proxy.h +++ b/ppapi/proxy/interface_proxy.h
@@ -23,20 +23,20 @@ // is transferred to the caller. typedef InterfaceProxy* (*Factory)(Dispatcher* dispatcher); - virtual ~InterfaceProxy(); + ~InterfaceProxy() override; Dispatcher* dispatcher() const { return dispatcher_; } // IPC::Sender implementation. - virtual bool Send(IPC::Message* msg); + bool Send(IPC::Message* msg) override; // Sub-classes must implement IPC::Listener which contains this: - //virtual bool OnMessageReceived(const IPC::Message& msg); + // virtual bool OnMessageReceived(const Message& message) = 0; protected: // Creates the given interface associated with the given dispatcher. The // dispatcher manages our lifetime. - InterfaceProxy(Dispatcher* dispatcher); + explicit InterfaceProxy(Dispatcher* dispatcher); private: Dispatcher* dispatcher_;
diff --git a/ppapi/proxy/ppb_audio_proxy.h b/ppapi/proxy/ppb_audio_proxy.h index a738104a..b4d3091 100644 --- a/ppapi/proxy/ppb_audio_proxy.h +++ b/ppapi/proxy/ppb_audio_proxy.h
@@ -32,8 +32,8 @@ class PPB_Audio_Proxy : public InterfaceProxy { public: - PPB_Audio_Proxy(Dispatcher* dispatcher); - virtual ~PPB_Audio_Proxy(); + explicit PPB_Audio_Proxy(Dispatcher* dispatcher); + ~PPB_Audio_Proxy() override; // Creates an Audio object in the plugin process. static PP_Resource CreateProxyResource( @@ -43,7 +43,7 @@ void* user_data); // InterfaceProxy implementation. - virtual bool OnMessageReceived(const IPC::Message& msg); + bool OnMessageReceived(const IPC::Message& msg) override; static const ApiID kApiID = API_ID_PPB_AUDIO;
diff --git a/ppapi/proxy/ppb_broker_proxy.h b/ppapi/proxy/ppb_broker_proxy.h index 7baf3a2..ec29de43 100644 --- a/ppapi/proxy/ppb_broker_proxy.h +++ b/ppapi/proxy/ppb_broker_proxy.h
@@ -23,12 +23,12 @@ class PPB_Broker_Proxy : public InterfaceProxy { public: explicit PPB_Broker_Proxy(Dispatcher* dispatcher); - virtual ~PPB_Broker_Proxy(); + ~PPB_Broker_Proxy() override; static PP_Resource CreateProxyResource(PP_Instance instance); // InterfaceProxy implementation. - virtual bool OnMessageReceived(const IPC::Message& msg); + bool OnMessageReceived(const IPC::Message& msg) override; static const ApiID kApiID = API_ID_PPB_BROKER;
diff --git a/ppapi/proxy/ppb_buffer_proxy.h b/ppapi/proxy/ppb_buffer_proxy.h index b3ba248..b36750a2 100644 --- a/ppapi/proxy/ppb_buffer_proxy.h +++ b/ppapi/proxy/ppb_buffer_proxy.h
@@ -52,7 +52,7 @@ class PPB_Buffer_Proxy : public InterfaceProxy { public: explicit PPB_Buffer_Proxy(Dispatcher* dispatcher); - virtual ~PPB_Buffer_Proxy(); + ~PPB_Buffer_Proxy() override; static PP_Resource CreateProxyResource(PP_Instance instance, uint32_t size); @@ -61,7 +61,7 @@ uint32_t size); // InterfaceProxy implementation. - virtual bool OnMessageReceived(const IPC::Message& msg); + bool OnMessageReceived(const IPC::Message& msg) override; static const ApiID kApiID = API_ID_PPB_BUFFER;
diff --git a/ppapi/proxy/ppb_core_proxy.h b/ppapi/proxy/ppb_core_proxy.h index a564519..aea10964 100644 --- a/ppapi/proxy/ppb_core_proxy.h +++ b/ppapi/proxy/ppb_core_proxy.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 PPAPI_PPB_CORE_PROXY_H_ -#define PPAPI_PPB_CORE_PROXY_H_ +#ifndef PPAPI_PROXY_PPB_CORE_PROXY_H_ +#define PPAPI_PROXY_PPB_CORE_PROXY_H_ #include "ppapi/c/pp_completion_callback.h" #include "ppapi/c/pp_resource.h" @@ -17,13 +17,13 @@ class PPB_Core_Proxy : public InterfaceProxy { public: - PPB_Core_Proxy(Dispatcher* dispatcher); - virtual ~PPB_Core_Proxy(); + explicit PPB_Core_Proxy(Dispatcher* dispatcher); + ~PPB_Core_Proxy() override; static const PPB_Core* GetPPB_Core_Interface(); // InterfaceProxy implementation. - virtual bool OnMessageReceived(const IPC::Message& msg); + bool OnMessageReceived(const IPC::Message& msg) override; static const ApiID kApiID = API_ID_PPB_CORE; @@ -41,4 +41,4 @@ } // namespace proxy } // namespace ppapi -#endif // PPAPI_PPB_CORE_PROXY_H_ +#endif // PPAPI_PROXY_PPB_CORE_PROXY_H_
diff --git a/ppapi/proxy/ppb_message_loop_proxy.h b/ppapi/proxy/ppb_message_loop_proxy.h index f78c3772..9c15539 100644 --- a/ppapi/proxy/ppb_message_loop_proxy.h +++ b/ppapi/proxy/ppb_message_loop_proxy.h
@@ -121,7 +121,7 @@ class PPB_MessageLoop_Proxy : public InterfaceProxy { public: explicit PPB_MessageLoop_Proxy(Dispatcher* dispatcher); - virtual ~PPB_MessageLoop_Proxy(); + ~PPB_MessageLoop_Proxy() override; static const PPB_MessageLoop_1_0* GetInterface();
diff --git a/ppapi/proxy/ppb_testing_proxy.h b/ppapi/proxy/ppb_testing_proxy.h index c4b149ac..8340e79 100644 --- a/ppapi/proxy/ppb_testing_proxy.h +++ b/ppapi/proxy/ppb_testing_proxy.h
@@ -24,13 +24,13 @@ class PPB_Testing_Proxy : public InterfaceProxy { public: - PPB_Testing_Proxy(Dispatcher* dispatcher); - virtual ~PPB_Testing_Proxy(); + explicit PPB_Testing_Proxy(Dispatcher* dispatcher); + ~PPB_Testing_Proxy() override; static const PPB_Testing_Private* GetProxyInterface(); // InterfaceProxy implementation. - virtual bool OnMessageReceived(const IPC::Message& msg); + bool OnMessageReceived(const IPC::Message& msg) override; private: // Message handlers.
diff --git a/ppapi/proxy/ppb_var_deprecated_proxy.h b/ppapi/proxy/ppb_var_deprecated_proxy.h index 508b492..a281018 100644 --- a/ppapi/proxy/ppb_var_deprecated_proxy.h +++ b/ppapi/proxy/ppb_var_deprecated_proxy.h
@@ -28,12 +28,12 @@ class PPB_Var_Deprecated_Proxy : public InterfaceProxy { public: explicit PPB_Var_Deprecated_Proxy(Dispatcher* dispatcher); - virtual ~PPB_Var_Deprecated_Proxy(); + ~PPB_Var_Deprecated_Proxy() override; static const PPB_Var_Deprecated* GetProxyInterface(); // InterfaceProxy implementation. - virtual bool OnMessageReceived(const IPC::Message& msg); + bool OnMessageReceived(const IPC::Message& msg) override; private: // Message handlers.
diff --git a/ppapi/proxy/ppb_video_decoder_proxy.h b/ppapi/proxy/ppb_video_decoder_proxy.h index 0b2a6f69..a74a874 100644 --- a/ppapi/proxy/ppb_video_decoder_proxy.h +++ b/ppapi/proxy/ppb_video_decoder_proxy.h
@@ -20,8 +20,8 @@ class PPB_VideoDecoder_Proxy : public InterfaceProxy { public: - PPB_VideoDecoder_Proxy(Dispatcher* dispatcher); - virtual ~PPB_VideoDecoder_Proxy(); + explicit PPB_VideoDecoder_Proxy(Dispatcher* dispatcher); + ~PPB_VideoDecoder_Proxy() override; // Creates a VideoDecoder object in the plugin process. static PP_Resource CreateProxyResource( @@ -30,7 +30,7 @@ PP_VideoDecoder_Profile profile); // InterfaceProxy implementation. - virtual bool OnMessageReceived(const IPC::Message& msg); + bool OnMessageReceived(const IPC::Message& msg) override; static const ApiID kApiID = API_ID_PPB_VIDEO_DECODER_DEV;
diff --git a/ppapi/proxy/ppp_class_proxy.h b/ppapi/proxy/ppp_class_proxy.h index c70b564..8ee1189a 100644 --- a/ppapi/proxy/ppp_class_proxy.h +++ b/ppapi/proxy/ppp_class_proxy.h
@@ -30,7 +30,7 @@ // PPP_Class isn't a normal interface that you can query for, so this // constructor doesn't take an interface pointer. explicit PPP_Class_Proxy(Dispatcher* dispatcher); - virtual ~PPP_Class_Proxy(); + ~PPP_Class_Proxy() override; // Factory function used for registration (normal code can just use the // constructor). @@ -50,7 +50,7 @@ int64_t* ppp_class_data); // InterfaceProxy implementation. - virtual bool OnMessageReceived(const IPC::Message& msg); + bool OnMessageReceived(const IPC::Message& msg) override; private: // IPC message handlers.
diff --git a/ppapi/proxy/ppp_content_decryptor_private_proxy.h b/ppapi/proxy/ppp_content_decryptor_private_proxy.h index 5987452..7a35292 100644 --- a/ppapi/proxy/ppp_content_decryptor_private_proxy.h +++ b/ppapi/proxy/ppp_content_decryptor_private_proxy.h
@@ -25,13 +25,13 @@ class PPP_ContentDecryptor_Private_Proxy : public InterfaceProxy { public: explicit PPP_ContentDecryptor_Private_Proxy(Dispatcher* dispatcher); - virtual ~PPP_ContentDecryptor_Private_Proxy(); + ~PPP_ContentDecryptor_Private_Proxy() override; static const PPP_ContentDecryptor_Private* GetProxyInterface(); private: // InterfaceProxy implementation. - virtual bool OnMessageReceived(const IPC::Message& msg); + bool OnMessageReceived(const IPC::Message& msg) override; // Message handlers. void OnMsgInitialize(PP_Instance instance,
diff --git a/ppapi/proxy/ppp_find_proxy.h b/ppapi/proxy/ppp_find_proxy.h index 8e07d7e..4e0b783 100644 --- a/ppapi/proxy/ppp_find_proxy.h +++ b/ppapi/proxy/ppp_find_proxy.h
@@ -18,12 +18,12 @@ class PPP_Find_Proxy : public InterfaceProxy { public: explicit PPP_Find_Proxy(Dispatcher* dispatcher); - virtual ~PPP_Find_Proxy(); + ~PPP_Find_Proxy() override; static const PPP_Find_Private* GetProxyInterface(); // InterfaceProxy implementation. - virtual bool OnMessageReceived(const IPC::Message& msg); + bool OnMessageReceived(const IPC::Message& msg) override; private: // Message handlers.
diff --git a/ppapi/proxy/ppp_graphics_3d_proxy.h b/ppapi/proxy/ppp_graphics_3d_proxy.h index 6897e6b..1b6e91a 100644 --- a/ppapi/proxy/ppp_graphics_3d_proxy.h +++ b/ppapi/proxy/ppp_graphics_3d_proxy.h
@@ -16,13 +16,13 @@ class PPP_Graphics3D_Proxy : public InterfaceProxy { public: - PPP_Graphics3D_Proxy(Dispatcher* dispatcher); - virtual ~PPP_Graphics3D_Proxy(); + explicit PPP_Graphics3D_Proxy(Dispatcher* dispatcher); + ~PPP_Graphics3D_Proxy() override; static const PPP_Graphics3D* GetProxyInterface(); // InterfaceProxy implementation. - virtual bool OnMessageReceived(const IPC::Message& msg); + bool OnMessageReceived(const IPC::Message& msg) override; private: // Message handlers.
diff --git a/ppapi/proxy/ppp_input_event_proxy.h b/ppapi/proxy/ppp_input_event_proxy.h index 01479da7..753714e 100644 --- a/ppapi/proxy/ppp_input_event_proxy.h +++ b/ppapi/proxy/ppp_input_event_proxy.h
@@ -18,13 +18,13 @@ class PPP_InputEvent_Proxy : public InterfaceProxy { public: - PPP_InputEvent_Proxy(Dispatcher* dispatcher); - virtual ~PPP_InputEvent_Proxy(); + explicit PPP_InputEvent_Proxy(Dispatcher* dispatcher); + ~PPP_InputEvent_Proxy() override; static const PPP_InputEvent* GetProxyInterface(); // InterfaceProxy implementation. - virtual bool OnMessageReceived(const IPC::Message& msg); + bool OnMessageReceived(const IPC::Message& msg) override; private: // Message handlers.
diff --git a/ppapi/proxy/ppp_instance_private_proxy.h b/ppapi/proxy/ppp_instance_private_proxy.h index f430203..f4ed0b8 100644 --- a/ppapi/proxy/ppp_instance_private_proxy.h +++ b/ppapi/proxy/ppp_instance_private_proxy.h
@@ -20,14 +20,14 @@ class PPP_Instance_Private_Proxy : public InterfaceProxy { public: - PPP_Instance_Private_Proxy(Dispatcher* dispatcher); - virtual ~PPP_Instance_Private_Proxy(); + explicit PPP_Instance_Private_Proxy(Dispatcher* dispatcher); + ~PPP_Instance_Private_Proxy() override; static const PPP_Instance_Private* GetProxyInterface(); private: // InterfaceProxy implementation. - virtual bool OnMessageReceived(const IPC::Message& msg); + bool OnMessageReceived(const IPC::Message& msg) override; // Message handlers. void OnMsgGetInstanceObject(PP_Instance instance,
diff --git a/ppapi/proxy/ppp_instance_proxy.h b/ppapi/proxy/ppp_instance_proxy.h index 7eda2bd..c8a4b464 100644 --- a/ppapi/proxy/ppp_instance_proxy.h +++ b/ppapi/proxy/ppp_instance_proxy.h
@@ -26,7 +26,7 @@ class PPP_Instance_Proxy : public InterfaceProxy { public: explicit PPP_Instance_Proxy(Dispatcher* dispatcher); - virtual ~PPP_Instance_Proxy(); + ~PPP_Instance_Proxy() override; static const PPP_Instance* GetInstanceInterface(); @@ -35,7 +35,7 @@ } // InterfaceProxy implementation. - virtual bool OnMessageReceived(const IPC::Message& msg); + bool OnMessageReceived(const IPC::Message& msg) override; private: // Message handlers.
diff --git a/ppapi/proxy/ppp_pdf_proxy.h b/ppapi/proxy/ppp_pdf_proxy.h index 94ddd1d..ff373fdf7 100644 --- a/ppapi/proxy/ppp_pdf_proxy.h +++ b/ppapi/proxy/ppp_pdf_proxy.h
@@ -15,13 +15,13 @@ class PPP_Pdf_Proxy : public InterfaceProxy { public: - PPP_Pdf_Proxy(Dispatcher* dispatcher); - virtual ~PPP_Pdf_Proxy(); + explicit PPP_Pdf_Proxy(Dispatcher* dispatcher); + ~PPP_Pdf_Proxy() override; static const PPP_Pdf* GetProxyInterface(); // InterfaceProxy implementation. - virtual bool OnMessageReceived(const IPC::Message& msg); + bool OnMessageReceived(const IPC::Message& msg) override; private: // Message handlers.
diff --git a/ppapi/proxy/ppp_printing_proxy.h b/ppapi/proxy/ppp_printing_proxy.h index 7c4025d..6f212bbb 100644 --- a/ppapi/proxy/ppp_printing_proxy.h +++ b/ppapi/proxy/ppp_printing_proxy.h
@@ -24,13 +24,13 @@ class PPP_Printing_Proxy : public InterfaceProxy { public: - PPP_Printing_Proxy(Dispatcher* dispatcher); - virtual ~PPP_Printing_Proxy(); + explicit PPP_Printing_Proxy(Dispatcher* dispatcher); + ~PPP_Printing_Proxy() override; static const PPP_Printing_Dev* GetProxyInterface(); // InterfaceProxy implementation. - virtual bool OnMessageReceived(const IPC::Message& msg); + bool OnMessageReceived(const IPC::Message& msg) override; private: // Message handlers.
diff --git a/ppapi/proxy/ppp_video_decoder_proxy.h b/ppapi/proxy/ppp_video_decoder_proxy.h index c4b23ef..2429ce6 100644 --- a/ppapi/proxy/ppp_video_decoder_proxy.h +++ b/ppapi/proxy/ppp_video_decoder_proxy.h
@@ -21,13 +21,13 @@ class PPP_VideoDecoder_Proxy : public InterfaceProxy { public: - PPP_VideoDecoder_Proxy(Dispatcher* dispatcher); - virtual ~PPP_VideoDecoder_Proxy(); + explicit PPP_VideoDecoder_Proxy(Dispatcher* dispatcher); + ~PPP_VideoDecoder_Proxy() override; static const PPP_VideoDecoder_Dev* GetProxyInterface(); // InterfaceProxy implementation. - virtual bool OnMessageReceived(const IPC::Message& msg); + bool OnMessageReceived(const IPC::Message& msg) override; private: // Message handlers.
diff --git a/remoting/host/input_injector_win.cc b/remoting/host/input_injector_win.cc index b7d31bb..93dc558 100644 --- a/remoting/host/input_injector_win.cc +++ b/remoting/host/input_injector_win.cc
@@ -415,15 +415,8 @@ input[1].ki.wVk = VK_CAPITAL; SendInput(arraysize(input), input, sizeof(INPUT)); } - - bool client_numlock_state = - (states & protocol::KeyEvent::LOCK_STATES_NUMLOCK) != 0; - bool host_numlock_state = (GetKeyState(VK_NUMLOCK) & 1) != 0; - if (client_numlock_state != host_numlock_state) { - input[0].ki.wVk = VK_NUMLOCK; - input[1].ki.wVk = VK_NUMLOCK; - SendInput(arraysize(input), input, sizeof(INPUT)); - } + // TODO(jamiewalch): Reinstate NumLock synchronization when the protocol + // supports the client reporting it as "unknown". } } // namespace
diff --git a/remoting/host/input_injector_x11.cc b/remoting/host/input_injector_x11.cc index 71b501b5..509b4531 100644 --- a/remoting/host/input_injector_x11.cc +++ b/remoting/host/input_injector_x11.cc
@@ -371,17 +371,14 @@ } void InputInjectorX11::Core::SetLockStates(uint32_t states) { + // TODO(jamiewalch): Reinstate NumLock synchronization when the protocol + // supports the client reporting it as "unknown". unsigned int caps_lock_mask = XkbKeysymToModifiers(display_, XK_Caps_Lock); - unsigned int num_lock_mask = XkbKeysymToModifiers(display_, XK_Num_Lock); unsigned int lock_values = 0; if (states & protocol::KeyEvent::LOCK_STATES_CAPSLOCK) { lock_values |= caps_lock_mask; } - if (states & protocol::KeyEvent::LOCK_STATES_NUMLOCK) { - lock_values |= num_lock_mask; - } - XkbLockModifiers(display_, XkbUseCoreKbd, caps_lock_mask | num_lock_mask, - lock_values); + XkbLockModifiers(display_, XkbUseCoreKbd, caps_lock_mask, lock_values); } void InputInjectorX11::Core::InjectScrollWheelClicks(int button, int count) {
diff --git a/remoting/host/linux/linux_me2me_host.py b/remoting/host/linux/linux_me2me_host.py index f026d68f..8302e290 100755 --- a/remoting/host/linux/linux_me2me_host.py +++ b/remoting/host/linux/linux_me2me_host.py
@@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. @@ -11,6 +11,12 @@ from __future__ import print_function +import sys +if sys.version_info[0] != 2 or sys.version_info[1] < 7: + print("This script requires Python version 2.7") + sys.exit(1) + +import argparse import atexit import errno import fcntl @@ -19,7 +25,6 @@ import hashlib import json import logging -import optparse import os import pipes import platform @@ -30,7 +35,6 @@ import signal import socket import subprocess -import sys import tempfile import threading import time @@ -791,9 +795,40 @@ self.host_proc.stdin.close() -def get_daemon_proc(): - """Checks if there is already an instance of this script running, and returns - a psutil.Process instance for it. +def parse_config_arg(args): + """Parses only the --config option from a given command-line. + + Returns: + A two-tuple. The first element is the value of the --config option (or None + if it is not specified), and the second is a list containing the remaining + arguments + """ + + # By default, argparse will exit the program on error. We would like it not to + # do that. + class ArgumentParserError(Exception): + pass + class ThrowingArgumentParser(argparse.ArgumentParser): + def error(self, message): + raise ArgumentParserError(message) + + parser = ThrowingArgumentParser() + parser.add_argument("--config", nargs='?', action="store") + + try: + result = parser.parse_known_args(args) + return (result[0].config, result[1]) + except ArgumentParserError: + return (None, list(args)) + + +def get_daemon_proc(config_file): + """Checks if there is already an instance of this script running against + |config_file|, and returns a psutil.Process instance for it. + + If a process is found without --config in the command line, get_daemon_proc + will fall back to the old behavior of checking whether the script path matches + the current script. This is to facilitate upgrades from previous versions. Returns: A Process instance for the existing daemon process, or None if the daemon @@ -826,8 +861,18 @@ cmdline = psget(process.cmdline) if len(cmdline) < 2: continue - if cmdline[0] == sys.executable and cmdline[1] == sys.argv[0]: - return process + if (os.path.basename(cmdline[0]).startswith('python') + and os.path.basename(cmdline[1]) == os.path.basename(sys.argv[0])): + process_config = parse_config_arg(cmdline[2:])[0] + if process_config is None: + # Fall back to old behavior if there is no --config argument + # TODO(rkjnsn): Consider removing this fallback once sufficient time + # has passed. + if cmdline[1] == sys.argv[0]: + return process + elif process_config == config_file: + return process + except (psutil.NoSuchProcess, psutil.AccessDenied): continue @@ -1323,57 +1368,63 @@ EPILOG = """This script is not intended for use by end-users. To configure Chrome Remote Desktop, please install the app from the Chrome Web Store: https://chrome.google.com/remotedesktop""" - parser = optparse.OptionParser( - usage="Usage: %prog [options] [ -- [ X server options ] ]", + parser = argparse.ArgumentParser( + usage="Usage: %(prog)s [options] [ -- [ X server options ] ]", epilog=EPILOG) - parser.add_option("-s", "--size", dest="size", action="append", - help="Dimensions of virtual desktop. This can be specified " - "multiple times to make multiple screen resolutions " - "available (if the X server supports this).") - parser.add_option("-f", "--foreground", dest="foreground", default=False, - action="store_true", - help="Don't run as a background daemon.") - parser.add_option("", "--start", dest="start", default=False, - action="store_true", - help="Start the host.") - parser.add_option("-k", "--stop", dest="stop", default=False, - action="store_true", - help="Stop the daemon currently running.") - parser.add_option("", "--get-status", dest="get_status", default=False, - action="store_true", - help="Prints host status") - parser.add_option("", "--check-running", dest="check_running", default=False, - action="store_true", - help="Return 0 if the daemon is running, or 1 otherwise.") - parser.add_option("", "--config", dest="config", action="store", - help="Use the specified configuration file.") - parser.add_option("", "--reload", dest="reload", default=False, - action="store_true", - help="Signal currently running host to reload the config.") - parser.add_option("", "--add-user", dest="add_user", default=False, - action="store_true", - help="Add current user to the chrome-remote-desktop group.") - parser.add_option("", "--add-user-as-root", dest="add_user_as_root", - action="store", metavar="USER", - help="Adds the specified user to the chrome-remote-desktop " - "group (must be run as root).") + parser.add_argument("-s", "--size", dest="size", action="append", + help="Dimensions of virtual desktop. This can be " + "specified multiple times to make multiple screen " + "resolutions available (if the X server supports this).") + parser.add_argument("-f", "--foreground", dest="foreground", default=False, + action="store_true", + help="Don't run as a background daemon.") + parser.add_argument("--start", dest="start", default=False, + action="store_true", + help="Start the host.") + parser.add_argument("-k", "--stop", dest="stop", default=False, + action="store_true", + help="Stop the daemon currently running.") + parser.add_argument("--get-status", dest="get_status", default=False, + action="store_true", + help="Prints host status") + parser.add_argument("--check-running", dest="check_running", + default=False, action="store_true", + help="Return 0 if the daemon is running, or 1 otherwise.") + parser.add_argument("--config", dest="config", action="store", + help="Use the specified configuration file.") + parser.add_argument("--reload", dest="reload", default=False, + action="store_true", + help="Signal currently running host to reload the " + "config.") + parser.add_argument("--add-user", dest="add_user", default=False, + action="store_true", + help="Add current user to the chrome-remote-desktop " + "group.") + parser.add_argument("--add-user-as-root", dest="add_user_as_root", + action="store", metavar="USER", + help="Adds the specified user to the " + "chrome-remote-desktop group (must be run as root).") # The script is being run as a child process under the user-session binary. # Don't daemonize and use the inherited environment. - parser.add_option("", "--child-process", dest="child_process", default=False, - action="store_true", - help=optparse.SUPPRESS_HELP) - parser.add_option("", "--watch-resolution", dest="watch_resolution", - type="int", nargs=2, default=False, action="store", - help=optparse.SUPPRESS_HELP) - (options, args) = parser.parse_args() + parser.add_argument("--child-process", dest="child_process", default=False, + action="store_true", + help=argparse.SUPPRESS) + parser.add_argument("--watch-resolution", dest="watch_resolution", + type=int, nargs=2, default=False, action="store", + help=argparse.SUPPRESS) + parser.add_argument(dest="args", nargs="*", help=argparse.SUPPRESS) + options = parser.parse_args() - # Determine the filename of the host configuration and PID files. - if not options.config: - options.config = os.path.join(CONFIG_DIR, "host#%s.json" % g_host_hash) + # Determine the filename of the host configuration. + if options.config: + config_file = options.config + else: + config_file = os.path.join(CONFIG_DIR, "host#%s.json" % g_host_hash) + config_file = os.path.realpath(config_file) # Check for a modal command-line option (start, stop, etc.) if options.get_status: - proc = get_daemon_proc() + proc = get_daemon_proc(config_file) if proc is not None: print("STARTED") elif is_supported_platform(): @@ -1385,11 +1436,11 @@ # TODO(sergeyu): Remove --check-running once NPAPI plugin and NM host are # updated to always use get-status flag instead. if options.check_running: - proc = get_daemon_proc() + proc = get_daemon_proc(config_file) return 1 if proc is None else 0 if options.stop: - proc = get_daemon_proc() + proc = get_daemon_proc(config_file) if proc is None: print("The daemon is not currently running") else: @@ -1403,7 +1454,7 @@ return 0 if options.reload: - proc = get_daemon_proc() + proc = get_daemon_proc(config_file) if proc is None: return 1 proc.send_signal(signal.SIGHUP) @@ -1466,6 +1517,21 @@ print(EPILOG, file=sys.stderr) return 1 + # Determine whether a desktop is already active for the specified host + # configuration. + proc = get_daemon_proc(config_file) + if proc is not None: + # Debian policy requires that services should "start" cleanly and return 0 + # if they are already running. + print("Service already running.") + return 0 + + if config_file != options.config: + # Canonicalize config flag so get_daemon_proc can find us. + exec_args = [sys.argv[0], "--config=" + config_file] + exec_args += parse_config_arg(sys.argv[1:])[1] + os.execvp(SCRIPT_PATH, exec_args) + # If a RANDR-supporting Xvfb is not available, limit the default size to # something more sensible. if USE_XORG_ENV_VAR not in os.environ and locate_xvfb_randr(): @@ -1502,7 +1568,7 @@ atexit.register(cleanup) # Load the initial host configuration. - host_config = Config(options.config) + host_config = Config(config_file) try: host_config.load() except (IOError, ValueError) as e: @@ -1522,15 +1588,6 @@ logging.error("Failed to load host configuration.") return 1 - # Determine whether a desktop is already active for the specified host - # host configuration. - proc = get_daemon_proc() - if proc is not None: - # Debian policy requires that services should "start" cleanly and return 0 - # if they are already running. - print("Service already running.") - return 0 - # If we're running under user-session, try to open the messaging pipe. if options.child_process: # Log to existing messaging pipe if it exists. @@ -1605,7 +1662,7 @@ relaunch_times.append(x_server_inhibitor.earliest_relaunch_time) else: logging.info("Launching X server and X session.") - desktop.launch_session(options.child_process, args) + desktop.launch_session(options.child_process, options.args) x_server_inhibitor.record_started(MINIMUM_PROCESS_LIFETIME, backoff_time) allow_relaunch_self = True
diff --git a/remoting/host/setup/daemon_controller_delegate_linux.cc b/remoting/host/setup/daemon_controller_delegate_linux.cc index d2a9816..addc529 100644 --- a/remoting/host/setup/daemon_controller_delegate_linux.cc +++ b/remoting/host/setup/daemon_controller_delegate_linux.cc
@@ -220,8 +220,8 @@ return; } - std::vector<std::string> args; - args.push_back("--reload"); + std::vector<std::string> args = {"--reload", + "--config=" + GetConfigPath().value()}; DaemonController::AsyncResult result = DaemonController::RESULT_FAILED; if (RunHostScript(args)) result = DaemonController::RESULT_OK; @@ -231,8 +231,8 @@ void DaemonControllerDelegateLinux::Stop( const DaemonController::CompletionCallback& done) { - std::vector<std::string> args; - args.push_back("--stop"); + std::vector<std::string> args = {"--stop", + "--config=" + GetConfigPath().value()}; DaemonController::AsyncResult result = DaemonController::RESULT_FAILED; if (RunHostScript(args)) result = DaemonController::RESULT_OK;
diff --git a/services/device/generic_sensor/platform_sensor.cc b/services/device/generic_sensor/platform_sensor.cc index 32e3708..42018d5 100644 --- a/services/device/generic_sensor/platform_sensor.cc +++ b/services/device/generic_sensor/platform_sensor.cc
@@ -26,7 +26,7 @@ PlatformSensor::~PlatformSensor() { if (provider_) - provider_->RemoveSensor(GetType()); + provider_->RemoveSensor(GetType(), this); } mojom::SensorType PlatformSensor::GetType() const {
diff --git a/services/device/generic_sensor/platform_sensor_provider_base.cc b/services/device/generic_sensor/platform_sensor_provider_base.cc index 51f63c3..f73b75146 100644 --- a/services/device/generic_sensor/platform_sensor_provider_base.cc +++ b/services/device/generic_sensor/platform_sensor_provider_base.cc
@@ -74,9 +74,24 @@ return shared_buffer_handle_.is_valid(); } -void PlatformSensorProviderBase::RemoveSensor(mojom::SensorType type) { +void PlatformSensorProviderBase::RemoveSensor(mojom::SensorType type, + PlatformSensor* sensor) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - DCHECK(ContainsKey(sensor_map_, type)); + auto it = sensor_map_.find(type); + if (it == sensor_map_.end()) { + // It is possible on PlatformSensorFusion creation failure since the + // PlatformSensorFusion object is not added to the |sensor_map_|, but + // its base class destructor PlatformSensor::~PlatformSensor() calls this + // RemoveSensor() function with the PlatformSensorFusion type. + return; + } + + if (sensor != it->second) { + NOTREACHED() + << "not expecting to track more than one sensor of the same type"; + return; + } + sensor_map_.erase(type); if (sensor_map_.empty()) {
diff --git a/services/device/generic_sensor/platform_sensor_provider_base.h b/services/device/generic_sensor/platform_sensor_provider_base.h index 77926f78..ac4e3c7f 100644 --- a/services/device/generic_sensor/platform_sensor_provider_base.h +++ b/services/device/generic_sensor/platform_sensor_provider_base.h
@@ -66,7 +66,7 @@ friend class PlatformSensor; // To call RemoveSensor(); bool CreateSharedBufferIfNeeded(); - void RemoveSensor(mojom::SensorType type); + void RemoveSensor(mojom::SensorType type, PlatformSensor* sensor); private: using CallbackQueue = std::vector<CreateSensorCallback>;
diff --git a/services/ui/ws/event_dispatcher.cc b/services/ui/ws/event_dispatcher.cc index 5e932f23..5fd4a6f 100644 --- a/services/ui/ws/event_dispatcher.cc +++ b/services/ui/ws/event_dispatcher.cc
@@ -86,20 +86,20 @@ mouse_button_down_ = false; } -void EventDispatcher::SetMousePointerDisplayLocation( - const gfx::Point& display_location, - int64_t display_id) { +std::unique_ptr<ui::Event> EventDispatcher::GenerateMouseMoveFor( + const gfx::Point& display_location) const { // Create a synthetic mouse event and dispatch it directly to ourselves so we // update internal caches and possibly send exit events in case the window // the cursor is over changes. - ui::PointerEvent move_event( + // TODO: This uses state here that may be out of sync at the time the event is + // actually processed. Fix. + std::unique_ptr<PointerEvent> event = base::MakeUnique<PointerEvent>( ui::ET_POINTER_MOVED, display_location, display_location, next_mouse_button_flags_, 0 /* changed_button_flags */, ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_MOUSE, ui::MouseEvent::kMousePointerId), base::TimeTicks::Now()); - ProcessEvent(move_event, display_id, - EventDispatcher::AcceleratorMatchPhase::ANY); + return event; } ui::CursorData EventDispatcher::GetCurrentMouseCursor() const { @@ -223,7 +223,7 @@ } void EventDispatcher::UpdateNonClientAreaForCurrentWindow() { - if (mouse_cursor_source_window_) { + if (!mouse_button_down_ && mouse_cursor_source_window_) { event_targeter_->FindTargetForLocation( EventSource::MOUSE, {mouse_pointer_last_location_, mouse_pointer_display_id_}, @@ -285,7 +285,7 @@ } bool EventDispatcher::IsProcessingEvent() const { - return event_targeter_->IsHitTestInFlight(); + return waiting_on_event_targeter_; } void EventDispatcher::ProcessEvent(const ui::Event& event, @@ -323,13 +323,22 @@ } DCHECK(event.IsPointerEvent()); + DCHECK(!waiting_on_event_targeter_); const EventSource event_source = event.IsMousePointerEvent() ? EventSource::MOUSE : EventSource::TOUCH; - event_targeter_->FindTargetForLocation( - event_source, - {event.AsPointerEvent()->root_location(), event_display_id_}, - base::BindOnce(&EventDispatcher::ProcessPointerEventOnFoundTarget, - base::Unretained(this), *event.AsPointerEvent())); + if (ShouldUseEventTargeter(*event.AsPointerEvent())) { + waiting_on_event_targeter_ = true; + event_targeter_->FindTargetForLocation( + event_source, + {event.AsPointerEvent()->root_location(), event_display_id_}, + base::BindOnce(&EventDispatcher::ProcessPointerEventOnFoundTarget, + base::Unretained(this), *event.AsPointerEvent())); + } else { + ProcessPointerEventOnFoundTargetImpl( + *event.AsPointerEvent(), + GetDisplayLocationFromEvent(*event.AsPointerEvent(), display_id), + nullptr); + } } ServerWindow* EventDispatcher::GetRootWindowContaining( @@ -352,6 +361,15 @@ return delegate_->GetWindowFromFrameSinkId(frame_sink_id); } +DisplayLocation EventDispatcher::GetDisplayLocationFromEvent( + const ui::PointerEvent& event, + int64_t display_id) const { + DisplayLocation display_location{event.root_location(), display_id}; + delegate_->GetRootWindowContaining(&display_location.location, + &display_location.display_id); + return display_location; +} + DeepestWindow EventDispatcher::AdjustTargetForModal( const DeepestWindow& target) const { const ServerWindow* modal_transient = @@ -438,10 +456,37 @@ delegate_->OnEventChangesCursorVisibility(event, false); } +bool EventDispatcher::ShouldUseEventTargeter(const PointerEvent& event) const { + const int32_t pointer_id = event.pointer_details().id; + if (drag_controller_) + return true; + + if (capture_window_) + return false; + + auto iter = pointer_targets_.find(pointer_id); + if (iter == pointer_targets_.end() || !iter->second.is_pointer_down) + return true; + + return (event.IsMousePointerEvent() && IsPointerGoingUp(event)) || + event.type() == ET_POINTER_DOWN; +} + void EventDispatcher::ProcessPointerEventOnFoundTarget( const ui::PointerEvent& event, const DisplayLocation& display_location, - const DeepestWindow& found_target) { + const DeepestWindow& target) { + DCHECK(waiting_on_event_targeter_); + waiting_on_event_targeter_ = false; + ProcessPointerEventOnFoundTargetImpl(event, display_location, &target); +} + +void EventDispatcher::ProcessPointerEventOnFoundTargetImpl( + const ui::PointerEvent& event, + const DisplayLocation& display_location, + const DeepestWindow* found_target) { + DCHECK(!waiting_on_event_targeter_); + // WARNING: |found_target| may be null! std::unique_ptr<ui::Event> cloned_event = ui::Event::Clone(event); if (display_location.display_id != event_display_id_) { event_display_id_ = display_location.display_id; @@ -468,10 +513,13 @@ } } - if (drag_controller_ && drag_controller_->DispatchPointerEvent( - *cloned_event->AsPointerEvent(), - AdjustTargetForModal(found_target).window)) { - return; + if (drag_controller_) { + DCHECK(found_target); + if (drag_controller_->DispatchPointerEvent( + *cloned_event->AsPointerEvent(), + AdjustTargetForModal(*found_target).window)) { + return; + } } if (capture_window_) { @@ -481,20 +529,26 @@ return; } - DeepestWindow updated_target = AdjustTargetForModal(found_target); - PointerTarget pointer_target; - pointer_target.is_mouse_event = is_mouse_event; - pointer_target.window = updated_target.window; - pointer_target.in_nonclient_area = updated_target.in_non_client_area; - pointer_target.is_pointer_down = event.type() == ui::ET_POINTER_DOWN; + std::unique_ptr<DeepestWindowAndTarget> result; + if (found_target) { + result = base::MakeUnique<DeepestWindowAndTarget>(); + result->deepest_window = AdjustTargetForModal(*found_target); + result->pointer_target.is_mouse_event = is_mouse_event; + result->pointer_target.window = result->deepest_window.window; + result->pointer_target.in_nonclient_area = + result->deepest_window.in_non_client_area; + result->pointer_target.is_pointer_down = + event.type() == ui::ET_POINTER_DOWN; + } const int32_t pointer_id = event.pointer_details().id; if (!IsTrackingPointer(pointer_id) || !pointer_targets_[pointer_id].is_pointer_down) { + DCHECK(result); const bool any_pointers_down = AreAnyPointersDown(); UpdateTargetForPointer(pointer_id, *cloned_event->AsPointerEvent(), - pointer_target); + result->pointer_target); if (is_mouse_event) SetMouseCursorSourceWindow(pointer_targets_[pointer_id].window); @@ -523,8 +577,10 @@ // up event to the window that had implicit capture. We have to set this // before we perform dispatch because the Delegate is going to read this // information from us. - if (is_pointer_going_up && is_mouse_event) - UpdateCursorProvider(updated_target); + if (is_pointer_going_up && is_mouse_event) { + DCHECK(result); + UpdateCursorProvider(result->deepest_window); + } DispatchToPointerTarget(pointer_targets_[pointer_id], *cloned_event->AsPointerEvent()); @@ -538,10 +594,13 @@ delegate_->ReleaseNativeCapture(); } - // Use |found_target| as |updated_target| has already been adjusted for the - // modal window. - if (event.type() == ET_POINTER_DOWN && found_target.window) - HandleClickOnBlockedWindow(found_target); + if (event.type() == ET_POINTER_DOWN) { + // Use |found_target| as |result| has already been adjusted for the + // modal window. + DCHECK(found_target); + if (found_target->window) + HandleClickOnBlockedWindow(*found_target); + } } void EventDispatcher::UpdateCursorRelatedProperties(
diff --git a/services/ui/ws/event_dispatcher.h b/services/ui/ws/event_dispatcher.h index 50851f7..0e48fc7 100644 --- a/services/ui/ws/event_dispatcher.h +++ b/services/ui/ws/event_dispatcher.h
@@ -73,8 +73,11 @@ // any events to the delegate. void Reset(); - void SetMousePointerDisplayLocation(const gfx::Point& display_location, - int64_t display_id); + // Generates a mouse move event corresponding to the mouse moving to a + // particular location. + std::unique_ptr<ui::Event> GenerateMouseMoveFor( + const gfx::Point& display_location) const; + const gfx::Point& mouse_pointer_last_location() const { return mouse_pointer_last_location_; } @@ -198,6 +201,14 @@ bool is_pointer_down; }; + struct DeepestWindowAndTarget { + PointerTarget pointer_target; + DeepestWindow deepest_window; + }; + + DisplayLocation GetDisplayLocationFromEvent(const ui::PointerEvent& event, + int64_t display_id) const; + // EventTargeter returns the deepest window based on hit-test data. If the // target is blocked by a modal window this returns a different target, // otherwise the supplied target is returned. @@ -227,6 +238,15 @@ return pointer_targets_.count(pointer_id) > 0; } + // Returns true if EventTargeter needs to queried for the specified event. + bool ShouldUseEventTargeter(const PointerEvent& event) const; + + // Callback from EventTargeter once the target has been found. Calls + // ProcessPointerEventOnFoundTargetImpl(). + void ProcessPointerEventOnFoundTarget(const ui::PointerEvent& event, + const DisplayLocation& display_location, + const DeepestWindow& target); + // EventDispatcher provides the following logic for pointer events: // . wheel events go to the current target of the associated pointer. If // there is no target, they go to the deepest window. @@ -236,9 +256,15 @@ // when no buttons on the mouse are down. // This also generates exit events as appropriate. For example, if the mouse // moves between one window to another an exit is generated on the first. - void ProcessPointerEventOnFoundTarget(const ui::PointerEvent& event, - const DisplayLocation& display_location, - const DeepestWindow& found_target); + // + // NOTE: |found_target| is null if ShouldUseEventTargeter() returned false. + // If ShouldUseEventTargeter() returned false it means this function should + // not need |found_target| and has enough information to process the event + // without a DeepestWindow. + void ProcessPointerEventOnFoundTargetImpl( + const ui::PointerEvent& event, + const DisplayLocation& display_location, + const DeepestWindow* found_target); // Called when processing a pointer event to updated cursor related // properties. @@ -369,6 +395,9 @@ // Keeps track of number of observe requests for each observed window. std::map<const ServerWindow*, uint8_t> observed_windows_; + // Set to true when querying EventTargeter for the target. + bool waiting_on_event_targeter_ = false; + #if !defined(NDEBUG) std::unique_ptr<ui::Event> previous_event_; AcceleratorMatchPhase previous_accelerator_match_phase_ =
diff --git a/services/ui/ws/event_dispatcher_unittest.cc b/services/ui/ws/event_dispatcher_unittest.cc index a107fd6..ec8c6034 100644 --- a/services/ui/ws/event_dispatcher_unittest.cc +++ b/services/ui/ws/event_dispatcher_unittest.cc
@@ -306,6 +306,8 @@ const ServerWindow* GetActiveSystemModalWindow() const; protected: + bool is_event_processing_async() const { return GetParam(); } + // testing::TestWithParam<bool>: void SetUp() override; @@ -340,8 +342,10 @@ EventDispatcher* dispatcher, const gfx::Point& display_location, int64_t display_id) { - dispatcher->SetMousePointerDisplayLocation(display_location, display_id); - RunTasks(); + std::unique_ptr<ui::Event> event = + dispatcher->GenerateMouseMoveFor(display_location); + DispatchEvent(dispatcher, *event, display_id, + EventDispatcher::AcceleratorMatchPhase::ANY); } void EventDispatcherTest::RunMouseEventTests( @@ -422,8 +426,7 @@ } void EventDispatcherTest::RunTasks() { - bool enable_async_event_targeting = GetParam(); - if (!enable_async_event_targeting) + if (!is_event_processing_async()) return; base::RunLoop runloop; @@ -431,8 +434,7 @@ } void EventDispatcherTest::SetUp() { - bool enable_async_event_targeting = GetParam(); - if (enable_async_event_targeting) { + if (is_event_processing_async()) { base::CommandLine::ForCurrentProcess()->AppendSwitch( switches::kUseAsyncEventTargeting); } @@ -474,8 +476,7 @@ EventDispatcher::AcceleratorMatchPhase match_phase) { dispatcher->ProcessEvent(event, display_id, match_phase); - bool enable_async_event_targeting = GetParam(); - if (!enable_async_event_targeting) + if (!is_event_processing_async()) return; base::RunLoop runloop; @@ -491,6 +492,8 @@ } protected: + bool is_event_processing_async() const { return GetParam(); } + // testing::TestWithParam<bool>: void SetUp() override; @@ -514,8 +517,7 @@ void EventDispatcherVizTargeterTest::SetUp() { base::CommandLine::ForCurrentProcess()->AppendSwitch( switches::kUseVizHitTest); - bool enable_async_event_targeting = GetParam(); - if (enable_async_event_targeting) { + if (is_event_processing_async()) { base::CommandLine::ForCurrentProcess()->AppendSwitch( switches::kUseAsyncEventTargeting); } @@ -2427,6 +2429,31 @@ EXPECT_EQ(root_window(), event_dispatcher()->mouse_cursor_source_window()); } +TEST_P(EventDispatcherTest, DontQueryWhileMouseIsDown) { + // This test is easier to write with async event processing. + if (!is_event_processing_async()) + return; + + std::unique_ptr<ServerWindow> child = CreateChildWindow(WindowId(1, 3)); + + root_window()->SetBounds(gfx::Rect(0, 0, 100, 100)); + child->SetBounds(gfx::Rect(10, 10, 20, 20)); + + const ui::PointerEvent press_event(ui::MouseEvent( + ui::ET_MOUSE_PRESSED, gfx::Point(20, 25), gfx::Point(20, 25), + base::TimeTicks(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON)); + DispatchEvent(event_dispatcher(), press_event, 0, + EventDispatcher::AcceleratorMatchPhase::ANY); + ASSERT_FALSE(event_dispatcher()->IsProcessingEvent()); + + const ui::PointerEvent move_event(ui::MouseEvent( + ui::ET_MOUSE_MOVED, gfx::Point(20, 25), gfx::Point(20, 25), + base::TimeTicks(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON)); + event_dispatcher()->ProcessEvent(move_event, 0, + EventDispatcher::AcceleratorMatchPhase::ANY); + EXPECT_FALSE(event_dispatcher()->IsProcessingEvent()); +} + TEST_P(EventDispatcherVizTargeterTest, ProcessEvent) { std::unique_ptr<ServerWindow> child = CreateChildWindow(WindowId(1, 3));
diff --git a/services/ui/ws/event_targeter.cc b/services/ui/ws/event_targeter.cc index e94346a..467bf33 100644 --- a/services/ui/ws/event_targeter.cc +++ b/services/ui/ws/event_targeter.cc
@@ -15,19 +15,8 @@ namespace ui { namespace ws { -EventTargeter::HitTestRequest::HitTestRequest( - EventSource event_source, - const DisplayLocation& display_location, - HitTestCallback callback) - : event_source(event_source), - display_location(display_location), - callback(std::move(callback)) {} - -EventTargeter::HitTestRequest::~HitTestRequest() {} - EventTargeter::EventTargeter(EventTargeterDelegate* event_targeter_delegate) : event_targeter_delegate_(event_targeter_delegate), - hit_test_in_flight_(false), weak_ptr_factory_(this) {} EventTargeter::~EventTargeter() {} @@ -36,30 +25,10 @@ EventSource event_source, const DisplayLocation& display_location, HitTestCallback callback) { - if (IsHitTestInFlight()) { - std::unique_ptr<HitTestRequest> hittest_request = - base::MakeUnique<HitTestRequest>(event_source, display_location, - std::move(callback)); - hit_test_request_queue_.push(std::move(hittest_request)); - return; - } - - ProcessFindTarget(event_source, display_location, std::move(callback)); -} - -bool EventTargeter::IsHitTestInFlight() const { - return hit_test_in_flight_ || !hit_test_request_queue_.empty(); -} - -void EventTargeter::ProcessFindTarget(EventSource event_source, - const DisplayLocation& display_location, - HitTestCallback callback) { // TODO(riajiang): After the async ask-client part is implemented, the async // part should be moved to after sync viz-hit-test call. if (base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kUseAsyncEventTargeting)) { - DCHECK(!hit_test_in_flight_); - hit_test_in_flight_ = true; base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(&EventTargeter::FindTargetForLocationNow, weak_ptr_factory_.GetWeakPtr(), event_source, @@ -106,22 +75,6 @@ } } std::move(callback).Run(updated_display_location, deepest_window); - ProcessNextHitTestRequestFromQueue(); -} - -void EventTargeter::ProcessNextHitTestRequestFromQueue() { - hit_test_in_flight_ = false; - if (hit_test_request_queue_.empty()) { - event_targeter_delegate_->ProcessNextAvailableEvent(); - return; - } - - std::unique_ptr<HitTestRequest> hittest_request = - std::move(hit_test_request_queue_.front()); - hit_test_request_queue_.pop(); - ProcessFindTarget(hittest_request->event_source, - hittest_request->display_location, - std::move(hittest_request->callback)); } } // namespace ws
diff --git a/services/ui/ws/event_targeter.h b/services/ui/ws/event_targeter.h index 93e8199..0a8ae3c 100644 --- a/services/ui/ws/event_targeter.h +++ b/services/ui/ws/event_targeter.h
@@ -6,19 +6,22 @@ #define SERVICES_UI_WS_EVENT_TARGETER_H_ #include <stdint.h> -#include <queue> -#include "base/callback.h" +#include "base/callback_forward.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "services/ui/ws/window_finder.h" -#include "ui/display/types/display_constants.h" #include "ui/gfx/geometry/point.h" namespace ui { namespace ws { + class EventTargeterDelegate; +namespace test { +class EventTargeterTestApi; +} + // Contains a location relative to a particular display. struct DisplayLocation { gfx::Point location; @@ -40,39 +43,15 @@ const DisplayLocation& display_location, HitTestCallback callback); - bool IsHitTestInFlight() const; - private: - struct HitTestRequest { - HitTestRequest(EventSource event_source, - const DisplayLocation& display_location, - HitTestCallback hittest_callback); - ~HitTestRequest(); - - EventSource event_source; - DisplayLocation display_location; - HitTestCallback callback; - }; - - void ProcessFindTarget(EventSource event_source, - const DisplayLocation& display_location, - HitTestCallback callback); + friend class test::EventTargeterTestApi; void FindTargetForLocationNow(EventSource event_source, const DisplayLocation& display_location, HitTestCallback callback); - void ProcessNextHitTestRequestFromQueue(); - EventTargeterDelegate* event_targeter_delegate_; - // True if we are waiting for the result of a hit-test. False otherwise. - bool hit_test_in_flight_; - - // Requests for a new location while waiting on an existing request are added - // here. - std::queue<std::unique_ptr<HitTestRequest>> hit_test_request_queue_; - base::WeakPtrFactory<EventTargeter> weak_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(EventTargeter);
diff --git a/services/ui/ws/test_utils.h b/services/ui/ws/test_utils.h index 04dbe58..32035bb 100644 --- a/services/ui/ws/test_utils.h +++ b/services/ui/ws/test_utils.h
@@ -23,6 +23,7 @@ #include "services/ui/ws/display_binding.h" #include "services/ui/ws/drag_controller.h" #include "services/ui/ws/event_dispatcher.h" +#include "services/ui/ws/event_targeter.h" #include "services/ui/ws/gpu_host.h" #include "services/ui/ws/platform_display.h" #include "services/ui/ws/platform_display_factory.h" @@ -181,6 +182,7 @@ return &ed_->modal_window_controller_; } ServerWindow* capture_window() { return ed_->capture_window_; } + EventTargeter* event_targeter() { return ed_->event_targeter_.get(); } private: EventDispatcher* ed_; @@ -190,6 +192,24 @@ // ----------------------------------------------------------------------------- +class EventTargeterTestApi { + public: + explicit EventTargeterTestApi(EventTargeter* event_targeter) + : event_targeter_(event_targeter) {} + ~EventTargeterTestApi() {} + + bool HasPendingQueries() const { + return event_targeter_->weak_ptr_factory_.HasWeakPtrs(); + } + + private: + EventTargeter* event_targeter_; + + DISALLOW_COPY_AND_ASSIGN(EventTargeterTestApi); +}; + +// ----------------------------------------------------------------------------- + class ModalWindowControllerTestApi { public: explicit ModalWindowControllerTestApi(ModalWindowController* mwc)
diff --git a/services/ui/ws/window_manager_state.cc b/services/ui/ws/window_manager_state.cc index 393c9744..9afceb1 100644 --- a/services/ui/ws/window_manager_state.cc +++ b/services/ui/ws/window_manager_state.cc
@@ -199,10 +199,11 @@ return; } - event_dispatcher()->SetMousePointerDisplayLocation(display_pixels, - display_id); - UpdateNativeCursorFromDispatcher(); display->platform_display()->MoveCursorTo(display_pixels); + + std::unique_ptr<ui::Event> event = + event_dispatcher_.GenerateMouseMoveFor(display_pixels); + ProcessEvent(*event, display_id); } void WindowManagerState::SetKeyEventsThatDontHideCursor( @@ -309,8 +310,9 @@ int64_t display_id) { SetAllRootWindowsVisible(true); event_dispatcher_.Reset(); - event_dispatcher_.SetMousePointerDisplayLocation(mouse_location_on_display, - display_id); + std::unique_ptr<ui::Event> event = + event_dispatcher_.GenerateMouseMoveFor(mouse_location_on_display); + ProcessEvent(*event, display_id); } void WindowManagerState::Deactivate() {
diff --git a/services/ui/ws/window_manager_state_unittest.cc b/services/ui/ws/window_manager_state_unittest.cc index dc2fbbe60..9ee583d 100644 --- a/services/ui/ws/window_manager_state_unittest.cc +++ b/services/ui/ws/window_manager_state_unittest.cc
@@ -729,8 +729,13 @@ window_tree()->GetWindowByClientId(child_window_id); window_tree()->AddWindow(FirstRootId(window_tree()), child_window_id); // Setup steps already do hit-test for mouse cursor update so this should go - // to the queue in EventDispatcher. - EXPECT_TRUE(window_manager_state()->event_dispatcher()->IsProcessingEvent()); + // to the queue in EventTargeter. + EventTargeterTestApi event_targeter_test_api( + EventDispatcherTestApi(window_manager_state()->event_dispatcher()) + .event_targeter()); + EXPECT_TRUE(event_targeter_test_api.HasPendingQueries()); + // But no events have been generated, so IsProcessingEvent() should be false. + EXPECT_FALSE(window_manager_state()->event_dispatcher()->IsProcessingEvent()); child_window->SetVisible(true); child_window->SetBounds(gfx::Rect(0, 0, 20, 20)); child_window->parent()->SetCursor(ui::CursorData(ui::CursorType::kCopy)); @@ -743,12 +748,9 @@ WindowManagerStateTestApi test_api(window_manager_state()); EXPECT_TRUE(test_api.is_event_queue_empty()); window_manager_state()->ProcessEvent(move, 0); - // There's no event dispatching in flight but there's hit-test in flight in - // EventDispatcher so we still put event processing request into the queue - // in WindowManagerState. EXPECT_FALSE(test_api.tree_awaiting_input_ack()); EXPECT_TRUE(window_manager_state()->event_dispatcher()->IsProcessingEvent()); - EXPECT_FALSE(test_api.is_event_queue_empty()); + EXPECT_TRUE(test_api.is_event_queue_empty()); task_runner_->RunUntilIdle(); EXPECT_TRUE(test_api.is_event_queue_empty()); // The event isn't over a valid target, which should trigger resetting the
diff --git a/skia/config/SkUserConfig.h b/skia/config/SkUserConfig.h index 65ae037..81c998d 100644 --- a/skia/config/SkUserConfig.h +++ b/skia/config/SkUserConfig.h
@@ -220,6 +220,10 @@ #define SK_SUPPORT_LEGACY_TILED_BITMAPS #endif +#ifndef SK_JUMPER_LEGACY_X86_8BIT +#define SK_JUMPER_LEGACY_X86_8BIT +#endif + ///////////////////////// Imported from BUILD.gn and skia_common.gypi /* In some places Skia can use static initializers for global initialization,
diff --git a/testing/buildbot/chromium.android.json b/testing/buildbot/chromium.android.json index 048c241..4a3d72e8 100644 --- a/testing/buildbot/chromium.android.json +++ b/testing/buildbot/chromium.android.json
@@ -877,7 +877,7 @@ "device_type": "bullhead" } ], - "hard_timeout": 960, + "hard_timeout": 1200, "output_links": [ { "link": [ @@ -6762,12 +6762,12 @@ ], "dimension_sets": [ { - "android_devices": "6", + "android_devices": "1", "device_os": "MMB29Q", "device_type": "bullhead" } ], - "hard_timeout": 1800, + "hard_timeout": 1200, "output_links": [ { "link": [ @@ -6777,7 +6777,8 @@ ], "name": "shard #${SHARD_INDEX} logcats" } - ] + ], + "shards": 14 }, "test": "chrome_public_test_apk" }, @@ -6851,12 +6852,12 @@ ], "dimension_sets": [ { - "android_devices": "6", + "android_devices": "1", "device_os": "MMB29Q", "device_type": "bullhead" } ], - "hard_timeout": 1800, + "hard_timeout": 1200, "output_links": [ { "link": [ @@ -6866,7 +6867,8 @@ ], "name": "shard #${SHARD_INDEX} logcats" } - ] + ], + "shards": 14 }, "test": "chrome_public_test_apk" },
diff --git a/testing/buildbot/chromium.perf.fyi.json b/testing/buildbot/chromium.perf.fyi.json index d6f6452..24573de 100644 --- a/testing/buildbot/chromium.perf.fyi.json +++ b/testing/buildbot/chromium.perf.fyi.json
@@ -2061,130 +2061,6 @@ } }, { - "args": [ - "page_cycler_v2.basic_oopif", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=release_x64" - ], - "isolate_name": "telemetry_perf_tests", - "name": "page_cycler_v2.basic_oopif", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "8086:22b1", - "id": "build155-b1", - "os": "Windows-10-10586", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 600, - "upload_test_results": false - } - }, - { - "args": [ - "page_cycler_v2.basic_oopif", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=reference", - "--max-failures=5", - "--output-trace-tag=_ref" - ], - "isolate_name": "telemetry_perf_tests", - "name": "page_cycler_v2.basic_oopif.reference", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "8086:22b1", - "id": "build155-b1", - "os": "Windows-10-10586", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": true, - "io_timeout": 600, - "upload_test_results": false - } - }, - { - "args": [ - "page_cycler_v2_site_isolation.basic_oopif", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=release_x64" - ], - "isolate_name": "telemetry_perf_tests", - "name": "page_cycler_v2_site_isolation.basic_oopif", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "8086:22b1", - "id": "build154-b1", - "os": "Windows-10-10586", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 600, - "upload_test_results": false - } - }, - { - "args": [ - "page_cycler_v2_site_isolation.basic_oopif", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=reference", - "--max-failures=5", - "--output-trace-tag=_ref" - ], - "isolate_name": "telemetry_perf_tests", - "name": "page_cycler_v2_site_isolation.basic_oopif.reference", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "8086:22b1", - "id": "build154-b1", - "os": "Windows-10-10586", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": true, - "io_timeout": 600, - "upload_test_results": false - } - }, - { "args": [], "isolate_name": "performance_browser_tests", "name": "performance_browser_tests", @@ -6540,130 +6416,6 @@ }, { "args": [ - "page_cycler_v2.basic_oopif", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=release_x64" - ], - "isolate_name": "telemetry_perf_tests", - "name": "page_cycler_v2.basic_oopif", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "1002:9874", - "id": "build219-b4", - "os": "Windows-10-10586", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 600, - "upload_test_results": false - } - }, - { - "args": [ - "page_cycler_v2.basic_oopif", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=reference", - "--max-failures=5", - "--output-trace-tag=_ref" - ], - "isolate_name": "telemetry_perf_tests", - "name": "page_cycler_v2.basic_oopif.reference", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "1002:9874", - "id": "build219-b4", - "os": "Windows-10-10586", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": true, - "io_timeout": 600, - "upload_test_results": false - } - }, - { - "args": [ - "page_cycler_v2_site_isolation.basic_oopif", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=release_x64" - ], - "isolate_name": "telemetry_perf_tests", - "name": "page_cycler_v2_site_isolation.basic_oopif", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "1002:9874", - "id": "build218-b4", - "os": "Windows-10-10586", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 600, - "upload_test_results": false - } - }, - { - "args": [ - "page_cycler_v2_site_isolation.basic_oopif", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=reference", - "--max-failures=5", - "--output-trace-tag=_ref" - ], - "isolate_name": "telemetry_perf_tests", - "name": "page_cycler_v2_site_isolation.basic_oopif.reference", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "1002:9874", - "id": "build218-b4", - "os": "Windows-10-10586", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": true, - "io_timeout": 600, - "upload_test_results": false - } - }, - { - "args": [ "power.idle_platform", "-v", "--upload-results",
diff --git a/testing/buildbot/chromium.perf.json b/testing/buildbot/chromium.perf.json index c3d0243..6936ff4 100644 --- a/testing/buildbot/chromium.perf.json +++ b/testing/buildbot/chromium.perf.json
@@ -32118,130 +32118,6 @@ }, { "args": [ - "page_cycler_v2.basic_oopif", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=release" - ], - "isolate_name": "telemetry_perf_tests", - "name": "page_cycler_v2.basic_oopif", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "102b:0534", - "id": "build150-m1", - "os": "Ubuntu-14.04", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 600, - "upload_test_results": false - } - }, - { - "args": [ - "page_cycler_v2.basic_oopif", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=reference", - "--max-failures=5", - "--output-trace-tag=_ref" - ], - "isolate_name": "telemetry_perf_tests", - "name": "page_cycler_v2.basic_oopif.reference", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "102b:0534", - "id": "build150-m1", - "os": "Ubuntu-14.04", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": true, - "io_timeout": 600, - "upload_test_results": false - } - }, - { - "args": [ - "page_cycler_v2_site_isolation.basic_oopif", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=release" - ], - "isolate_name": "telemetry_perf_tests", - "name": "page_cycler_v2_site_isolation.basic_oopif", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "102b:0534", - "id": "build152-m1", - "os": "Ubuntu-14.04", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 600, - "upload_test_results": false - } - }, - { - "args": [ - "page_cycler_v2_site_isolation.basic_oopif", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=reference", - "--max-failures=5", - "--output-trace-tag=_ref" - ], - "isolate_name": "telemetry_perf_tests", - "name": "page_cycler_v2_site_isolation.basic_oopif.reference", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "102b:0534", - "id": "build152-m1", - "os": "Ubuntu-14.04", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": true, - "io_timeout": 600, - "upload_test_results": false - } - }, - { - "args": [ "power.idle_platform", "-v", "--upload-results", @@ -36782,130 +36658,6 @@ }, { "args": [ - "page_cycler_v2.basic_oopif", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=release" - ], - "isolate_name": "telemetry_perf_tests", - "name": "page_cycler_v2.basic_oopif", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "8086:0166", - "id": "build103-b1", - "os": "Mac-10.11", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 600, - "upload_test_results": false - } - }, - { - "args": [ - "page_cycler_v2.basic_oopif", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=reference", - "--max-failures=5", - "--output-trace-tag=_ref" - ], - "isolate_name": "telemetry_perf_tests", - "name": "page_cycler_v2.basic_oopif.reference", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "8086:0166", - "id": "build103-b1", - "os": "Mac-10.11", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": true, - "io_timeout": 600, - "upload_test_results": false - } - }, - { - "args": [ - "page_cycler_v2_site_isolation.basic_oopif", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=release" - ], - "isolate_name": "telemetry_perf_tests", - "name": "page_cycler_v2_site_isolation.basic_oopif", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "8086:0166", - "id": "build106-b1", - "os": "Mac-10.11", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 600, - "upload_test_results": false - } - }, - { - "args": [ - "page_cycler_v2_site_isolation.basic_oopif", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=reference", - "--max-failures=5", - "--output-trace-tag=_ref" - ], - "isolate_name": "telemetry_perf_tests", - "name": "page_cycler_v2_site_isolation.basic_oopif.reference", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "8086:0166", - "id": "build106-b1", - "os": "Mac-10.11", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": true, - "io_timeout": 600, - "upload_test_results": false - } - }, - { - "args": [ "power.idle_platform", "-v", "--upload-results", @@ -41487,130 +41239,6 @@ }, { "args": [ - "page_cycler_v2.basic_oopif", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=release" - ], - "isolate_name": "telemetry_perf_tests", - "name": "page_cycler_v2.basic_oopif", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "8086:0a2e", - "id": "build159-m1", - "os": "Mac-10.12", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 600, - "upload_test_results": false - } - }, - { - "args": [ - "page_cycler_v2.basic_oopif", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=reference", - "--max-failures=5", - "--output-trace-tag=_ref" - ], - "isolate_name": "telemetry_perf_tests", - "name": "page_cycler_v2.basic_oopif.reference", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "8086:0a2e", - "id": "build159-m1", - "os": "Mac-10.12", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": true, - "io_timeout": 600, - "upload_test_results": false - } - }, - { - "args": [ - "page_cycler_v2_site_isolation.basic_oopif", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=release" - ], - "isolate_name": "telemetry_perf_tests", - "name": "page_cycler_v2_site_isolation.basic_oopif", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "8086:0a2e", - "id": "build162-m1", - "os": "Mac-10.12", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 600, - "upload_test_results": false - } - }, - { - "args": [ - "page_cycler_v2_site_isolation.basic_oopif", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=reference", - "--max-failures=5", - "--output-trace-tag=_ref" - ], - "isolate_name": "telemetry_perf_tests", - "name": "page_cycler_v2_site_isolation.basic_oopif.reference", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "8086:0a2e", - "id": "build162-m1", - "os": "Mac-10.12", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": true, - "io_timeout": 600, - "upload_test_results": false - } - }, - { - "args": [ "power.idle_platform", "-v", "--upload-results", @@ -46170,130 +45798,6 @@ } }, { - "args": [ - "page_cycler_v2.basic_oopif", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=release" - ], - "isolate_name": "telemetry_perf_tests", - "name": "page_cycler_v2.basic_oopif", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "8086:1626", - "id": "build124-b1", - "os": "Mac-10.11", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 600, - "upload_test_results": false - } - }, - { - "args": [ - "page_cycler_v2.basic_oopif", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=reference", - "--max-failures=5", - "--output-trace-tag=_ref" - ], - "isolate_name": "telemetry_perf_tests", - "name": "page_cycler_v2.basic_oopif.reference", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "8086:1626", - "id": "build124-b1", - "os": "Mac-10.11", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": true, - "io_timeout": 600, - "upload_test_results": false - } - }, - { - "args": [ - "page_cycler_v2_site_isolation.basic_oopif", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=release" - ], - "isolate_name": "telemetry_perf_tests", - "name": "page_cycler_v2_site_isolation.basic_oopif", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "8086:1626", - "id": "build127-b1", - "os": "Mac-10.11", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 600, - "upload_test_results": false - } - }, - { - "args": [ - "page_cycler_v2_site_isolation.basic_oopif", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=reference", - "--max-failures=5", - "--output-trace-tag=_ref" - ], - "isolate_name": "telemetry_perf_tests", - "name": "page_cycler_v2_site_isolation.basic_oopif.reference", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "8086:1626", - "id": "build127-b1", - "os": "Mac-10.11", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": true, - "io_timeout": 600, - "upload_test_results": false - } - }, - { "args": [], "isolate_name": "performance_browser_tests", "name": "performance_browser_tests", @@ -50876,130 +50380,6 @@ }, { "args": [ - "page_cycler_v2.basic_oopif", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=release" - ], - "isolate_name": "telemetry_perf_tests", - "name": "page_cycler_v2.basic_oopif", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "8086:0a26", - "id": "build25-b1", - "os": "Mac-10.12", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 600, - "upload_test_results": false - } - }, - { - "args": [ - "page_cycler_v2.basic_oopif", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=reference", - "--max-failures=5", - "--output-trace-tag=_ref" - ], - "isolate_name": "telemetry_perf_tests", - "name": "page_cycler_v2.basic_oopif.reference", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "8086:0a26", - "id": "build25-b1", - "os": "Mac-10.12", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": true, - "io_timeout": 600, - "upload_test_results": false - } - }, - { - "args": [ - "page_cycler_v2_site_isolation.basic_oopif", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=release" - ], - "isolate_name": "telemetry_perf_tests", - "name": "page_cycler_v2_site_isolation.basic_oopif", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "8086:0a26", - "id": "build28-b1", - "os": "Mac-10.12", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 600, - "upload_test_results": false - } - }, - { - "args": [ - "page_cycler_v2_site_isolation.basic_oopif", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=reference", - "--max-failures=5", - "--output-trace-tag=_ref" - ], - "isolate_name": "telemetry_perf_tests", - "name": "page_cycler_v2_site_isolation.basic_oopif.reference", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "8086:0a26", - "id": "build28-b1", - "os": "Mac-10.12", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": true, - "io_timeout": 600, - "upload_test_results": false - } - }, - { - "args": [ "power.idle_platform", "-v", "--upload-results", @@ -55559,130 +54939,6 @@ } }, { - "args": [ - "page_cycler_v2.basic_oopif", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=release" - ], - "isolate_name": "telemetry_perf_tests", - "name": "page_cycler_v2.basic_oopif", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "1002:6821", - "id": "build129-b1", - "os": "Mac-10.11", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 600, - "upload_test_results": false - } - }, - { - "args": [ - "page_cycler_v2.basic_oopif", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=reference", - "--max-failures=5", - "--output-trace-tag=_ref" - ], - "isolate_name": "telemetry_perf_tests", - "name": "page_cycler_v2.basic_oopif.reference", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "1002:6821", - "id": "build129-b1", - "os": "Mac-10.11", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": true, - "io_timeout": 600, - "upload_test_results": false - } - }, - { - "args": [ - "page_cycler_v2_site_isolation.basic_oopif", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=release" - ], - "isolate_name": "telemetry_perf_tests", - "name": "page_cycler_v2_site_isolation.basic_oopif", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "1002:6821", - "id": "build132-b1", - "os": "Mac-10.11", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 600, - "upload_test_results": false - } - }, - { - "args": [ - "page_cycler_v2_site_isolation.basic_oopif", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=reference", - "--max-failures=5", - "--output-trace-tag=_ref" - ], - "isolate_name": "telemetry_perf_tests", - "name": "page_cycler_v2_site_isolation.basic_oopif.reference", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "1002:6821", - "id": "build132-b1", - "os": "Mac-10.11", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": true, - "io_timeout": 600, - "upload_test_results": false - } - }, - { "args": [], "isolate_name": "performance_browser_tests", "name": "performance_browser_tests", @@ -60264,130 +59520,6 @@ } }, { - "args": [ - "page_cycler_v2.basic_oopif", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=release" - ], - "isolate_name": "telemetry_perf_tests", - "name": "page_cycler_v2.basic_oopif", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "8086:0d26", - "id": "build5-b1", - "os": "Mac-10.11", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 600, - "upload_test_results": false - } - }, - { - "args": [ - "page_cycler_v2.basic_oopif", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=reference", - "--max-failures=5", - "--output-trace-tag=_ref" - ], - "isolate_name": "telemetry_perf_tests", - "name": "page_cycler_v2.basic_oopif.reference", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "8086:0d26", - "id": "build5-b1", - "os": "Mac-10.11", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": true, - "io_timeout": 600, - "upload_test_results": false - } - }, - { - "args": [ - "page_cycler_v2_site_isolation.basic_oopif", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=release" - ], - "isolate_name": "telemetry_perf_tests", - "name": "page_cycler_v2_site_isolation.basic_oopif", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "8086:0d26", - "id": "build30-b4", - "os": "Mac-10.11", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 600, - "upload_test_results": false - } - }, - { - "args": [ - "page_cycler_v2_site_isolation.basic_oopif", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=reference", - "--max-failures=5", - "--output-trace-tag=_ref" - ], - "isolate_name": "telemetry_perf_tests", - "name": "page_cycler_v2_site_isolation.basic_oopif.reference", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "8086:0d26", - "id": "build30-b4", - "os": "Mac-10.11", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": true, - "io_timeout": 600, - "upload_test_results": false - } - }, - { "args": [], "isolate_name": "performance_browser_tests", "name": "performance_browser_tests", @@ -64846,130 +63978,6 @@ }, { "args": [ - "page_cycler_v2.basic_oopif", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=release_x64" - ], - "isolate_name": "telemetry_perf_tests", - "name": "page_cycler_v2.basic_oopif", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "8086:1616", - "id": "build118-b1", - "os": "Windows-10-10240", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 600, - "upload_test_results": false - } - }, - { - "args": [ - "page_cycler_v2.basic_oopif", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=reference", - "--max-failures=5", - "--output-trace-tag=_ref" - ], - "isolate_name": "telemetry_perf_tests", - "name": "page_cycler_v2.basic_oopif.reference", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "8086:1616", - "id": "build118-b1", - "os": "Windows-10-10240", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": true, - "io_timeout": 600, - "upload_test_results": false - } - }, - { - "args": [ - "page_cycler_v2_site_isolation.basic_oopif", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=release_x64" - ], - "isolate_name": "telemetry_perf_tests", - "name": "page_cycler_v2_site_isolation.basic_oopif", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "8086:1616", - "id": "build180-b4", - "os": "Windows-10-10240", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 600, - "upload_test_results": false - } - }, - { - "args": [ - "page_cycler_v2_site_isolation.basic_oopif", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=reference", - "--max-failures=5", - "--output-trace-tag=_ref" - ], - "isolate_name": "telemetry_perf_tests", - "name": "page_cycler_v2_site_isolation.basic_oopif.reference", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "8086:1616", - "id": "build180-b4", - "os": "Windows-10-10240", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": true, - "io_timeout": 600, - "upload_test_results": false - } - }, - { - "args": [ "power.idle_platform", "-v", "--upload-results", @@ -69303,130 +68311,6 @@ }, { "args": [ - "page_cycler_v2.basic_oopif", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=release_x64" - ], - "isolate_name": "telemetry_perf_tests", - "name": "page_cycler_v2.basic_oopif", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "102b:0534", - "id": "build133-m1", - "os": "Windows-10-10240", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 600, - "upload_test_results": false - } - }, - { - "args": [ - "page_cycler_v2.basic_oopif", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=reference", - "--max-failures=5", - "--output-trace-tag=_ref" - ], - "isolate_name": "telemetry_perf_tests", - "name": "page_cycler_v2.basic_oopif.reference", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "102b:0534", - "id": "build133-m1", - "os": "Windows-10-10240", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": true, - "io_timeout": 600, - "upload_test_results": false - } - }, - { - "args": [ - "page_cycler_v2_site_isolation.basic_oopif", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=release_x64" - ], - "isolate_name": "telemetry_perf_tests", - "name": "page_cycler_v2_site_isolation.basic_oopif", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "102b:0534", - "id": "build136-m1", - "os": "Windows-10-10240", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 600, - "upload_test_results": false - } - }, - { - "args": [ - "page_cycler_v2_site_isolation.basic_oopif", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=reference", - "--max-failures=5", - "--output-trace-tag=_ref" - ], - "isolate_name": "telemetry_perf_tests", - "name": "page_cycler_v2_site_isolation.basic_oopif.reference", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "102b:0534", - "id": "build136-m1", - "os": "Windows-10-10240", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": true, - "io_timeout": 600, - "upload_test_results": false - } - }, - { - "args": [ "power.idle_platform", "-v", "--upload-results", @@ -73801,130 +72685,6 @@ } }, { - "args": [ - "page_cycler_v2.basic_oopif", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=release_x64" - ], - "isolate_name": "telemetry_perf_tests", - "name": "page_cycler_v2.basic_oopif", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "1002:6613", - "id": "build102-m1", - "os": "Windows-2008ServerR2-SP1", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 600, - "upload_test_results": false - } - }, - { - "args": [ - "page_cycler_v2.basic_oopif", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=reference", - "--max-failures=5", - "--output-trace-tag=_ref" - ], - "isolate_name": "telemetry_perf_tests", - "name": "page_cycler_v2.basic_oopif.reference", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "1002:6613", - "id": "build102-m1", - "os": "Windows-2008ServerR2-SP1", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": true, - "io_timeout": 600, - "upload_test_results": false - } - }, - { - "args": [ - "page_cycler_v2_site_isolation.basic_oopif", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=release_x64" - ], - "isolate_name": "telemetry_perf_tests", - "name": "page_cycler_v2_site_isolation.basic_oopif", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "1002:6613", - "id": "build105-m1", - "os": "Windows-2008ServerR2-SP1", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 600, - "upload_test_results": false - } - }, - { - "args": [ - "page_cycler_v2_site_isolation.basic_oopif", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=reference", - "--max-failures=5", - "--output-trace-tag=_ref" - ], - "isolate_name": "telemetry_perf_tests", - "name": "page_cycler_v2_site_isolation.basic_oopif.reference", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "1002:6613", - "id": "build105-m1", - "os": "Windows-2008ServerR2-SP1", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": true, - "io_timeout": 600, - "upload_test_results": false - } - }, - { "args": [], "isolate_name": "performance_browser_tests", "name": "performance_browser_tests", @@ -78300,130 +77060,6 @@ } }, { - "args": [ - "page_cycler_v2.basic_oopif", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=release_x64" - ], - "isolate_name": "telemetry_perf_tests", - "name": "page_cycler_v2.basic_oopif", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "8086:041a", - "id": "build165-m1", - "os": "Windows-2008ServerR2-SP1", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 600, - "upload_test_results": false - } - }, - { - "args": [ - "page_cycler_v2.basic_oopif", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=reference", - "--max-failures=5", - "--output-trace-tag=_ref" - ], - "isolate_name": "telemetry_perf_tests", - "name": "page_cycler_v2.basic_oopif.reference", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "8086:041a", - "id": "build165-m1", - "os": "Windows-2008ServerR2-SP1", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": true, - "io_timeout": 600, - "upload_test_results": false - } - }, - { - "args": [ - "page_cycler_v2_site_isolation.basic_oopif", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=release_x64" - ], - "isolate_name": "telemetry_perf_tests", - "name": "page_cycler_v2_site_isolation.basic_oopif", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "8086:041a", - "id": "build168-m1", - "os": "Windows-2008ServerR2-SP1", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 600, - "upload_test_results": false - } - }, - { - "args": [ - "page_cycler_v2_site_isolation.basic_oopif", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=reference", - "--max-failures=5", - "--output-trace-tag=_ref" - ], - "isolate_name": "telemetry_perf_tests", - "name": "page_cycler_v2_site_isolation.basic_oopif.reference", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "8086:041a", - "id": "build168-m1", - "os": "Windows-2008ServerR2-SP1", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": true, - "io_timeout": 600, - "upload_test_results": false - } - }, - { "args": [], "isolate_name": "performance_browser_tests", "name": "performance_browser_tests", @@ -82821,130 +81457,6 @@ }, { "args": [ - "page_cycler_v2.basic_oopif", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=release_x64" - ], - "isolate_name": "telemetry_perf_tests", - "name": "page_cycler_v2.basic_oopif", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "10de:104a", - "id": "build93-m1", - "os": "Windows-2008ServerR2-SP1", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 600, - "upload_test_results": false - } - }, - { - "args": [ - "page_cycler_v2.basic_oopif", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=reference", - "--max-failures=5", - "--output-trace-tag=_ref" - ], - "isolate_name": "telemetry_perf_tests", - "name": "page_cycler_v2.basic_oopif.reference", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "10de:104a", - "id": "build93-m1", - "os": "Windows-2008ServerR2-SP1", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": true, - "io_timeout": 600, - "upload_test_results": false - } - }, - { - "args": [ - "page_cycler_v2_site_isolation.basic_oopif", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=release_x64" - ], - "isolate_name": "telemetry_perf_tests", - "name": "page_cycler_v2_site_isolation.basic_oopif", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "10de:104a", - "id": "build96-m1", - "os": "Windows-2008ServerR2-SP1", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 600, - "upload_test_results": false - } - }, - { - "args": [ - "page_cycler_v2_site_isolation.basic_oopif", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=reference", - "--max-failures=5", - "--output-trace-tag=_ref" - ], - "isolate_name": "telemetry_perf_tests", - "name": "page_cycler_v2_site_isolation.basic_oopif.reference", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "10de:104a", - "id": "build96-m1", - "os": "Windows-2008ServerR2-SP1", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": true, - "io_timeout": 600, - "upload_test_results": false - } - }, - { - "args": [ "power.idle_platform", "-v", "--upload-results", @@ -87299,130 +85811,6 @@ }, { "args": [ - "page_cycler_v2.basic_oopif", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=release" - ], - "isolate_name": "telemetry_perf_tests", - "name": "page_cycler_v2.basic_oopif", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "102b:0532", - "id": "build188-m1", - "os": "Windows-2008ServerR2-SP1", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 600, - "upload_test_results": false - } - }, - { - "args": [ - "page_cycler_v2.basic_oopif", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=reference", - "--max-failures=5", - "--output-trace-tag=_ref" - ], - "isolate_name": "telemetry_perf_tests", - "name": "page_cycler_v2.basic_oopif.reference", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "102b:0532", - "id": "build188-m1", - "os": "Windows-2008ServerR2-SP1", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": true, - "io_timeout": 600, - "upload_test_results": false - } - }, - { - "args": [ - "page_cycler_v2_site_isolation.basic_oopif", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=release" - ], - "isolate_name": "telemetry_perf_tests", - "name": "page_cycler_v2_site_isolation.basic_oopif", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "102b:0532", - "id": "build189-m1", - "os": "Windows-2008ServerR2-SP1", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 600, - "upload_test_results": false - } - }, - { - "args": [ - "page_cycler_v2_site_isolation.basic_oopif", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=reference", - "--max-failures=5", - "--output-trace-tag=_ref" - ], - "isolate_name": "telemetry_perf_tests", - "name": "page_cycler_v2_site_isolation.basic_oopif.reference", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "102b:0532", - "id": "build189-m1", - "os": "Windows-2008ServerR2-SP1", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": true, - "io_timeout": 600, - "upload_test_results": false - } - }, - { - "args": [ "power.idle_platform", "-v", "--upload-results", @@ -91755,130 +90143,6 @@ } }, { - "args": [ - "page_cycler_v2.basic_oopif", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=release_x64" - ], - "isolate_name": "telemetry_perf_tests", - "name": "page_cycler_v2.basic_oopif", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "102b:0532", - "id": "build139-m1", - "os": "Windows-2008ServerR2-SP1", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 600, - "upload_test_results": false - } - }, - { - "args": [ - "page_cycler_v2.basic_oopif", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=reference", - "--max-failures=5", - "--output-trace-tag=_ref" - ], - "isolate_name": "telemetry_perf_tests", - "name": "page_cycler_v2.basic_oopif.reference", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "102b:0532", - "id": "build139-m1", - "os": "Windows-2008ServerR2-SP1", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": true, - "io_timeout": 600, - "upload_test_results": false - } - }, - { - "args": [ - "page_cycler_v2_site_isolation.basic_oopif", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=release_x64" - ], - "isolate_name": "telemetry_perf_tests", - "name": "page_cycler_v2_site_isolation.basic_oopif", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "102b:0532", - "id": "build142-m1", - "os": "Windows-2008ServerR2-SP1", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 600, - "upload_test_results": false - } - }, - { - "args": [ - "page_cycler_v2_site_isolation.basic_oopif", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=reference", - "--max-failures=5", - "--output-trace-tag=_ref" - ], - "isolate_name": "telemetry_perf_tests", - "name": "page_cycler_v2_site_isolation.basic_oopif.reference", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "102b:0532", - "id": "build142-m1", - "os": "Windows-2008ServerR2-SP1", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": true, - "io_timeout": 600, - "upload_test_results": false - } - }, - { "args": [], "isolate_name": "performance_browser_tests", "name": "performance_browser_tests", @@ -96254,130 +94518,6 @@ } }, { - "args": [ - "page_cycler_v2.basic_oopif", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=release_x64" - ], - "isolate_name": "telemetry_perf_tests", - "name": "page_cycler_v2.basic_oopif", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "102b:0532", - "id": "build144-m1", - "os": "Windows-2012ServerR2-SP0", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 600, - "upload_test_results": false - } - }, - { - "args": [ - "page_cycler_v2.basic_oopif", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=reference", - "--max-failures=5", - "--output-trace-tag=_ref" - ], - "isolate_name": "telemetry_perf_tests", - "name": "page_cycler_v2.basic_oopif.reference", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "102b:0532", - "id": "build144-m1", - "os": "Windows-2012ServerR2-SP0", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": true, - "io_timeout": 600, - "upload_test_results": false - } - }, - { - "args": [ - "page_cycler_v2_site_isolation.basic_oopif", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=release_x64" - ], - "isolate_name": "telemetry_perf_tests", - "name": "page_cycler_v2_site_isolation.basic_oopif", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "102b:0532", - "id": "build147-m1", - "os": "Windows-2012ServerR2-SP0", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 600, - "upload_test_results": false - } - }, - { - "args": [ - "page_cycler_v2_site_isolation.basic_oopif", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=reference", - "--max-failures=5", - "--output-trace-tag=_ref" - ], - "isolate_name": "telemetry_perf_tests", - "name": "page_cycler_v2_site_isolation.basic_oopif.reference", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "102b:0532", - "id": "build147-m1", - "os": "Windows-2012ServerR2-SP0", - "pool": "Chrome-perf" - } - ], - "expiration": 72000, - "hard_timeout": 10800, - "ignore_task_failure": true, - "io_timeout": 600, - "upload_test_results": false - } - }, - { "args": [], "isolate_name": "performance_browser_tests", "name": "performance_browser_tests",
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations index 1110d88b6..47b4e99 100644 --- a/third_party/WebKit/LayoutTests/TestExpectations +++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -1001,6 +1001,10 @@ crbug.com/637255 [ Win10 ] media/video-transformed.html [ Pass Failure ] +crbug.com/760367 http/tests/devtools/console/console-tainted-globals.html [ NeedsManualRebaseline Timeout ] +crbug.com/760367 inspector/runtime/runtime-callFunctionOn.html [ NeedsManualRebaseline Timeout ] +crbug.com/760367 virtual/mojo-loading/http/tests/devtools/console/console-tainted-globals.html [ NeedsManualRebaseline Timeout ] + # These tests pass but images do not match because tests are stricter than the spec. crbug.com/492664 external/wpt/css/css-writing-modes-3/text-combine-upright-value-all-001.html [ Failure ] crbug.com/492664 external/wpt/css/css-writing-modes-3/text-combine-upright-value-all-002.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/compositing/overflow/escape-clip-to-scroll-sibling-should-not-crash-expected.html b/third_party/WebKit/LayoutTests/compositing/overflow/escape-clip-to-scroll-sibling-should-not-crash-expected.html new file mode 100644 index 0000000..d4d9515 --- /dev/null +++ b/third_party/WebKit/LayoutTests/compositing/overflow/escape-clip-to-scroll-sibling-should-not-crash-expected.html
@@ -0,0 +1,6 @@ +<!DOCTYPE html> +<div style="overflow:scroll; width:100px; height:100px;"> + <div style="width:200px; height:200px; background: green;"> + </div> +</div> +This test verifies an element can correctly escape clip to some scroll sibling's state.
diff --git a/third_party/WebKit/LayoutTests/compositing/overflow/escape-clip-to-scroll-sibling-should-not-crash.html b/third_party/WebKit/LayoutTests/compositing/overflow/escape-clip-to-scroll-sibling-should-not-crash.html new file mode 100644 index 0000000..3159e5e6 --- /dev/null +++ b/third_party/WebKit/LayoutTests/compositing/overflow/escape-clip-to-scroll-sibling-should-not-crash.html
@@ -0,0 +1,30 @@ +<!DOCTYPE html> +<div style="overflow:scroll; position:relative; width:100px; height:100px;"> + <div id="elem" style="position:relative; width:200px; height:200px; overflow:hidden;"> + <div style="will-change:opacity; overflow:hidden; width:10px; height:10px;"> + <div style="position:absolute; width:250px; height:250px; background:green;"></div> + </div> + </div> +</div> +This test verifies an element can correctly escape clip to some scroll sibling's state. +<script src="../../resources/run-after-layout-and-paint.js"></script> +<script> +// The crash we intended to test is sensitive to random hash ordering. +// There is a 50% probability to crash for each trial. +var elem = document.getElementById('elem'); +var count = 10; +function toggle() { + if (elem.style.display == 'none') + elem.style.display = ''; + else + elem.style.display = 'none'; + + if (--count) + runAfterLayoutAndPaint(toggle); + else if (window.testRunner) + testRunner.notifyDone(); +} +if (window.testRunner) + testRunner.waitUntilDone(); +runAfterLayoutAndPaint(toggle); +</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/feature-policy/resources/feature-policy-webvr.html b/third_party/WebKit/LayoutTests/external/wpt/feature-policy/resources/feature-policy-webvr.html new file mode 100644 index 0000000..64a152b --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/feature-policy/resources/feature-policy-webvr.html
@@ -0,0 +1,9 @@ +<script> +'use strict'; + +Promise.resolve().then(() => navigator.getVRDisplays()).then(displays => { + window.parent.postMessage({ enabled: true }, '*'); +}, error => { + window.parent.postMessage({ enabled: false }, '*'); +}); +</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webvr/webvr-disabled-by-feature-policy.https.sub.html b/third_party/WebKit/LayoutTests/external/wpt/webvr/webvr-disabled-by-feature-policy.https.sub.html new file mode 100644 index 0000000..567499c --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/webvr/webvr-disabled-by-feature-policy.https.sub.html
@@ -0,0 +1,33 @@ +<!DOCTYPE html> +<body> + <script src=/resources/testharness.js></script> + <script src=/resources/testharnessreport.js></script> + <script src=/feature-policy/resources/featurepolicy.js></script> + + <script> + 'use strict'; + var same_origin_src = '/feature-policy/resources/feature-policy-webvr.html'; + var cross_origin_src = 'https://{{domains[www]}}:{{ports[https][0]}}' + + same_origin_src; + var header = 'Feature-Policy header vr "none"'; + + promise_test(() => { + return navigator.getVRDisplays().then(() => { + assert_unreached('expected promise to reject'); + }, error => { + }); + }, header + ' disallows the top-level document.'); + + async_test(t => { + test_feature_availability( + 'navigator.getVRDisplays()', t, same_origin_src, + expect_feature_unavailable_default); + }, header + ' disallows same-origin iframes.'); + + async_test(t => { + test_feature_availability( + 'navigator.getVRDisplays()', t, cross_origin_src, + expect_feature_unavailable_default); + }, header + ' disallows cross-origin iframes.'); + </script> +</body>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webvr/webvr-disabled-by-feature-policy.https.sub.html.headers b/third_party/WebKit/LayoutTests/external/wpt/webvr/webvr-disabled-by-feature-policy.https.sub.html.headers new file mode 100644 index 0000000..d021af7 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/webvr/webvr-disabled-by-feature-policy.https.sub.html.headers
@@ -0,0 +1 @@ +Feature-Policy: vr 'none'
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webvr/webvr-enabled-by-feature-policy-attribute-redirect-on-load.https.sub.html b/third_party/WebKit/LayoutTests/external/wpt/webvr/webvr-enabled-by-feature-policy-attribute-redirect-on-load.https.sub.html new file mode 100644 index 0000000..da01dafd --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/webvr/webvr-enabled-by-feature-policy-attribute-redirect-on-load.https.sub.html
@@ -0,0 +1,27 @@ +<!DOCTYPE html> +<body> + <script src=/resources/testharness.js></script> + <script src=/resources/testharnessreport.js></script> + <script src=/feature-policy/resources/featurepolicy.js></script> + <script> + 'use strict'; + var relative_path = '/feature-policy/resources/feature-policy-webvr.html'; + var base_src = '/feature-policy/resources/redirect-on-load.html#'; + var same_origin_src = base_src + relative_path; + var cross_origin_src = base_src + 'https://{{domains[www]}}:{{ports[https][0]}}' + + relative_path; + var header = 'Feature-Policy allow="vr" attribute'; + + async_test(t => { + test_feature_availability( + 'navigator.getVRDisplays()', t, same_origin_src, + expect_feature_available_default, 'vr'); + }, header + ' allows same-origin relocation'); + + async_test(t => { + test_feature_availability( + 'navigator.getVRDisplays()', t, cross_origin_src, + expect_feature_unavailable_default, 'vr'); + }, header + ' disallows cross-origin relocation'); + </script> +</body>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webvr/webvr-enabled-by-feature-policy-attribute.https.sub.html b/third_party/WebKit/LayoutTests/external/wpt/webvr/webvr-enabled-by-feature-policy-attribute.https.sub.html new file mode 100644 index 0000000..d715f90 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/webvr/webvr-enabled-by-feature-policy-attribute.https.sub.html
@@ -0,0 +1,25 @@ +<!DOCTYPE html> +<body> + <script src=/resources/testharness.js></script> + <script src=/resources/testharnessreport.js></script> + <script src=/feature-policy/resources/featurepolicy.js></script> + <script> + 'use strict'; + var same_origin_src = '/feature-policy/resources/feature-policy-webvr.html'; + var cross_origin_src = 'https://{{domains[www]}}:{{ports[https][0]}}' + + same_origin_src; + var header = 'Feature-Policy allow="vr" attribute'; + + async_test(t => { + test_feature_availability( + 'navigator.getVRDisplays()', t, same_origin_src, + expect_feature_available_default, 'vr'); + }, header + ' allows same-origin iframe'); + + async_test(t => { + test_feature_availability( + 'navigator.getVRDisplays()', t, cross_origin_src, + expect_feature_available_default, 'vr'); + }, header + ' allows cross-origin iframe'); + </script> +</body>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webvr/webvr-enabled-by-feature-policy.https.sub.html b/third_party/WebKit/LayoutTests/external/wpt/webvr/webvr-enabled-by-feature-policy.https.sub.html new file mode 100644 index 0000000..ee02566 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/webvr/webvr-enabled-by-feature-policy.https.sub.html
@@ -0,0 +1,30 @@ +<!DOCTYPE html> +<body> + <script src=/resources/testharness.js></script> + <script src=/resources/testharnessreport.js></script> + <script src=/feature-policy/resources/featurepolicy.js></script> + + <script> + 'use strict'; + var same_origin_src = '/feature-policy/resources/feature-policy-webvr.html'; + var cross_origin_src = 'https://{{domains[www]}}:{{ports[https][0]}}' + + same_origin_src; + var header = 'Feature-Policy header vr *'; + + promise_test( + () => navigator.getVRDisplays(), + header + ' allows the top-level document.'); + + async_test(t => { + test_feature_availability( + 'navigator.getVRDisplays()', t, same_origin_src, + expect_feature_available_default); + }, header + ' allows same-origin iframes.'); + + async_test(t => { + test_feature_availability( + 'navigator.getVRDisplays()', t, cross_origin_src, + expect_feature_available_default); + }, header + ' allows cross-origin iframes.'); + </script> +</body>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webvr/webvr-enabled-by-feature-policy.https.sub.html.headers b/third_party/WebKit/LayoutTests/external/wpt/webvr/webvr-enabled-by-feature-policy.https.sub.html.headers new file mode 100644 index 0000000..e7427ee --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/webvr/webvr-enabled-by-feature-policy.https.sub.html.headers
@@ -0,0 +1 @@ +Feature-Policy: vr *
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webvr/webvr-enabled-on-self-origin-by-feature-policy.https.sub.html b/third_party/WebKit/LayoutTests/external/wpt/webvr/webvr-enabled-on-self-origin-by-feature-policy.https.sub.html new file mode 100644 index 0000000..bd7e82f --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/webvr/webvr-enabled-on-self-origin-by-feature-policy.https.sub.html
@@ -0,0 +1,30 @@ +<!DOCTYPE html> +<body> + <script src=/resources/testharness.js></script> + <script src=/resources/testharnessreport.js></script> + <script src=/feature-policy/resources/featurepolicy.js></script> + + <script> + 'use strict'; + var same_origin_src = '/feature-policy/resources/feature-policy-webvr.html'; + var cross_origin_src = 'https://{{domains[www]}}:{{ports[https][0]}}' + + same_origin_src; + var header = 'Feature-Policy header vr "self"'; + + promise_test( + () => navigator.getVRDisplays(), + header + ' allows the top-level document.'); + + async_test(t => { + test_feature_availability( + 'navigator.getVRDisplays()', t, same_origin_src, + expect_feature_available_default); + }, header + ' allows same-origin iframes.'); + + async_test(t => { + test_feature_availability( + 'navigator.getVRDisplays()', t, cross_origin_src, + expect_feature_unavailable_default); + }, header + ' disallows cross-origin iframes.'); + </script> +</body>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webvr/webvr-enabled-on-self-origin-by-feature-policy.https.sub.html.headers b/third_party/WebKit/LayoutTests/external/wpt/webvr/webvr-enabled-on-self-origin-by-feature-policy.https.sub.html.headers new file mode 100644 index 0000000..87d343d --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/webvr/webvr-enabled-on-self-origin-by-feature-policy.https.sub.html.headers
@@ -0,0 +1 @@ +Feature-Policy: vr 'self'
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-tainted-globals.html b/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-tainted-globals.html index d212db4..a5f2289 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-tainted-globals.html +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-tainted-globals.html
@@ -157,7 +157,7 @@ function sum() { return this.a + this.b; } - result = await TestRunner.RuntimeAgent.callFunctionOn(result.objectId, sum.toString()); + result = await TestRunner.RuntimeAgent.callFunctionOn(sum.toString(), result.objectId); TestRunner.assertEquals(3, result.value); next();
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/cache-storage/cache-data-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector/cache-storage/cache-data-expected.txt index c47f78e2..726f950c 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector/cache-storage/cache-data-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/inspector/cache-storage/cache-data-expected.txt
@@ -9,9 +9,9 @@ (cache empty) Dumping CacheStorage tree: cache: testCache1 - http://127.0.0.1:8000 - 1 - 2 + 1, text/plain, 0 + 2, text/plain, 0 cache: testCache2 - http://127.0.0.1:8000 - 1 - 2 + 1, text/plain, 0 + 2, text/plain, 0
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/cache-storage/cache-deletion-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector/cache-storage/cache-deletion-expected.txt index d23d751..9fbb577 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector/cache-storage/cache-deletion-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/inspector/cache-storage/cache-deletion-expected.txt
@@ -9,11 +9,11 @@ (cache empty) Dumping CacheStorage tree: cache: testCache1 - http://127.0.0.1:8000 - 1 - 2 + 1, text/plain, 0 + 2, text/plain, 0 cache: testCache2 - http://127.0.0.1:8000 - 1 - 2 + 1, text/plain, 0 + 2, text/plain, 0 Deleting CacheStorage cache testCache2 Dumping CacheStorage tree: (empty)
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/cache-storage/cache-entry-deletion-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector/cache-storage/cache-entry-deletion-expected.txt index aea9ec6..ea56f742 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector/cache-storage/cache-entry-deletion-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/inspector/cache-storage/cache-entry-deletion-expected.txt
@@ -4,15 +4,15 @@ (empty) Dumping CacheStorage tree: cache: testCache1 - http://127.0.0.1:8000 - 1 - 2 + 1, text/plain, 0 + 2, text/plain, 0 cache: testCache2 - http://127.0.0.1:8000 - 1 - 2 + 1, text/plain, 0 + 2, text/plain, 0 Deleting CacheStorage entry http://fake.request2.com/2 in cache testCache2 Dumping CacheStorage tree: cache: testCache1 - http://127.0.0.1:8000 - 1 + 1, text/plain, 0 cache: testCache2 - http://127.0.0.1:8000 - 1 + 1, text/plain, 0
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/cache-storage/cache-live-update-cache-content-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector/cache-storage/cache-live-update-cache-content-expected.txt index ea42256..4740da4 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector/cache-storage/cache-live-update-cache-content-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/inspector/cache-storage/cache-live-update-cache-content-expected.txt
@@ -8,7 +8,7 @@ Added entry Dumping CacheStorage tree: cache: testCache1 - http://127.0.0.1:8000 - 1 + 1, text/plain, 0 Deleted entry Dumping CacheStorage tree: cache: testCache1 - http://127.0.0.1:8000
diff --git a/third_party/WebKit/LayoutTests/inspector/runtime/runtime-callFunctionOn.html b/third_party/WebKit/LayoutTests/inspector/runtime/runtime-callFunctionOn.html index 1f4229ea..17d10f2d 100644 --- a/third_party/WebKit/LayoutTests/inspector/runtime/runtime-callFunctionOn.html +++ b/third_party/WebKit/LayoutTests/inspector/runtime/runtime-callFunctionOn.html
@@ -13,7 +13,7 @@ function sum() { return this.a + this.b; } - var result = await TestRunner.RuntimeAgent.callFunctionOn(obj1.objectId, sum.toString()); + var result = await TestRunner.RuntimeAgent.callFunctionOn(sum.toString(), obj1.objectId); TestRunner.addResult(result.value); next(); @@ -27,7 +27,7 @@ undef; } var result = - await TestRunner.RuntimeAgent.callFunctionOn(obj1.objectId, format.toString(), [obj1, obj2, {value: 4}, {}]); + await TestRunner.RuntimeAgent.callFunctionOn(format.toString(), obj1.objectId, [obj1, obj2, {value: 4}, {}]); TestRunner.addResult(result.value); next();
diff --git a/third_party/WebKit/Source/core/editing/markers/ActiveSuggestionMarkerListImpl.cpp b/third_party/WebKit/Source/core/editing/markers/ActiveSuggestionMarkerListImpl.cpp index a053005..19765f45 100644 --- a/third_party/WebKit/Source/core/editing/markers/ActiveSuggestionMarkerListImpl.cpp +++ b/third_party/WebKit/Source/core/editing/markers/ActiveSuggestionMarkerListImpl.cpp
@@ -17,6 +17,7 @@ } void ActiveSuggestionMarkerListImpl::Add(DocumentMarker* marker) { + DCHECK_EQ(DocumentMarker::kActiveSuggestion, marker->GetType()); SortedDocumentMarkerListEditor::AddMarkerWithoutMergingOverlapping(&markers_, marker); }
diff --git a/third_party/WebKit/Source/core/editing/markers/CompositionMarkerListImpl.cpp b/third_party/WebKit/Source/core/editing/markers/CompositionMarkerListImpl.cpp index abcee75..130c10d 100644 --- a/third_party/WebKit/Source/core/editing/markers/CompositionMarkerListImpl.cpp +++ b/third_party/WebKit/Source/core/editing/markers/CompositionMarkerListImpl.cpp
@@ -4,7 +4,7 @@ #include "core/editing/markers/CompositionMarkerListImpl.h" -#include "core/editing/markers/SortedDocumentMarkerListEditor.h" +#include "core/editing/markers/UnsortedDocumentMarkerListEditor.h" namespace blink { @@ -17,8 +17,8 @@ } void CompositionMarkerListImpl::Add(DocumentMarker* marker) { - SortedDocumentMarkerListEditor::AddMarkerWithoutMergingOverlapping(&markers_, - marker); + DCHECK_EQ(DocumentMarker::kComposition, marker->GetType()); + markers_.push_back(marker); } void CompositionMarkerListImpl::Clear() { @@ -33,34 +33,34 @@ DocumentMarker* CompositionMarkerListImpl::FirstMarkerIntersectingRange( unsigned start_offset, unsigned end_offset) const { - return SortedDocumentMarkerListEditor::FirstMarkerIntersectingRange( + return UnsortedDocumentMarkerListEditor::FirstMarkerIntersectingRange( markers_, start_offset, end_offset); } HeapVector<Member<DocumentMarker>> CompositionMarkerListImpl::MarkersIntersectingRange(unsigned start_offset, unsigned end_offset) const { - return SortedDocumentMarkerListEditor::MarkersIntersectingRange( + return UnsortedDocumentMarkerListEditor::MarkersIntersectingRange( markers_, start_offset, end_offset); } bool CompositionMarkerListImpl::MoveMarkers(int length, DocumentMarkerList* dst_markers_) { - return SortedDocumentMarkerListEditor::MoveMarkers(&markers_, length, - dst_markers_); + return UnsortedDocumentMarkerListEditor::MoveMarkers(&markers_, length, + dst_markers_); } bool CompositionMarkerListImpl::RemoveMarkers(unsigned start_offset, int length) { - return SortedDocumentMarkerListEditor::RemoveMarkers(&markers_, start_offset, - length); + return UnsortedDocumentMarkerListEditor::RemoveMarkers(&markers_, + start_offset, length); } bool CompositionMarkerListImpl::ShiftMarkers(const String&, unsigned offset, unsigned old_length, unsigned new_length) { - return SortedDocumentMarkerListEditor::ShiftMarkersContentIndependent( + return UnsortedDocumentMarkerListEditor::ShiftMarkersContentIndependent( &markers_, offset, old_length, new_length); }
diff --git a/third_party/WebKit/Source/core/editing/markers/CompositionMarkerListImpl.h b/third_party/WebKit/Source/core/editing/markers/CompositionMarkerListImpl.h index 2c057d4..4bf8851e 100644 --- a/third_party/WebKit/Source/core/editing/markers/CompositionMarkerListImpl.h +++ b/third_party/WebKit/Source/core/editing/markers/CompositionMarkerListImpl.h
@@ -9,12 +9,10 @@ namespace blink { -// Implementation of DocumentMarkerList for Composition markers. -// Composition markers are always inserted in order, aside from some potential -// oddball cases (e.g. splitting the marker list into two nodes, then undoing -// the split). This means we can keep the list in sorted order to do some -// operations more efficiently, while still being able to do inserts in O(1) -// time at the end of the list. +// Implementation of DocumentMarkerList for Composition markers. Composition +// markers can overlap (e.g. an IME might pass two markers on the same region of +// text, one to underline it and one to add a background color), so we store +// them unsorted. class CORE_EXPORT CompositionMarkerListImpl final : public DocumentMarkerList { public: CompositionMarkerListImpl() = default;
diff --git a/third_party/WebKit/Source/core/editing/markers/CompositionMarkerListImplTest.cpp b/third_party/WebKit/Source/core/editing/markers/CompositionMarkerListImplTest.cpp index 15f58c7..9ba9da4 100644 --- a/third_party/WebKit/Source/core/editing/markers/CompositionMarkerListImplTest.cpp +++ b/third_party/WebKit/Source/core/editing/markers/CompositionMarkerListImplTest.cpp
@@ -23,20 +23,66 @@ Persistent<CompositionMarkerListImpl> marker_list_; }; -// CompositionMarkerListImpl shouldn't merge markers with touching endpoints -TEST_F(CompositionMarkerListImplTest, Add) { - EXPECT_EQ(0u, marker_list_->GetMarkers().size()); +namespace { - marker_list_->Add(CreateMarker(0, 1)); - marker_list_->Add(CreateMarker(1, 2)); +bool compare_markers(const Member<DocumentMarker>& marker1, + const Member<DocumentMarker>& marker2) { + if (marker1->StartOffset() != marker2->StartOffset()) + return marker1->StartOffset() < marker2->StartOffset(); - EXPECT_EQ(2u, marker_list_->GetMarkers().size()); + return marker1->EndOffset() < marker2->EndOffset(); +} - EXPECT_EQ(0u, marker_list_->GetMarkers()[0]->StartOffset()); - EXPECT_EQ(1u, marker_list_->GetMarkers()[0]->EndOffset()); +} // namespace - EXPECT_EQ(1u, marker_list_->GetMarkers()[1]->StartOffset()); - EXPECT_EQ(2u, marker_list_->GetMarkers()[1]->EndOffset()); +TEST_F(CompositionMarkerListImplTest, AddOverlapping) { + // Add some overlapping markers in an arbitrary order and verify that the + // list stores them properly + marker_list_->Add(CreateMarker(40, 50)); + marker_list_->Add(CreateMarker(10, 40)); + marker_list_->Add(CreateMarker(20, 50)); + marker_list_->Add(CreateMarker(10, 30)); + marker_list_->Add(CreateMarker(10, 50)); + marker_list_->Add(CreateMarker(30, 50)); + marker_list_->Add(CreateMarker(30, 40)); + marker_list_->Add(CreateMarker(10, 20)); + marker_list_->Add(CreateMarker(20, 40)); + marker_list_->Add(CreateMarker(20, 30)); + + DocumentMarkerVector markers = marker_list_->GetMarkers(); + std::sort(markers.begin(), markers.end(), compare_markers); + + EXPECT_EQ(10u, markers.size()); + + EXPECT_EQ(10u, markers[0]->StartOffset()); + EXPECT_EQ(20u, markers[0]->EndOffset()); + + EXPECT_EQ(10u, markers[1]->StartOffset()); + EXPECT_EQ(30u, markers[1]->EndOffset()); + + EXPECT_EQ(10u, markers[2]->StartOffset()); + EXPECT_EQ(40u, markers[2]->EndOffset()); + + EXPECT_EQ(10u, markers[3]->StartOffset()); + EXPECT_EQ(50u, markers[3]->EndOffset()); + + EXPECT_EQ(20u, markers[4]->StartOffset()); + EXPECT_EQ(30u, markers[4]->EndOffset()); + + EXPECT_EQ(20u, markers[5]->StartOffset()); + EXPECT_EQ(40u, markers[5]->EndOffset()); + + EXPECT_EQ(20u, markers[6]->StartOffset()); + EXPECT_EQ(50u, markers[6]->EndOffset()); + + EXPECT_EQ(30u, markers[7]->StartOffset()); + EXPECT_EQ(40u, markers[7]->EndOffset()); + + EXPECT_EQ(30u, markers[8]->StartOffset()); + EXPECT_EQ(50u, markers[8]->EndOffset()); + + EXPECT_EQ(40u, markers[9]->StartOffset()); + EXPECT_EQ(50u, markers[9]->EndOffset()); } } // namespace blink
diff --git a/third_party/WebKit/Source/core/editing/markers/SpellCheckMarkerListImpl.cpp b/third_party/WebKit/Source/core/editing/markers/SpellCheckMarkerListImpl.cpp index 5a1ec40..1405f5b 100644 --- a/third_party/WebKit/Source/core/editing/markers/SpellCheckMarkerListImpl.cpp +++ b/third_party/WebKit/Source/core/editing/markers/SpellCheckMarkerListImpl.cpp
@@ -13,6 +13,8 @@ } void SpellCheckMarkerListImpl::Add(DocumentMarker* marker) { + DCHECK_EQ(MarkerType(), marker->GetType()); + if (markers_.IsEmpty() || markers_.back()->EndOffset() < marker->StartOffset()) { markers_.push_back(marker);
diff --git a/third_party/WebKit/Source/core/editing/markers/SuggestionMarkerListImpl.cpp b/third_party/WebKit/Source/core/editing/markers/SuggestionMarkerListImpl.cpp index 3aac516..811682b6 100644 --- a/third_party/WebKit/Source/core/editing/markers/SuggestionMarkerListImpl.cpp +++ b/third_party/WebKit/Source/core/editing/markers/SuggestionMarkerListImpl.cpp
@@ -63,6 +63,7 @@ } void SuggestionMarkerListImpl::Add(DocumentMarker* marker) { + DCHECK_EQ(DocumentMarker::kSuggestion, marker->GetType()); markers_.push_back(marker); }
diff --git a/third_party/WebKit/Source/core/editing/markers/TextMatchMarkerListImpl.cpp b/third_party/WebKit/Source/core/editing/markers/TextMatchMarkerListImpl.cpp index ddc337dc..feb398f 100644 --- a/third_party/WebKit/Source/core/editing/markers/TextMatchMarkerListImpl.cpp +++ b/third_party/WebKit/Source/core/editing/markers/TextMatchMarkerListImpl.cpp
@@ -22,6 +22,7 @@ } void TextMatchMarkerListImpl::Add(DocumentMarker* marker) { + DCHECK_EQ(DocumentMarker::kTextMatch, marker->GetType()); SortedDocumentMarkerListEditor::AddMarkerWithoutMergingOverlapping(&markers_, marker); }
diff --git a/third_party/WebKit/Source/core/editing/markers/UnsortedDocumentMarkerListEditor.cpp b/third_party/WebKit/Source/core/editing/markers/UnsortedDocumentMarkerListEditor.cpp index 93dd7774..399325b 100644 --- a/third_party/WebKit/Source/core/editing/markers/UnsortedDocumentMarkerListEditor.cpp +++ b/third_party/WebKit/Source/core/editing/markers/UnsortedDocumentMarkerListEditor.cpp
@@ -56,6 +56,37 @@ return did_remove_marker; } +bool UnsortedDocumentMarkerListEditor::ShiftMarkersContentIndependent( + MarkerList* list, + unsigned offset, + unsigned old_length, + unsigned new_length) { + // For an unsorted marker list, the quickest way to perform this operation is + // to build a new list with the markers not removed by the shift. + bool did_shift_marker = false; + HeapVector<Member<DocumentMarker>> unremoved_markers; + for (const Member<DocumentMarker>& marker : *list) { + Optional<DocumentMarker::MarkerOffsets> result = + marker->ComputeOffsetsAfterShift(offset, old_length, new_length); + if (!result) { + did_shift_marker = true; + continue; + } + + if (marker->StartOffset() != result.value().start_offset || + marker->EndOffset() != result.value().end_offset) { + marker->SetStartOffset(result.value().start_offset); + marker->SetEndOffset(result.value().end_offset); + did_shift_marker = true; + } + + unremoved_markers.push_back(marker); + } + + *list = std::move(unremoved_markers); + return did_shift_marker; +} + DocumentMarker* UnsortedDocumentMarkerListEditor::FirstMarkerIntersectingRange( const MarkerList& list, unsigned start_offset,
diff --git a/third_party/WebKit/Source/core/editing/markers/UnsortedDocumentMarkerListEditorTest.cpp b/third_party/WebKit/Source/core/editing/markers/UnsortedDocumentMarkerListEditorTest.cpp index 92ac36f6..0c36b01 100644 --- a/third_party/WebKit/Source/core/editing/markers/UnsortedDocumentMarkerListEditorTest.cpp +++ b/third_party/WebKit/Source/core/editing/markers/UnsortedDocumentMarkerListEditorTest.cpp
@@ -135,6 +135,230 @@ } TEST_F(UnsortedDocumentMarkerListEditorTest, + ContentIndependentMarker_ReplaceStartOfMarker) { + UnsortedDocumentMarkerListEditor::MarkerList markers; + markers.push_back(CreateMarker(0, 10)); + + // Replace with shorter text + UnsortedDocumentMarkerListEditor::ShiftMarkersContentIndependent(&markers, 0, + 5, 4); + + EXPECT_EQ(1u, markers.size()); + EXPECT_EQ(0u, markers[0]->StartOffset()); + EXPECT_EQ(9u, markers[0]->EndOffset()); + + // Replace with longer text + UnsortedDocumentMarkerListEditor::ShiftMarkersContentIndependent(&markers, 0, + 4, 5); + + EXPECT_EQ(1u, markers.size()); + EXPECT_EQ(0u, markers[0]->StartOffset()); + EXPECT_EQ(10u, markers[0]->EndOffset()); + + // Replace with text of same length + UnsortedDocumentMarkerListEditor::ShiftMarkersContentIndependent(&markers, 0, + 5, 5); + + EXPECT_EQ(1u, markers.size()); + EXPECT_EQ(0u, markers[0]->StartOffset()); + EXPECT_EQ(10u, markers[0]->EndOffset()); +} + +TEST_F(UnsortedDocumentMarkerListEditorTest, + ContentIndependentMarker_ReplaceContainsStartOfMarker) { + UnsortedDocumentMarkerListEditor::MarkerList markers; + markers.push_back(CreateMarker(5, 15)); + + UnsortedDocumentMarkerListEditor::ShiftMarkersContentIndependent(&markers, 0, + 10, 10); + + EXPECT_EQ(1u, markers.size()); + EXPECT_EQ(10u, markers[0]->StartOffset()); + EXPECT_EQ(15u, markers[0]->EndOffset()); +} + +TEST_F(UnsortedDocumentMarkerListEditorTest, + ContentIndependentMarker_ReplaceEndOfMarker) { + UnsortedDocumentMarkerListEditor::MarkerList markers; + markers.push_back(CreateMarker(0, 10)); + + // Replace with shorter text + UnsortedDocumentMarkerListEditor::ShiftMarkersContentIndependent(&markers, 5, + 5, 4); + + EXPECT_EQ(1u, markers.size()); + EXPECT_EQ(0u, markers[0]->StartOffset()); + EXPECT_EQ(9u, markers[0]->EndOffset()); + + // Replace with longer text + UnsortedDocumentMarkerListEditor::ShiftMarkersContentIndependent(&markers, 5, + 4, 5); + + EXPECT_EQ(1u, markers.size()); + EXPECT_EQ(0u, markers[0]->StartOffset()); + EXPECT_EQ(10u, markers[0]->EndOffset()); + + // Replace with text of same length + UnsortedDocumentMarkerListEditor::ShiftMarkersContentIndependent(&markers, 5, + 5, 5); + + EXPECT_EQ(1u, markers.size()); + EXPECT_EQ(0u, markers[0]->StartOffset()); + EXPECT_EQ(10u, markers[0]->EndOffset()); +} + +TEST_F(UnsortedDocumentMarkerListEditorTest, + ContentIndependentMarker_ReplaceContainsEndOfMarker) { + UnsortedDocumentMarkerListEditor::MarkerList markers; + markers.push_back(CreateMarker(0, 10)); + + UnsortedDocumentMarkerListEditor::ShiftMarkersContentIndependent(&markers, 5, + 10, 10); + + EXPECT_EQ(1u, markers.size()); + EXPECT_EQ(0u, markers[0]->StartOffset()); + EXPECT_EQ(5u, markers[0]->EndOffset()); +} + +TEST_F(UnsortedDocumentMarkerListEditorTest, + ContentIndependentMarker_ReplaceEntireMarker) { + UnsortedDocumentMarkerListEditor::MarkerList markers; + markers.push_back(CreateMarker(0, 10)); + + // Replace with shorter text + UnsortedDocumentMarkerListEditor::ShiftMarkersContentIndependent(&markers, 0, + 10, 9); + + EXPECT_EQ(1u, markers.size()); + EXPECT_EQ(0u, markers[0]->StartOffset()); + EXPECT_EQ(9u, markers[0]->EndOffset()); + + // Replace with longer text + UnsortedDocumentMarkerListEditor::ShiftMarkersContentIndependent(&markers, 0, + 9, 10); + + EXPECT_EQ(1u, markers.size()); + EXPECT_EQ(0u, markers[0]->StartOffset()); + EXPECT_EQ(10u, markers[0]->EndOffset()); + + // Replace with text of same length + UnsortedDocumentMarkerListEditor::ShiftMarkersContentIndependent(&markers, 0, + 10, 10); + + EXPECT_EQ(1u, markers.size()); + EXPECT_EQ(0u, markers[0]->StartOffset()); + EXPECT_EQ(10u, markers[0]->EndOffset()); +} + +TEST_F(UnsortedDocumentMarkerListEditorTest, + ContentIndependentMarker_ReplaceTextWithMarkerAtBeginning) { + UnsortedDocumentMarkerListEditor::MarkerList markers; + markers.push_back(CreateMarker(0, 10)); + + UnsortedDocumentMarkerListEditor::ShiftMarkersContentIndependent(&markers, 0, + 15, 15); + + EXPECT_EQ(0u, markers.size()); +} + +TEST_F(UnsortedDocumentMarkerListEditorTest, + ContentIndependentMarker_ReplaceTextWithMarkerAtEnd) { + UnsortedDocumentMarkerListEditor::MarkerList markers; + markers.push_back(CreateMarker(5, 15)); + + UnsortedDocumentMarkerListEditor::ShiftMarkersContentIndependent(&markers, 0, + 15, 15); + + EXPECT_EQ(0u, markers.size()); +} + +TEST_F(UnsortedDocumentMarkerListEditorTest, + ContentIndependentMarker_Deletions) { + UnsortedDocumentMarkerListEditor::MarkerList markers; + markers.push_back(CreateMarker(0, 5)); + markers.push_back(CreateMarker(5, 10)); + markers.push_back(CreateMarker(10, 15)); + markers.push_back(CreateMarker(15, 20)); + markers.push_back(CreateMarker(20, 25)); + + // Delete range containing the end of the second marker, the entire third + // marker, and the start of the fourth marker + UnsortedDocumentMarkerListEditor::ShiftMarkersContentIndependent(&markers, 8, + 9, 0); + + EXPECT_EQ(4u, markers.size()); + + EXPECT_EQ(0u, markers[0]->StartOffset()); + EXPECT_EQ(5u, markers[0]->EndOffset()); + + EXPECT_EQ(5u, markers[1]->StartOffset()); + EXPECT_EQ(8u, markers[1]->EndOffset()); + + EXPECT_EQ(8u, markers[2]->StartOffset()); + EXPECT_EQ(11u, markers[2]->EndOffset()); + + EXPECT_EQ(11u, markers[3]->StartOffset()); + EXPECT_EQ(16u, markers[3]->EndOffset()); +} + +TEST_F(UnsortedDocumentMarkerListEditorTest, + ContentIndependentMarker_DeleteExactlyOnMarker) { + UnsortedDocumentMarkerListEditor::MarkerList markers; + markers.push_back(CreateMarker(0, 10)); + + UnsortedDocumentMarkerListEditor::ShiftMarkersContentIndependent(&markers, 0, + 10, 0); + + EXPECT_EQ(0u, markers.size()); +} + +TEST_F(UnsortedDocumentMarkerListEditorTest, + ContentIndependentMarker_InsertInMarkerInterior) { + UnsortedDocumentMarkerListEditor::MarkerList markers; + markers.push_back(CreateMarker(0, 5)); + markers.push_back(CreateMarker(5, 10)); + markers.push_back(CreateMarker(10, 15)); + + // insert in middle of second marker + UnsortedDocumentMarkerListEditor::ShiftMarkersContentIndependent(&markers, 7, + 0, 5); + + EXPECT_EQ(3u, markers.size()); + + EXPECT_EQ(0u, markers[0]->StartOffset()); + EXPECT_EQ(5u, markers[0]->EndOffset()); + + EXPECT_EQ(5u, markers[1]->StartOffset()); + EXPECT_EQ(15u, markers[1]->EndOffset()); + + EXPECT_EQ(15u, markers[2]->StartOffset()); + EXPECT_EQ(20u, markers[2]->EndOffset()); +} + +TEST_F(UnsortedDocumentMarkerListEditorTest, + ContentIndependentMarker_InsertBetweenMarkers) { + UnsortedDocumentMarkerListEditor::MarkerList markers; + markers.push_back(CreateMarker(0, 5)); + markers.push_back(CreateMarker(5, 10)); + markers.push_back(CreateMarker(10, 15)); + + // insert before second marker + UnsortedDocumentMarkerListEditor::ShiftMarkersContentIndependent(&markers, 5, + 0, 5); + + EXPECT_EQ(3u, markers.size()); + + EXPECT_EQ(0u, markers[0]->StartOffset()); + EXPECT_EQ(5u, markers[0]->EndOffset()); + + EXPECT_EQ(10u, markers[1]->StartOffset()); + EXPECT_EQ(15u, markers[1]->EndOffset()); + + EXPECT_EQ(15u, markers[2]->StartOffset()); + EXPECT_EQ(20u, markers[2]->EndOffset()); +} + +TEST_F(UnsortedDocumentMarkerListEditorTest, FirstMarkerIntersectingRange_Empty) { DocumentMarker* marker = UnsortedDocumentMarkerListEditor::FirstMarkerIntersectingRange(
diff --git a/third_party/WebKit/Source/core/inspector/browser_protocol.json b/third_party/WebKit/Source/core/inspector/browser_protocol.json index acb70c5..7550fa6 100644 --- a/third_party/WebKit/Source/core/inspector/browser_protocol.json +++ b/third_party/WebKit/Source/core/inspector/browser_protocol.json
@@ -2129,7 +2129,11 @@ "description": "Data entry.", "properties": [ { "name": "requestURL", "type": "string", "description": "Request URL." }, + { "name": "requestMethod", "type": "string", "description": "Request method." }, + { "name": "requestHeaders", "type": "array", "items": { "$ref": "Header" }, "description": "Request headers" }, { "name": "responseTime", "type": "number", "description": "Number of seconds since epoch." }, + { "name": "responseStatus", "type": "integer", "description": "HTTP response status code." }, + { "name": "responseStatusText", "type": "string", "description": "HTTP response status text." }, { "name": "responseHeaders", "type": "array", "items": { "$ref": "Header" }, "description": "Response headers" } ] },
diff --git a/third_party/WebKit/Source/devtools/front_end/common/ResourceType.js b/third_party/WebKit/Source/devtools/front_end/common/ResourceType.js index 80243849..121f283b 100644 --- a/third_party/WebKit/Source/devtools/front_end/common/ResourceType.js +++ b/third_party/WebKit/Source/devtools/front_end/common/ResourceType.js
@@ -49,17 +49,24 @@ * @return {!Common.ResourceType} */ static fromMimeType(mimeType) { - var contentTypeAndTopLevelType = mimeType.match(/(\w*)\/\w*/); - if (!contentTypeAndTopLevelType) + if (mimeType.startsWith('text/html')) + return Common.resourceTypes.Document; + if (mimeType.startsWith('text/css')) + return Common.resourceTypes.Stylesheet; + if (mimeType.startsWith('image/')) + return Common.resourceTypes.Image; + if (mimeType.startsWith('text/')) + return Common.resourceTypes.Script; + + if (mimeType.includes('font')) + return Common.resourceTypes.Font; + if (mimeType.includes('script')) + return Common.resourceTypes.Script; + if (mimeType.includes('octet')) return Common.resourceTypes.Other; + if (mimeType.includes('application')) + return Common.resourceTypes.Script; - var resourceType = Common.ResourceType._resourceTypeByMimeType.get(contentTypeAndTopLevelType[0]); - if (resourceType) - return resourceType; - - resourceType = Common.ResourceType._resourceTypeByMimeType.get(contentTypeAndTopLevelType[1]); - if (resourceType) - return resourceType; return Common.resourceTypes.Other; } @@ -315,15 +322,3 @@ // Font ['ttf', 'font/opentype'], ['otf', 'font/opentype'], ['ttc', 'font/opentype'], ['woff', 'application/font-woff'] ]); - -Common.ResourceType._resourceTypeByMimeType = new Map([ - // Web types - ['text/javascript', Common.resourceTypes.Script], ['text/css', Common.resourceTypes.Stylesheet], - ['text/html', Common.resourceTypes.Document], ['application/json', Common.resourceTypes.Script], - - // Image - ['image', Common.resourceTypes.Image], - - // Font - ['font', Common.resourceTypes.Font], ['application/font-woff', Common.resourceTypes.Font] -]);
diff --git a/third_party/WebKit/Source/devtools/front_end/har_importer/HARImporter.js b/third_party/WebKit/Source/devtools/front_end/har_importer/HARImporter.js index 7a940210..184b4a24 100644 --- a/third_party/WebKit/Source/devtools/front_end/har_importer/HARImporter.js +++ b/third_party/WebKit/Source/devtools/front_end/har_importer/HARImporter.js
@@ -96,7 +96,7 @@ var contentData = {error: null, content: null, encoded: entry.response.content.encoding === 'base64'}; if (entry.response.content.text !== undefined) contentData.content = entry.response.content.text; - request.setContentData(contentData); + request.setContentDataProvider(async () => contentData); // Timing data. HARImporter.Importer._setupTiming(request, issueTime, entry.time, entry.timings);
diff --git a/third_party/WebKit/Source/devtools/front_end/resources/ServiceWorkerCacheViews.js b/third_party/WebKit/Source/devtools/front_end/resources/ServiceWorkerCacheViews.js index cd10121..df76aa0 100644 --- a/third_party/WebKit/Source/devtools/front_end/resources/ServiceWorkerCacheViews.js +++ b/third_party/WebKit/Source/devtools/front_end/resources/ServiceWorkerCacheViews.js
@@ -97,19 +97,59 @@ */ _createDataGrid() { var columns = /** @type {!Array<!DataGrid.DataGrid.ColumnDescriptor>} */ ([ - // {id: 'number', title: Common.UIString('#'), width: '50px'}, - {id: 'path', title: Common.UIString('Path')}, - // {id: 'response', title: Common.UIString('Response')}, - {id: 'responseTime', title: Common.UIString('Time Cached'), width: '12em'} + {id: 'path', title: Common.UIString('Path'), weight: 4, sortable: true}, + {id: 'contentType', title: Common.UIString('Content-Type'), weight: 1, sortable: true}, { + id: 'contentLength', + title: Common.UIString('Content-Length'), + weight: 1, + align: DataGrid.DataGrid.Align.Right, + sortable: true + }, + { + id: 'responseTime', + title: Common.UIString('Time Cached'), + width: '12em', + weight: 1, + align: DataGrid.DataGrid.Align.Right, + sortable: true + } ]); var dataGrid = new DataGrid.DataGrid( columns, undefined, this._deleteButtonClicked.bind(this), this._updateData.bind(this, true)); + + dataGrid.addEventListener(DataGrid.DataGrid.Events.SortingChanged, this._sortingChanged, this); + dataGrid.addEventListener( DataGrid.DataGrid.Events.SelectedNode, event => this._previewCachedResponse(event.data.data), this); dataGrid.setStriped(true); return dataGrid; } + _sortingChanged() { + if (!this._dataGrid) + return; + + var accending = this._dataGrid.isSortOrderAscending(); + var columnId = this._dataGrid.sortColumnId(); + var comparator; + if (columnId === 'path') + comparator = (a, b) => a._path.localeCompare(b._path); + else if (columnId === 'contentType') + comparator = (a, b) => a.data.mimeType.localeCompare(b.data.mimeType); + else if (columnId === 'contentLength') + comparator = (a, b) => a.data.resourceSize - b.data.resourceSize; + else if (columnId === 'responseTime') + comparator = (a, b) => a.data.endTime - b.data.endTime; + + var children = this._dataGrid.rootNode().children.slice(); + this._dataGrid.rootNode().removeChildren(); + children.sort((a, b) => { + var result = comparator(a, b); + return accending ? result : -result; + }); + children.forEach(child => this._dataGrid.rootNode().appendChild(child)); + } + /** * @param {!Common.Event} event */ @@ -135,7 +175,7 @@ if (!node) return; } - await this._model.deleteCacheEntry(this._cache, /** @type {string} */ (node.data.requestURL)); + await this._model.deleteCacheEntry(this._cache, /** @type {string} */ (node.data.url())); node.remove(); } @@ -160,7 +200,7 @@ * @this {Resources.ServiceWorkerCacheView} */ _updateDataCallback(skipCount, entries, hasMore) { - var selected = this._dataGrid.selectedNode && this._dataGrid.selectedNode.data.requestURL; + var selected = this._dataGrid.selectedNode && this._dataGrid.selectedNode.data.url(); this._refreshButton.setEnabled(true); this._entriesForTest = entries; @@ -174,7 +214,7 @@ for (var entry of entries) { var node = oldEntries.get(entry.requestURL); if (!node || node.data.responseTime !== entry.responseTime) { - node = new Resources.ServiceWorkerCacheView.DataGridNode(entry); + node = new Resources.ServiceWorkerCacheView.DataGridNode(this._createRequest(entry)); node.selectable = true; } rootNode.appendChild(node); @@ -227,61 +267,83 @@ } /** - * @param {!Protocol.CacheStorage.DataEntry} entry + * @param {!SDK.NetworkRequest} request */ - async _previewCachedResponse(entry) { - var preview = entry[Resources.ServiceWorkerCacheView._previewSymbol]; + async _previewCachedResponse(request) { + var preview = request[Resources.ServiceWorkerCacheView._previewSymbol]; if (!preview) { - preview = await this._entryPreview(entry); - entry[Resources.ServiceWorkerCacheView._previewSymbol] = preview; + preview = new Resources.ServiceWorkerCacheView.RequestView(request); + request[Resources.ServiceWorkerCacheView._previewSymbol] = preview; } // It is possible that table selection changes before the preview opens. - if (entry === this._dataGrid.selectedNode.data) + if (request === this._dataGrid.selectedNode.data) this._showPreview(preview); } /** * @param {!Protocol.CacheStorage.DataEntry} entry - * @return {!Promise<!UI.Widget>} + * @return {!SDK.NetworkRequest} */ - async _entryPreview(entry) { - var response = await this._cache.requestCachedResponse(entry.requestURL); - if (!response) - return new UI.EmptyWidget(Common.UIString('Preview is not available')); + _createRequest(entry) { + var request = new SDK.NetworkRequest('cache-storage-' + entry.requestURL, entry.requestURL, '', '', '', null); + request.requestMethod = entry.requestMethod; + request.setRequestHeaders(entry.requestHeaders); + request.statusCode = entry.responseStatus; + request.statusText = entry.responseStatusText; + request.protocol = new Common.ParsedURL(entry.requestURL).scheme; + request.responseHeaders = entry.responseHeaders; + request.setRequestHeadersText(''); + request.endTime = entry.responseTime; var header = entry.responseHeaders.find(header => header.name.toLowerCase() === 'content-type'); var contentType = header ? header.value : 'text/plain'; + request.mimeType = contentType; + + header = entry.responseHeaders.find(header => header.name.toLowerCase() === 'content-length'); + request.resourceSize = (header && header.value) | 0; + var resourceType = Common.ResourceType.fromMimeType(contentType); - var body = resourceType.isTextType() ? window.atob(response.body) : response.body; - var provider = new Common.StaticContentProvider(entry.requestURL, resourceType, () => Promise.resolve(body)); - var preview = SourceFrame.PreviewFactory.createPreview(provider, contentType); - if (!preview) - return new UI.EmptyWidget(Common.UIString('Preview is not available')); - return preview; + if (!resourceType) + resourceType = Common.ResourceType.fromURL(entry.requestURL) || Common.resourceTypes.Other; + request.setResourceType(resourceType); + request.setContentDataProvider(this._requestContent.bind(this, request)); + return request; + } + + /** + * @param {!SDK.NetworkRequest} request + * @return {!Promise<!SDK.NetworkRequest.ContentData>} + */ + async _requestContent(request) { + var isText = request.resourceType().isTextType(); + var contentData = {error: null, content: null, encoded: !isText}; + var response = await this._cache.requestCachedResponse(request.url()); + if (response) + contentData.content = isText ? window.atob(response.body) : response.body; + return contentData; } _updatedForTest() { } }; - Resources.ServiceWorkerCacheView._previewSymbol = Symbol('preview'); Resources.ServiceWorkerCacheView._RESPONSE_CACHE_SIZE = 10; Resources.ServiceWorkerCacheView.DataGridNode = class extends DataGrid.DataGridNode { /** - * @param {!Protocol.CacheStorage.DataEntry} entry + * @param {!SDK.NetworkRequest} request */ - constructor(entry) { - super(entry); - this._path = Common.ParsedURL.extractPath(entry.requestURL); + constructor(request) { + super(request); + this._path = Common.ParsedURL.extractPath(request.url()); if (!this._path) - this._path = entry.requestURL; + this._path = request.url(); if (this._path.length > 1 && this._path.startsWith('/')) this._path = this._path.substring(1); - this._responseTime = new Date(entry.responseTime * 1000).toLocaleString(); + this._request = request; } /** @@ -294,9 +356,54 @@ var value; if (columnId === 'path') value = this._path; + else if (columnId === 'contentType') + value = this._request.mimeType; + else if (columnId === 'contentLength') + value = (this._request.resourceSize | 0).toLocaleString('en-US'); else if (columnId === 'responseTime') - value = this._responseTime; + value = new Date(this._request.endTime * 1000).toLocaleString(); DataGrid.DataGrid.setElementText(cell, value || '', true); return cell; } }; + +Resources.ServiceWorkerCacheView.RequestView = class extends UI.VBox { + /** + * @param {!SDK.NetworkRequest} request + */ + constructor(request) { + super(); + + this._tabbedPane = new UI.TabbedPane(); + this._tabbedPane.addEventListener(UI.TabbedPane.Events.TabSelected, this._tabSelected, this); + this._resourceViewTabSetting = Common.settings.createSetting('cacheStorageViewTab', 'preview'); + + this._tabbedPane.appendTab('headers', Common.UIString('Headers'), new Network.RequestHeadersView(request)); + this._tabbedPane.appendTab('preview', Common.UIString('Preview'), new Network.RequestPreviewView(request)); + this._tabbedPane.show(this.element); + } + + /** + * @override + */ + wasShown() { + super.wasShown(); + this._selectTab(); + } + + /** + * @param {string=} tabId + */ + _selectTab(tabId) { + if (!tabId) + tabId = this._resourceViewTabSetting.get(); + if (!this._tabbedPane.selectTab(tabId)) + this._tabbedPane.selectTab('headers'); + } + + _tabSelected(event) { + if (!event.data.isUserGesture) + return; + this._resourceViewTabSetting.set(event.data.tabId); + } +};
diff --git a/third_party/WebKit/Source/devtools/front_end/resources/module.json b/third_party/WebKit/Source/devtools/front_end/resources/module.json index f1ce7dfa..49a4afa 100644 --- a/third_party/WebKit/Source/devtools/front_end/resources/module.json +++ b/third_party/WebKit/Source/devtools/front_end/resources/module.json
@@ -24,7 +24,8 @@ "components", "object_ui", "perf_ui", - "mobile_throttling" + "mobile_throttling", + "network" ], "scripts": [ "ApplicationCacheModel.js",
diff --git a/third_party/WebKit/Source/devtools/front_end/sdk/NetworkRequest.js b/third_party/WebKit/Source/devtools/front_end/sdk/NetworkRequest.js index f77d6924..f5e2c7ca 100644 --- a/third_party/WebKit/Source/devtools/front_end/sdk/NetworkRequest.js +++ b/third_party/WebKit/Source/devtools/front_end/sdk/NetworkRequest.js
@@ -897,16 +897,19 @@ contentData() { if (this._contentData) return this._contentData; - this._contentData = SDK.NetworkManager.requestContentData(this); + if (this._contentDataProvider) + this._contentData = this._contentDataProvider(); + else + this._contentData = SDK.NetworkManager.requestContentData(this); return this._contentData; } /** - * @param {!SDK.NetworkRequest.ContentData} data + * @param {function():!Promise<!SDK.NetworkRequest.ContentData>} dataProvider */ - setContentData(data) { + setContentDataProvider(dataProvider) { console.assert(!this._contentData, 'contentData can only be set once.'); - this._contentData = Promise.resolve(data); + this._contentDataProvider = dataProvider; } /**
diff --git a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineFlameChartDataProvider.js b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineFlameChartDataProvider.js index 411d6a7..4eab933 100644 --- a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineFlameChartDataProvider.js +++ b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineFlameChartDataProvider.js
@@ -339,9 +339,10 @@ var flowEventsEnabled = Runtime.experiments.isEnabled('timelineFlowEvents'); var blackboxingEnabled = !isExtension && Runtime.experiments.isEnabled('blackboxJSFramesOnTimeline'); var maxStackDepth = 0; + var markerEventsFilter = Timeline.TimelineUIUtils.paintEventsFilter(); for (var i = 0; i < events.length; ++i) { var e = events[i]; - if (!isExtension && TimelineModel.TimelineModel.isMarkerEvent(e)) { + if (!isExtension && TimelineModel.TimelineModel.isMarkerEvent(e) && markerEventsFilter.accept(e)) { this._markers.push(new Timeline.TimelineFlameChartMarker( e.startTime, e.startTime - this._model.minimumRecordTime(), Timeline.TimelineUIUtils.markerStyleForEvent(e))); @@ -956,9 +957,7 @@ * @return {boolean} */ _isVisible(event) { - return this._filters.every(function(filter) { - return filter.accept(event); - }); + return this._filters.every(filter => filter.accept(event)); } /**
diff --git a/third_party/WebKit/Source/devtools/front_end/timeline/TimelinePanel.js b/third_party/WebKit/Source/devtools/front_end/timeline/TimelinePanel.js index 6b4ef7e..7047745d 100644 --- a/third_party/WebKit/Source/devtools/front_end/timeline/TimelinePanel.js +++ b/third_party/WebKit/Source/devtools/front_end/timeline/TimelinePanel.js
@@ -69,8 +69,6 @@ this._filters.push(Timeline.TimelineUIUtils.visibleEventsFilter()); this._filters.push(new TimelineModel.ExcludeTopLevelFilter()); } - if (!Runtime.experiments.isEnabled('timelinePaintTimingMarkers')) - this._filters.push(Timeline.TimelineUIUtils.paintEventsFilter()); /** @type {?Timeline.PerformanceModel} */ this._performanceModel = null; @@ -846,9 +844,12 @@ var markers = new Map(); var recordTypes = TimelineModel.TimelineModel.RecordType; var zeroTime = timelineModel.minimumRecordTime(); + var filter = Timeline.TimelineUIUtils.paintEventsFilter(); for (var event of timelineModel.eventDividers()) { if (event.name === recordTypes.TimeStamp || event.name === recordTypes.ConsoleTime) continue; + if (!filter.accept(event)) + continue; markers.set(event.startTime, Timeline.TimelineUIUtils.createEventDivider(event, zeroTime)); } this._overviewPane.setMarkers(markers);
diff --git a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineUIUtils.js b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineUIUtils.js index 6bb5bbd..1e6b3c7 100644 --- a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineUIUtils.js +++ b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineUIUtils.js
@@ -1471,7 +1471,10 @@ */ static paintEventsFilter() { var recordTypes = TimelineModel.TimelineModel.RecordType; - return new TimelineModel.TimelineInvisibleEventsFilter([recordTypes.MarkFMP, recordTypes.MarkFMPCandidate]); + return new TimelineModel.TimelineInvisibleEventsFilter( + !Runtime.experiments.isEnabled('timelinePaintTimingMarkers') ? + [recordTypes.MarkFMP, recordTypes.MarkFMPCandidate] : + []); } /**
diff --git a/third_party/WebKit/Source/modules/cachestorage/InspectorCacheStorageAgent.cpp b/third_party/WebKit/Source/modules/cachestorage/InspectorCacheStorageAgent.cpp index 87da598..8dac57f 100644 --- a/third_party/WebKit/Source/modules/cachestorage/InspectorCacheStorageAgent.cpp +++ b/third_party/WebKit/Source/modules/cachestorage/InspectorCacheStorageAgent.cpp
@@ -17,6 +17,7 @@ #include "platform/SharedBuffer.h" #include "platform/blob/BlobData.h" #include "platform/heap/Handle.h" +#include "platform/network/HTTPHeaderMap.h" #include "platform/weborigin/KURL.h" #include "platform/weborigin/SecurityOrigin.h" #include "platform/wtf/Functional.h" @@ -205,8 +206,12 @@ struct RequestResponse { String request_url; + String request_method; + HTTPHeaderMap request_headers; + int response_status; + String response_status_text; double response_time; - Vector<std::pair<String, String>> headers; + HTTPHeaderMap response_headers; }; class ResponsesAccumulator : public RefCounted<ResponsesAccumulator> { @@ -226,12 +231,14 @@ DCHECK_GT(num_responses_left_, 0); RequestResponse& request_response = responses_.at(responses_.size() - num_responses_left_); + request_response.request_url = request.Url().GetString(); + request_response.request_method = request.Method(); + request_response.request_headers = request.Headers(); + request_response.response_status = response.Status(); + request_response.response_status_text = response.StatusText(); request_response.response_time = response.ResponseTime().ToDoubleT(); - for (const auto& header : response.GetHeaderKeys()) { - request_response.headers.push_back( - std::make_pair(header, response.GetHeader(header))); - } + request_response.response_headers = response.Headers(); if (--num_responses_left_ != 0) return; @@ -251,18 +258,17 @@ } std::unique_ptr<Array<DataEntry>> array = Array<DataEntry>::create(); for (const auto& request_response : responses_) { - std::unique_ptr<Array<Header>> headers = Array<Header>::create(); - for (const auto& header : request_response.headers) { - headers->addItem(Header::create() - .setName(header.first) - .setValue(header.second) - .build()); - } std::unique_ptr<DataEntry> entry = DataEntry::create() .setRequestURL(request_response.request_url) + .setRequestMethod(request_response.request_method) + .setRequestHeaders( + SerializeHeaders(request_response.request_headers)) + .setResponseStatus(request_response.response_status) + .setResponseStatusText(request_response.response_status_text) .setResponseTime(request_response.response_time) - .setResponseHeaders(std::move(headers)) + .setResponseHeaders( + SerializeHeaders(request_response.response_headers)) .build(); array->addItem(std::move(entry)); } @@ -273,6 +279,18 @@ callback_->sendFailure(error); } + std::unique_ptr<Array<Header>> SerializeHeaders( + const HTTPHeaderMap& headers) { + std::unique_ptr<Array<Header>> result = Array<Header>::create(); + for (HTTPHeaderMap::const_iterator it = headers.begin(), + end = headers.end(); + it != end; ++it) { + result->addItem( + Header::create().setName(it->key).setValue(it->value).build()); + } + return result; + } + private: DataRequestParams params_; int num_responses_left_;
diff --git a/third_party/WebKit/Source/modules/vr/NavigatorVR.cpp b/third_party/WebKit/Source/modules/vr/NavigatorVR.cpp index c966856..e13b967 100644 --- a/third_party/WebKit/Source/modules/vr/NavigatorVR.cpp +++ b/third_party/WebKit/Source/modules/vr/NavigatorVR.cpp
@@ -18,6 +18,7 @@ #include "modules/vr/VRDisplay.h" #include "modules/vr/VRGetDevicesCallback.h" #include "modules/vr/VRPose.h" +#include "platform/feature_policy/FeaturePolicy.h" #include "platform/wtf/PtrUtil.h" #include "public/platform/Platform.h" @@ -72,6 +73,23 @@ return promise; } + LocalFrame* frame = GetDocument()->GetFrame(); + // TODO(bshe): Add different error string for cases when promise is rejected. + if (!frame) { + RejectNavigatorDetached(resolver); + return promise; + } + if (IsSupportedInFeaturePolicy(WebFeaturePolicyFeature::kWebVr)) { + if (!frame->IsFeatureEnabled(WebFeaturePolicyFeature::kWebVr)) { + RejectNavigatorDetached(resolver); + return promise; + } + } else if (!frame->HasReceivedUserGesture() && + frame->IsCrossOriginSubframe()) { + RejectNavigatorDetached(resolver); + return promise; + } + UseCounter::Count(*GetDocument(), WebFeature::kVRGetDisplays); ExecutionContext* execution_context = ExecutionContext::From(script_state); if (!execution_context->IsSecureContext())
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioWorkletGlobalScope.cpp b/third_party/WebKit/Source/modules/webaudio/AudioWorkletGlobalScope.cpp index 358d129..ecbdd70 100644 --- a/third_party/WebKit/Source/modules/webaudio/AudioWorkletGlobalScope.cpp +++ b/third_party/WebKit/Source/modules/webaudio/AudioWorkletGlobalScope.cpp
@@ -11,6 +11,7 @@ #include "bindings/core/v8/WorkerOrWorkletScriptController.h" #include "bindings/modules/v8/V8AudioParamDescriptor.h" #include "core/dom/ExceptionCode.h" +#include "modules/webaudio/CrossThreadAudioWorkletProcessorInfo.h" #include "modules/webaudio/AudioBuffer.h" #include "modules/webaudio/AudioParamDescriptor.h" #include "modules/webaudio/AudioWorkletProcessor.h" @@ -208,6 +209,23 @@ return processor_definition_map_.at(name); } +unsigned AudioWorkletGlobalScope::NumberOfRegisteredDefinitions() { + return processor_definition_map_.size(); +} + +std::unique_ptr<Vector<CrossThreadAudioWorkletProcessorInfo>> +AudioWorkletGlobalScope::WorkletProcessorInfoListForSynchronization() { + auto processor_info_list = + WTF::MakeUnique<Vector<CrossThreadAudioWorkletProcessorInfo>>(); + for (auto definition_entry : processor_definition_map_) { + if (!definition_entry.value->IsSynchronized()) { + definition_entry.value->MarkAsSynchronized(); + processor_info_list->emplace_back(*definition_entry.value); + } + } + return processor_info_list; +} + DEFINE_TRACE(AudioWorkletGlobalScope) { visitor->Trace(processor_definition_map_); visitor->Trace(processor_instances_);
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioWorkletGlobalScope.h b/third_party/WebKit/Source/modules/webaudio/AudioWorkletGlobalScope.h index 9023bef..b32f2d4 100644 --- a/third_party/WebKit/Source/modules/webaudio/AudioWorkletGlobalScope.h +++ b/third_party/WebKit/Source/modules/webaudio/AudioWorkletGlobalScope.h
@@ -9,6 +9,7 @@ #include "core/dom/ExecutionContext.h" #include "core/workers/ThreadedWorkletGlobalScope.h" #include "modules/ModulesExport.h" +#include "modules/webaudio/AudioParamDescriptor.h" #include "platform/bindings/ScriptWrappable.h" namespace blink { @@ -16,6 +17,7 @@ class AudioBuffer; class AudioWorkletProcessor; class AudioWorkletProcessorDefinition; +class CrossThreadAudioWorkletProcessorInfo; class ExceptionState; // This is constructed and destroyed on a worker thread, and all methods also @@ -50,6 +52,11 @@ AudioWorkletProcessorDefinition* FindDefinition(const String& name); + unsigned NumberOfRegisteredDefinitions(); + + std::unique_ptr<Vector<CrossThreadAudioWorkletProcessorInfo>> + WorkletProcessorInfoListForSynchronization(); + DECLARE_TRACE(); DECLARE_TRACE_WRAPPERS();
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioWorkletMessagingProxy.cpp b/third_party/WebKit/Source/modules/webaudio/AudioWorkletMessagingProxy.cpp index f9d23c1..64893c1 100644 --- a/third_party/WebKit/Source/modules/webaudio/AudioWorkletMessagingProxy.cpp +++ b/third_party/WebKit/Source/modules/webaudio/AudioWorkletMessagingProxy.cpp
@@ -4,6 +4,7 @@ #include "modules/webaudio/AudioWorkletMessagingProxy.h" +#include "modules/webaudio/CrossThreadAudioWorkletProcessorInfo.h" #include "modules/webaudio/AudioWorkletObjectProxy.h" #include "modules/webaudio/AudioWorkletThread.h" @@ -16,18 +17,32 @@ AudioWorkletMessagingProxy::~AudioWorkletMessagingProxy() {} -void AudioWorkletMessagingProxy::SynchronizeWorkletData() { +void AudioWorkletMessagingProxy::SynchronizeWorkletProcessorInfoList( + std::unique_ptr<Vector<CrossThreadAudioWorkletProcessorInfo>> info_list) { DCHECK(IsMainThread()); - // TODO(crbug.com/755566): the argument will be a set of a node name and - // parameter descriptors. Use the information to update the copy in - // AudioWorkletMessagingProxy. + for (auto& processor_info : *info_list) { + processor_info_map_.insert(processor_info.Name(), + processor_info.ParamInfoList()); + } +} + +bool AudioWorkletMessagingProxy::IsProcessorRegistered( + const String& name) const { + return processor_info_map_.Contains(name); +} + +const Vector<CrossThreadAudioParamInfo> +AudioWorkletMessagingProxy::GetParamInfoListForProcessor( + const String& name) const { + DCHECK(IsProcessorRegistered(name)); + return processor_info_map_.at(name); } std::unique_ptr<ThreadedWorkletObjectProxy> - AudioWorkletMessagingProxy::CreateObjectProxy( - ThreadedWorkletMessagingProxy* messaging_proxy, - ParentFrameTaskRunners* parent_frame_task_runners) { +AudioWorkletMessagingProxy::CreateObjectProxy( + ThreadedWorkletMessagingProxy* messaging_proxy, + ParentFrameTaskRunners* parent_frame_task_runners) { return WTF::MakeUnique<AudioWorkletObjectProxy>( static_cast<AudioWorkletMessagingProxy*>(messaging_proxy), parent_frame_task_runners);
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioWorkletMessagingProxy.h b/third_party/WebKit/Source/modules/webaudio/AudioWorkletMessagingProxy.h index 216f208..b20d4d5c5 100644 --- a/third_party/WebKit/Source/modules/webaudio/AudioWorkletMessagingProxy.h +++ b/third_party/WebKit/Source/modules/webaudio/AudioWorkletMessagingProxy.h
@@ -10,6 +10,8 @@ namespace blink { +class CrossThreadAudioParamInfo; +class CrossThreadAudioWorkletProcessorInfo; class ExecutionContext; class WorkerThread; @@ -20,9 +22,20 @@ public: AudioWorkletMessagingProxy(ExecutionContext*, WorkerClients*); - // Invoked by AudioWorkletObjectProxy to synchronize the information from - // AudioWorkletGlobalScope after the script code evaluation. - void SynchronizeWorkletData(); + // Invoked by AudioWorkletObjectProxy on AudioWorkletThread to fetch the + // information from AudioWorkletGlobalScope to AudioWorkletMessagingProxy + // after the script code evaluation. It copies the information about newly + // added AudioWorkletProcessor since the previous synchronization. (e.g. + // processor name and AudioParam list) + void SynchronizeWorkletProcessorInfoList( + std::unique_ptr<Vector<CrossThreadAudioWorkletProcessorInfo>>); + + // Returns true if the processor with given name is registered in + // AudioWorkletGlobalScope. + bool IsProcessorRegistered(const String& name) const; + + const Vector<CrossThreadAudioParamInfo> GetParamInfoListForProcessor( + const String& name) const; private: ~AudioWorkletMessagingProxy() override; @@ -33,6 +46,9 @@ ParentFrameTaskRunners*) override; std::unique_ptr<WorkerThread> CreateWorkerThread() override; + + // Each entry consists of processor name and associated AudioParam list. + HashMap<String, Vector<CrossThreadAudioParamInfo>> processor_info_map_; }; } // namespace blink
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioWorkletObjectProxy.cpp b/third_party/WebKit/Source/modules/webaudio/AudioWorkletObjectProxy.cpp index 5829a1e..479180db 100644 --- a/third_party/WebKit/Source/modules/webaudio/AudioWorkletObjectProxy.cpp +++ b/third_party/WebKit/Source/modules/webaudio/AudioWorkletObjectProxy.cpp
@@ -6,6 +6,7 @@ #include "core/workers/ThreadedWorkletMessagingProxy.h" #include "core/workers/WorkerThread.h" +#include "modules/webaudio/CrossThreadAudioWorkletProcessorInfo.h" #include "modules/webaudio/AudioWorkletGlobalScope.h" #include "modules/webaudio/AudioWorkletMessagingProxy.h" #include "platform/CrossThreadFunctional.h" @@ -26,15 +27,23 @@ void AudioWorkletObjectProxy::DidEvaluateModuleScript(bool success) { DCHECK(global_scope_); - // TODO(crbug.com/755566): Extract/build the information for synchronization - // and send it to the associated AudioWorkletMessagingProxy. Currently this - // is an empty cross-thread call for the future implementation. - GetParentFrameTaskRunners()->Get(TaskType::kUnthrottled) - ->PostTask( - BLINK_FROM_HERE, - CrossThreadBind( - &AudioWorkletMessagingProxy::SynchronizeWorkletData, - GetAudioWorkletMessagingProxyWeakPtr())); + + if (!success || global_scope_->NumberOfRegisteredDefinitions() == 0) + return; + + std::unique_ptr<Vector<CrossThreadAudioWorkletProcessorInfo>> + processor_info_list = + global_scope_->WorkletProcessorInfoListForSynchronization(); + + if (processor_info_list->size() == 0) + return; + + GetParentFrameTaskRunners()->Get(TaskType::kUnthrottled)->PostTask( + BLINK_FROM_HERE, + CrossThreadBind( + &AudioWorkletMessagingProxy::SynchronizeWorkletProcessorInfoList, + GetAudioWorkletMessagingProxyWeakPtr(), + WTF::Passed(std::move(processor_info_list)))); } void AudioWorkletObjectProxy::WillDestroyWorkerGlobalScope() {
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioWorkletProcessorDefinition.h b/third_party/WebKit/Source/modules/webaudio/AudioWorkletProcessorDefinition.h index bc08de3..d3f20f5 100644 --- a/third_party/WebKit/Source/modules/webaudio/AudioWorkletProcessorDefinition.h +++ b/third_party/WebKit/Source/modules/webaudio/AudioWorkletProcessorDefinition.h
@@ -41,6 +41,11 @@ const Vector<String> GetAudioParamDescriptorNames() const; const AudioParamDescriptor* GetAudioParamDescriptor(const String& key) const; + // Flag for data synchronization of definition between + // AudioWorkletMessagingProxy and AudioWorkletGlobalScope. + bool IsSynchronized() const { return is_synchronized_; } + void MarkAsSynchronized() { is_synchronized_ = true; } + DEFINE_INLINE_TRACE() { visitor->Trace(audio_param_descriptors_); }; DECLARE_TRACE_WRAPPERS(); @@ -52,6 +57,7 @@ v8::Local<v8::Function> process); const String name_; + bool is_synchronized_ = false; // The definition is per global scope. The active instance of // |AudioProcessorWorklet| should be passed into these to perform JS function.
diff --git a/third_party/WebKit/Source/modules/webaudio/BUILD.gn b/third_party/WebKit/Source/modules/webaudio/BUILD.gn index fe0f3da4..c487eb82 100644 --- a/third_party/WebKit/Source/modules/webaudio/BUILD.gn +++ b/third_party/WebKit/Source/modules/webaudio/BUILD.gn
@@ -72,6 +72,7 @@ "ConstantSourceNode.h", "ConvolverNode.cpp", "ConvolverNode.h", + "CrossThreadAudioWorkletProcessorInfo.h", "DefaultAudioDestinationNode.cpp", "DefaultAudioDestinationNode.h", "DeferredTaskHandler.cpp",
diff --git a/third_party/WebKit/Source/modules/webaudio/CrossThreadAudioWorkletProcessorInfo.h b/third_party/WebKit/Source/modules/webaudio/CrossThreadAudioWorkletProcessorInfo.h new file mode 100644 index 0000000..c556ff12 --- /dev/null +++ b/third_party/WebKit/Source/modules/webaudio/CrossThreadAudioWorkletProcessorInfo.h
@@ -0,0 +1,68 @@ +// 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 CrossThreadAudioWorkletProcessorInfo_h +#define CrossThreadAudioWorkletProcessorInfo_h + +#include "modules/webaudio/AudioParamDescriptor.h" +#include "modules/webaudio/AudioWorkletProcessorDefinition.h" + +namespace blink { + +// A class for shallow repackage of |AudioParamDescriptor|. This is created only +// when requested when the synchronization between AudioWorkletMessagingProxy +// and AudioWorkletGlobalScope. +class CrossThreadAudioParamInfo { + DISALLOW_NEW_EXCEPT_PLACEMENT_NEW(); + + public: + explicit CrossThreadAudioParamInfo(const AudioParamDescriptor* descriptor) + : name_(descriptor->name().IsolatedCopy()), + default_value_(descriptor->defaultValue()), + max_value_(descriptor->maxValue()), + min_value_(descriptor->minValue()) {} + + const String& Name() const { return name_; } + float DefaultValue() const { return default_value_; } + float MaxValue() const { return max_value_; } + float MinValue() const { return min_value_; } + + private: + const String name_; + const float default_value_; + const float max_value_; + const float min_value_; +}; + +// A class for shallow repackage of |AudioWorkletProcessorDefinition|. This is +// created only when requested when the synchronization between +// AudioWorkletMessagingProxy and AudioWorkletGlobalScope. +class CrossThreadAudioWorkletProcessorInfo { + DISALLOW_NEW_EXCEPT_PLACEMENT_NEW(); + + public: + explicit CrossThreadAudioWorkletProcessorInfo( + const AudioWorkletProcessorDefinition& definition) + : name_(definition.GetName().IsolatedCopy()) { + // To avoid unnecessary reallocations of the vector. + param_info_list_.ReserveInitialCapacity( + definition.GetAudioParamDescriptorNames().size()); + + for (const String& name : definition.GetAudioParamDescriptorNames()) { + param_info_list_.emplace_back( + definition.GetAudioParamDescriptor(name)); + } + } + + const String& Name() const { return name_; } + Vector<CrossThreadAudioParamInfo> ParamInfoList() { return param_info_list_; } + + private: + const String name_; + Vector<CrossThreadAudioParamInfo> param_info_list_; +}; + +} // namespace blink + +#endif // CrossThreadAudioWorkletProcessorInfo_h
diff --git a/third_party/WebKit/Source/platform/feature_policy/FeaturePolicy.cpp b/third_party/WebKit/Source/platform/feature_policy/FeaturePolicy.cpp index ab9d06e7..2a0f48a 100644 --- a/third_party/WebKit/Source/platform/feature_policy/FeaturePolicy.cpp +++ b/third_party/WebKit/Source/platform/feature_policy/FeaturePolicy.cpp
@@ -1,4 +1,3 @@ -// Copyright 2016 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. @@ -31,6 +30,9 @@ // Old syntax only allows whitespace as valid delimiter. if (policy.Contains(';') || policy.Contains(',')) return false; + // An empty policy is also allowed in the new syntax. + if (policy.ContainsOnlyWhitespace()) + return false; // Old syntax does not support specifying wildcards / origins for any feature. if (policy.Contains("self") || policy.Contains("src") || policy.Contains("none") || policy.Contains("*")) { @@ -126,6 +128,9 @@ // "name value1 value2" or "name". Vector<String> tokens; entry.Split(' ', tokens); + // Empty policy. Skip. + if (tokens.IsEmpty()) + continue; if (!feature_names.Contains(tokens[0])) { if (messages) messages->push_back("Unrecognized feature: '" + tokens[0] + "'."); @@ -184,6 +189,7 @@ case WebFeaturePolicyFeature::kFullscreen: case WebFeaturePolicyFeature::kPayment: case WebFeaturePolicyFeature::kUsb: + case WebFeaturePolicyFeature::kWebVr: return true; case WebFeaturePolicyFeature::kVibrate: return RuntimeEnabledFeatures::FeaturePolicyExperimentalFeaturesEnabled(); @@ -208,6 +214,7 @@ default_feature_name_map.Set("geolocation", WebFeaturePolicyFeature::kGeolocation); default_feature_name_map.Set("midi", WebFeaturePolicyFeature::kMidiFeature); + default_feature_name_map.Set("vr", WebFeaturePolicyFeature::kWebVr); if (RuntimeEnabledFeatures::FeaturePolicyExperimentalFeaturesEnabled()) { default_feature_name_map.Set("vibrate", WebFeaturePolicyFeature::kVibrate);
diff --git a/third_party/WebKit/Source/platform/feature_policy/FeaturePolicyTest.cpp b/third_party/WebKit/Source/platform/feature_policy/FeaturePolicyTest.cpp index 785d8ca..2a86539e 100644 --- a/third_party/WebKit/Source/platform/feature_policy/FeaturePolicyTest.cpp +++ b/third_party/WebKit/Source/platform/feature_policy/FeaturePolicyTest.cpp
@@ -17,7 +17,13 @@ namespace { const char* const kValidPolicies[] = { - ";;", // Empty policies. + "", // An empty policy. + " ", // An empty policy. + ";;", // Empty policies. + ",,", // Empty policies. + " ; ;", // Empty policies. + " , ,", // Empty policies. + ",;,", // Empty policies. "vibrate 'none'", "vibrate 'self'", "vibrate 'src'", // Only valid for iframe allow attribute.
diff --git a/third_party/WebKit/Source/platform/graphics/ColorBehavior.cpp b/third_party/WebKit/Source/platform/graphics/ColorBehavior.cpp index 1a37e94..920568f 100644 --- a/third_party/WebKit/Source/platform/graphics/ColorBehavior.cpp +++ b/third_party/WebKit/Source/platform/graphics/ColorBehavior.cpp
@@ -15,10 +15,104 @@ namespace { +// This must match ICCProfileAnalyzeResult enum in histograms.xml. +enum ICCAnalyzeResult { + kICCExtractedMatrixAndAnalyticTrFn = 0, + kICCExtractedMatrixAndApproximatedTrFn = 1, + kICCFailedToApproximateTrFn = 2, + kICCFailedToExtractRawTrFn = 3, + kICCFailedToExtractMatrix = 4, + kICCFailedToParse = 5, + kICCProfileAnalyzeLast = kICCFailedToParse +}; + // The output device color space is global and shared across multiple threads. SpinLock g_target_color_space_lock; gfx::ColorSpace* g_target_color_space = nullptr; +ICCAnalyzeResult HistogramICCProfile(const gfx::ICCProfile& profile) { + std::vector<char> data = profile.GetData(); + sk_sp<SkICC> sk_icc = SkICC::Make(data.data(), data.size()); + if (!sk_icc) + return kICCFailedToParse; + + SkMatrix44 to_xyzd50; + bool to_xyzd50_result = sk_icc->toXYZD50(&to_xyzd50); + if (!to_xyzd50_result) + return kICCFailedToExtractMatrix; + + SkColorSpaceTransferFn fn; + bool is_numerical_transfer_fn_result = sk_icc->isNumericalTransferFn(&fn); + if (is_numerical_transfer_fn_result) + return kICCExtractedMatrixAndAnalyticTrFn; + + // Analyze the numerical approximation of table-based transfer functions. + // This should never fail in practice, because any profile from which a + // primary matrix was extracted will also provide raw transfer data. + SkICC::Tables tables; + bool raw_transfer_fn_result = sk_icc->rawTransferFnData(&tables); + DCHECK(raw_transfer_fn_result); + if (!raw_transfer_fn_result) + return kICCFailedToExtractRawTrFn; + + // Analyze the channels separately. + std::vector<float> x_combined; + std::vector<float> t_combined; + for (size_t c = 0; c < 3; ++c) { + SkICC::Channel* channels[3] = {&tables.fRed, &tables.fGreen, &tables.fBlue}; + SkICC::Channel* channel = channels[c]; + DCHECK_GE(channel->fCount, 2); + const float* data = reinterpret_cast<const float*>( + tables.fStorage->bytes() + channel->fOffset); + std::vector<float> x; + std::vector<float> t; + for (int i = 0; i < channel->fCount; ++i) { + float xi = i / (channel->fCount - 1.f); + float ti = data[i]; + x.push_back(xi); + t.push_back(ti); + x_combined.push_back(xi); + t_combined.push_back(ti); + } + + bool nonlinear_fit_converged = + gfx::SkApproximateTransferFn(x.data(), t.data(), x.size(), &fn); + UMA_HISTOGRAM_BOOLEAN("Blink.ColorSpace.Destination.NonlinearFitConverged", + nonlinear_fit_converged); + + // Record the accuracy of the fit, separating out by nonlinear and + // linear fits. + if (nonlinear_fit_converged) { + float max_error = 0.f; + for (size_t i = 0; i < x.size(); ++i) { + float fn_of_xi = gfx::SkTransferFnEval(fn, x[i]); + float error_at_xi = std::abs(t[i] - fn_of_xi); + max_error = std::max(max_error, error_at_xi); + } + UMA_HISTOGRAM_CUSTOM_COUNTS( + "Blink.ColorSpace.Destination.NonlinearFitError", + static_cast<int>(max_error * 255), 0, 127, 16); + } + } + + bool combined_nonlinear_fit_converged = gfx::SkApproximateTransferFn( + x_combined.data(), t_combined.data(), x_combined.size(), &fn); + if (!combined_nonlinear_fit_converged) + return kICCFailedToApproximateTrFn; + + float combined_max_error = 0.f; + for (size_t i = 0; i < x_combined.size(); ++i) { + float fn_of_xi = gfx::SkTransferFnEval(fn, x_combined[i]); + float error_at_xi = std::abs(t_combined[i] - fn_of_xi); + combined_max_error = std::max(combined_max_error, error_at_xi); + } + UMA_HISTOGRAM_CUSTOM_COUNTS( + "Blink.ColorSpace.Destination.NonlinearFitErrorCombined", + static_cast<int>(combined_max_error * 255), 0, 127, 16); + + return kICCExtractedMatrixAndApproximatedTrFn; +} + } // namespace // static @@ -33,9 +127,14 @@ return; // Attempt to convert the ICC profile to an SkColorSpace. - if (profile != gfx::ICCProfile()) + if (profile != gfx::ICCProfile()) { g_target_color_space = new gfx::ColorSpace(profile.GetColorSpace()); + ICCAnalyzeResult analyze_result = HistogramICCProfile(profile); + UMA_HISTOGRAM_ENUMERATION("Blink.ColorSpace.Destination.ICCResult", + analyze_result, kICCProfileAnalyzeLast); + } + // If we do not succeed, assume sRGB. if (!g_target_color_space) g_target_color_space = new gfx::ColorSpace(gfx::ColorSpace::CreateSRGB());
diff --git a/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager.cc b/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager.cc index 9e62623..e968433 100644 --- a/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager.cc +++ b/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager.cc
@@ -8,7 +8,6 @@ #include <set> #include "base/bind.h" -#include "base/metrics/histogram_macros.h" #include "base/trace_event/trace_event.h" #include "platform/scheduler/base/real_time_domain.h" #include "platform/scheduler/base/task_queue_impl.h" @@ -25,19 +24,6 @@ namespace scheduler { namespace { -const size_t kRecordRecordTaskDelayHistogramsEveryNTasks = 10; - -void RecordDelayedTaskLateness(base::TimeDelta lateness) { - UMA_HISTOGRAM_TIMES("RendererScheduler.TaskQueueManager.DelayedTaskLateness", - lateness); -} - -void RecordImmediateTaskQueueingDuration(base::TimeDelta duration) { - UMA_HISTOGRAM_TIMES( - "RendererScheduler.TaskQueueManager.ImmediateTaskQueueingDuration", - duration); -} - double MonotonicTimeInSeconds(base::TimeTicks time_ticks) { return (time_ticks - base::TimeTicks()).InSecondsF(); } @@ -51,14 +37,13 @@ return base::BindRepeating([](base::OnceClosure cb) { std::move(cb).Run(); }, base::Passed(&cb)); } -} +} // namespace TaskQueueManager::TaskQueueManager( scoped_refptr<TaskQueueManagerDelegate> delegate) : real_time_domain_(new RealTimeDomain()), delegate_(delegate), task_was_run_on_quiescence_monitored_queue_(false), - record_task_delay_histograms_(true), work_batch_size_(1), task_count_(0), currently_executing_task_queue_(nullptr), @@ -498,9 +483,6 @@ return ProcessTaskResult::DEFERRED; } - if (record_task_delay_histograms_) - MaybeRecordTaskDelayHistograms(pending_task, queue); - double task_start_time_sec = 0; base::TimeTicks task_start_time; TRACE_TASK_EXECUTION("TaskQueueManager::ProcessTaskFromWorkQueue", @@ -565,22 +547,6 @@ return ProcessTaskResult::EXECUTED; } -void TaskQueueManager::MaybeRecordTaskDelayHistograms( - const internal::TaskQueueImpl::Task& pending_task, - const internal::TaskQueueImpl* queue) { - if ((task_count_++ % kRecordRecordTaskDelayHistogramsEveryNTasks) != 0) - return; - - // Record delayed task lateness and immediate task queuing durations. - if (!pending_task.delayed_run_time.is_null()) { - RecordDelayedTaskLateness(delegate_->NowTicks() - - pending_task.delayed_run_time); - } else if (!pending_task.time_posted.is_null()) { - RecordImmediateTaskQueueingDuration(base::TimeTicks::Now() - - pending_task.time_posted); - } -} - bool TaskQueueManager::RunsTasksInCurrentSequence() const { return delegate_->RunsTasksInCurrentSequence(); } @@ -703,12 +669,6 @@ return !selector_.EnabledWorkQueuesEmpty(); } -void TaskQueueManager::SetRecordTaskDelayHistograms( - bool record_task_delay_histograms) { - DCHECK(main_thread_checker_.CalledOnValidThread()); - record_task_delay_histograms_ = record_task_delay_histograms; -} - void TaskQueueManager::SweepCanceledDelayedTasks() { std::map<TimeDomain*, base::TimeTicks> time_domain_now; for (const auto& queue : queues_) {
diff --git a/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager.h b/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager.h index 2bbf7095..d1e856b 100644 --- a/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager.h +++ b/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager.h
@@ -151,10 +151,6 @@ // Removes all canceled delayed tasks. void SweepCanceledDelayedTasks(); - // There is a small overhead to recording task delay histograms. If you don't - // need them, you can turn them off. - void SetRecordTaskDelayHistograms(bool record_task_delay_histograms); - protected: friend class LazyNow; friend class internal::TaskQueueImpl; @@ -287,10 +283,6 @@ base::Optional<NextTaskDelay> ComputeDelayTillNextTaskLocked( LazyNow* lazy_now); - void MaybeRecordTaskDelayHistograms( - const internal::TaskQueueImpl::Task& pending_task, - const internal::TaskQueueImpl* queue); - std::unique_ptr<base::trace_event::ConvertableToTraceFormat> AsValueWithSelectorResult(bool should_run, internal::WorkQueue* selected_work_queue) const; @@ -367,8 +359,6 @@ NextDelayedDoWork next_delayed_do_work_; - bool record_task_delay_histograms_; - int work_batch_size_; size_t task_count_;
diff --git a/third_party/WebKit/Source/platform/scheduler/child/scheduler_helper.cc b/third_party/WebKit/Source/platform/scheduler/child/scheduler_helper.cc index e134a23..d83d9a3 100644 --- a/third_party/WebKit/Source/platform/scheduler/child/scheduler_helper.cc +++ b/third_party/WebKit/Source/platform/scheduler/child/scheduler_helper.cc
@@ -42,15 +42,6 @@ task_queue_manager_delegate_->RestoreDefaultTaskRunner(); } -void SchedulerHelper::SetRecordTaskDelayHistograms( - bool record_task_delay_histograms) { - if (!task_queue_manager_) - return; - - task_queue_manager_->SetRecordTaskDelayHistograms( - record_task_delay_histograms); -} - size_t SchedulerHelper::GetNumberOfPendingTasks() const { return task_queue_manager_->GetNumberOfPendingTasks(); }
diff --git a/third_party/WebKit/Source/platform/scheduler/child/scheduler_helper.h b/third_party/WebKit/Source/platform/scheduler/child/scheduler_helper.h index 9a38772..7dae827 100644 --- a/third_party/WebKit/Source/platform/scheduler/child/scheduler_helper.h +++ b/third_party/WebKit/Source/platform/scheduler/child/scheduler_helper.h
@@ -25,10 +25,6 @@ scoped_refptr<SchedulerTqmDelegate> task_queue_manager_delegate); ~SchedulerHelper() override; - // There is a small overhead to recording task delay histograms, we may not - // wish to do this on all threads. - void SetRecordTaskDelayHistograms(bool record_task_delay_histograms); - // TaskQueueManager::Observer implementation: void OnTriedToExecuteBlockedTask() override; void OnBeginNestedRunLoop() override;
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/user_model.cc b/third_party/WebKit/Source/platform/scheduler/renderer/user_model.cc index 34ad48dd..8868026 100644 --- a/third_party/WebKit/Source/platform/scheduler/renderer/user_model.cc +++ b/third_party/WebKit/Source/platform/scheduler/renderer/user_model.cc
@@ -4,29 +4,9 @@ #include "platform/scheduler/renderer/user_model.h" -#include "base/metrics/histogram_macros.h" - namespace blink { namespace scheduler { -namespace { -// This enum is used to back a histogram, and should therefore be treated as -// append-only. -enum GesturePredictionResult { - GESTURE_OCCURED_WAS_PREDICTED = 0, - GESTURE_OCCURED_BUT_NOT_PREDICTED = 1, - GESTURE_PREDICTED_BUT_DID_NOT_OCCUR = 2, - GESTURE_PREDICTION_RESULT_COUNT = 3 -}; - -void RecordGesturePrediction(GesturePredictionResult result) { - UMA_HISTOGRAM_ENUMERATION( - "RendererScheduler.UserModel.GesturePredictedCorrectly", result, - GESTURE_PREDICTION_RESULT_COUNT); -} - -} // namespace - UserModel::UserModel() : pending_input_event_count_(0), is_gesture_active_(false), @@ -40,31 +20,9 @@ type == blink::WebInputEvent::kGestureScrollBegin || type == blink::WebInputEvent::kGesturePinchBegin) { // Only update stats once per gesture. - if (!is_gesture_active_) { + if (!is_gesture_active_) last_gesture_start_time_ = now; - RecordGesturePrediction(is_gesture_expected_ - ? GESTURE_OCCURED_WAS_PREDICTED - : GESTURE_OCCURED_BUT_NOT_PREDICTED); - - if (!last_reset_time_.is_null()) { - base::TimeDelta time_since_reset = now - last_reset_time_; - UMA_HISTOGRAM_MEDIUM_TIMES( - "RendererScheduler.UserModel.GestureStartTimeSinceModelReset", - time_since_reset); - } - - // If there has been a previous gesture, record a UMA metric for the time - // interval between then and now. - if (!last_continuous_gesture_time_.is_null()) { - base::TimeDelta time_since_last_gesture = - now - last_continuous_gesture_time_; - UMA_HISTOGRAM_MEDIUM_TIMES( - "RendererScheduler.UserModel.TimeBetweenGestures", - time_since_last_gesture); - } - } - is_gesture_active_ = true; } @@ -87,12 +45,6 @@ type == blink::WebInputEvent::kGesturePinchEnd || type == blink::WebInputEvent::kGestureFlingStart || type == blink::WebInputEvent::kTouchEnd) { - // Only update stats once per gesture. - if (is_gesture_active_) { - base::TimeDelta duration = now - last_gesture_start_time_; - UMA_HISTOGRAM_TIMES("RendererScheduler.UserModel.GestureDuration", - duration); - } is_gesture_active_ = false; } @@ -134,11 +86,6 @@ // gesture actually happened. if (!was_gesture_expected && is_gesture_expected_) last_gesture_expected_start_time_ = now; - - if (was_gesture_expected && !is_gesture_expected_ && - last_gesture_expected_start_time_ > last_gesture_start_time_) { - RecordGesturePrediction(GESTURE_PREDICTED_BUT_DID_NOT_OCCUR); - } return is_gesture_expected_; }
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/port_testcase.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/port_testcase.py index a5f8e1f..c220c1e 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/port_testcase.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/port_testcase.py
@@ -191,33 +191,43 @@ port = self.make_port() self.assertTrue(port.test_configuration()) - def test_get_crash_log(self): + def test_get_crash_log_all_none(self): port = self.make_port() - self.assertEqual(port._get_crash_log(None, None, None, None, newer_than=None), - (None, - 'crash log for <unknown process name> (pid <unknown>):\n' - 'STDOUT: <empty>\n' - 'STDERR: <empty>\n')) + stderr, details = port._get_crash_log(None, None, None, None, newer_than=None) + self.assertIsNone(stderr) + self.assertEqual(details, + 'crash log for <unknown process name> (pid <unknown>):\n' + 'STDOUT: <empty>\n' + 'STDERR: <empty>\n') - self.assertEqual(port._get_crash_log('foo', 1234, 'out bar\nout baz', 'err bar\nerr baz\n', newer_than=None), - ('err bar\nerr baz\n', - 'crash log for foo (pid 1234):\n' - 'STDOUT: out bar\n' - 'STDOUT: out baz\n' - 'STDERR: err bar\n' - 'STDERR: err baz\n')) + def test_get_crash_log_simple(self): + port = self.make_port() + stderr, details = port._get_crash_log('foo', 1234, 'out bar\nout baz', 'err bar\nerr baz\n', newer_than=None) + self.assertEqual(stderr, 'err bar\nerr baz\n') + self.assertEqual(details, + 'crash log for foo (pid 1234):\n' + 'STDOUT: out bar\n' + 'STDOUT: out baz\n' + 'STDERR: err bar\n' + 'STDERR: err baz\n') - self.assertEqual(port._get_crash_log('foo', 1234, 'foo\xa6bar', 'foo\xa6bar', newer_than=None), - ('foo\xa6bar', - u'crash log for foo (pid 1234):\n' - u'STDOUT: foo\ufffdbar\n' - u'STDERR: foo\ufffdbar\n')) + def test_get_crash_log_non_ascii(self): + port = self.make_port() + stderr, details = port._get_crash_log('foo', 1234, 'foo\xa6bar', 'foo\xa6bar', newer_than=None) + self.assertEqual(stderr, 'foo\xa6bar') + self.assertEqual(details, + u'crash log for foo (pid 1234):\n' + u'STDOUT: foo\ufffdbar\n' + u'STDERR: foo\ufffdbar\n') - self.assertEqual(port._get_crash_log('foo', 1234, 'foo\xa6bar', 'foo\xa6bar', newer_than=1.0), - ('foo\xa6bar', - u'crash log for foo (pid 1234):\n' - u'STDOUT: foo\ufffdbar\n' - u'STDERR: foo\ufffdbar\n')) + def test_get_crash_log_newer_than(self): + port = self.make_port() + stderr, details = port._get_crash_log('foo', 1234, 'foo\xa6bar', 'foo\xa6bar', newer_than=1.0) + self.assertEqual(stderr, 'foo\xa6bar') + self.assertEqual(details, + u'crash log for foo (pid 1234):\n' + u'STDOUT: foo\ufffdbar\n' + u'STDERR: foo\ufffdbar\n') def test_expectations_files(self): port = self.make_port()
diff --git a/third_party/WebKit/public/platform/WebFeaturePolicyFeature.h b/third_party/WebKit/public/platform/WebFeaturePolicyFeature.h index 2c271ba5..b67f918 100644 --- a/third_party/WebKit/public/platform/WebFeaturePolicyFeature.h +++ b/third_party/WebKit/public/platform/WebFeaturePolicyFeature.h
@@ -47,7 +47,9 @@ kUsb, // Controls access to AOM event listeners. kAccessibilityEvents, - LAST_FEATURE = kAccessibilityEvents + // Controls use of WebVR API. + kWebVr, + LAST_FEATURE = kWebVr }; } // namespace blink
diff --git a/third_party/android_support_test_runner/BUILD.gn b/third_party/android_support_test_runner/BUILD.gn index 1f0a6e8b..7383d4b 100644 --- a/third_party/android_support_test_runner/BUILD.gn +++ b/third_party/android_support_test_runner/BUILD.gn
@@ -19,5 +19,6 @@ } android_aar_prebuilt("rules_java") { + testonly = true aar_path = "lib/rules-0.5.aar" }
diff --git a/third_party/bazel/desugar/BUILD.gn b/third_party/bazel/desugar/BUILD.gn index bff746ab..6d9df28f 100644 --- a/third_party/bazel/desugar/BUILD.gn +++ b/third_party/bazel/desugar/BUILD.gn
@@ -8,4 +8,5 @@ java_prebuilt("desugar_runtime_java") { supports_android = true jar_path = "Desugar-runtime.jar" + no_build_hooks = true }
diff --git a/tools/gn/docs/reference.md b/tools/gn/docs/reference.md index 2d7a0c0a7..981b6f4 100644 --- a/tools/gn/docs/reference.md +++ b/tools/gn/docs/reference.md
@@ -215,7 +215,7 @@ tries really hard to always write something to the output JSON and convey errors that way rather than via return codes. ``` -### <a name="args"></a>**gn args <out_dir> [\--list] [\--short] [\--args]** +### <a name="args"></a>**gn args <out_dir> [\--list] [\--short] [\--args] [\--overrides-only]** ``` See also "gn help buildargs" for a more high-level overview of how @@ -240,7 +240,7 @@ Note: you can edit the build args manually by editing the file "args.gn" in the build directory and then running "gn gen <out_dir>". - gn args <out_dir> --list[=<exact_arg>] [--short] + gn args <out_dir> --list[=<exact_arg>] [--short] [--overrides-only] Lists all build arguments available in the current configuration, or, if an exact_arg is specified for the list flag, just that one build argument. @@ -251,6 +251,10 @@ If --short is specified, only the names and current values will be printed. + + If --overrides-only is specified, only the names and current values of + arguments that have been overridden (i.e. non-default arguments) will + be printed. Overrides come from the <out_dir>/args.gn file and //.gn ``` #### **Examples** @@ -263,6 +267,9 @@ Prints all arguments with their default values for the out/Debug build. + gn args out/Debug --list --short --overrides-only + Prints overridden arguments for the out/Debug build. + gn args out/Debug --list=target_cpu Prints information about the "target_cpu" argument for the " "out/Debug @@ -6090,13 +6097,6 @@ itself). ``` -#### **Shared libraries** - -``` - The results of shared_library targets are runtime dependencies, unless the - targets are depended upon only through action/action_foreach. -``` - #### **Multiple outputs** ``` @@ -6242,3 +6242,4 @@ * [-v: Verbose logging.](#-v) * [--version: Prints the GN version number and exits.](#--version) ``` +
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 4ee8bdad..3e3cbab 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -19933,14 +19933,6 @@ <int value="3" label="Failed to extract transfer function"/> <int value="4" label="Failed to extract primary matrix"/> <int value="5" label="Failed to parse"/> - <int value="6" label="Parsed, but failed to extract SkColorSpace"/> - <int value="7" - label="Parsed and extracteed SkColorSpace, but failed to create - SkColorSpaceXform to this space"/> - <int value="8" - label="Converged to an insufficiently accurate approximation of - transfer function"/> - <int value="9" label="Extracted an sRGB profile directly"/> </enum> <enum name="IceCandidatePairTypes">
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 0df2901..1f8e391 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -64941,6 +64941,9 @@ <histogram name="RendererScheduler.TaskQueueManager.DelayedTaskLateness" units="ms"> + <obsolete> + Removed from code 2017-08. + </obsolete> <owner>alexclarke@chromium.org</owner> <summary> The delta between when a delayed task was scheduled to run and when the @@ -64952,6 +64955,9 @@ <histogram name="RendererScheduler.TaskQueueManager.ImmediateTaskQueueingDuration" units="ms"> + <obsolete> + Removed from code 2017-08. + </obsolete> <owner>alexclarke@chromium.org</owner> <summary> The queueing duration for non-delayed tasks posted to the RendererScheduler. @@ -64995,18 +65001,27 @@ </histogram> <histogram name="RendererScheduler.UserModel.GestureDuration" units="ms"> + <obsolete> + Removed from code 2017-08. + </obsolete> <owner>alexclarke@chromium.org</owner> <summary>Duration of gestures (scrolls and pinches).</summary> </histogram> <histogram name="RendererScheduler.UserModel.GesturePredictedCorrectly" units="GesturePredictionResult"> + <obsolete> + Removed from code 2017-08. + </obsolete> <owner>alexclarke@chromium.org</owner> <summary>Whether a user gesture was predicted correctly.</summary> </histogram> <histogram name="RendererScheduler.UserModel.GestureStartTimeSinceModelReset" units="ms"> + <obsolete> + Removed from code 2017-08. + </obsolete> <owner>alexclarke@chromium.org</owner> <summary> Time between when the UserModel was last reset (which happens on navigation) @@ -65015,6 +65030,9 @@ </histogram> <histogram name="RendererScheduler.UserModel.TimeBetweenGestures" units="ms"> + <obsolete> + Removed from code 2017-08. + </obsolete> <owner>alexclarke@chromium.org</owner> <summary>Time between subsequent gestures (scrolls and pinches).</summary> </histogram>
diff --git a/tools/perf/benchmark.csv b/tools/perf/benchmark.csv index d60397d..7e5cff0 100644 --- a/tools/perf/benchmark.csv +++ b/tools/perf/benchmark.csv
@@ -46,8 +46,6 @@ octane,"bmeurer@chromium.org, mvstanton@chromium.org", oortonline,ulan@chromium.org, oortonline_tbmv2,ulan@chromium.org, -page_cycler_v2.basic_oopif,nasko@chromium.org, -page_cycler_v2_site_isolation.basic_oopif,nasko@chromium.org, performance_browser_tests,miu@chromium.org, power.idle_platform,, power.steady_state,,
diff --git a/tools/perf/benchmarks/oopif.py b/tools/perf/benchmarks/oopif.py deleted file mode 100644 index 71b2090e..0000000 --- a/tools/perf/benchmarks/oopif.py +++ /dev/null
@@ -1,81 +0,0 @@ -# Copyright 2016 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. - -# TODO(rnephew): Migrate to loading benchmark harness. -from core import perf_benchmark -import page_sets - -from benchmarks import loading_metrics_category -from telemetry import benchmark -from telemetry import story -from telemetry.page import cache_temperature -from telemetry.web_perf import timeline_based_measurement - -class _OopifBase(perf_benchmark.PerfBenchmark): - options = {'pageset_repeat': 2} - - def CreateCoreTimelineBasedMeasurementOptions(self): - tbm_options = timeline_based_measurement.Options() - loading_metrics_category.AugmentOptionsForLoadingMetrics(tbm_options) - return tbm_options - - @classmethod - def ShouldDisable(cls, possible_browser): - # crbug.com/619254 - if possible_browser.browser_type == 'reference': - return True - - # crbug.com/616781 - if (cls.IsSvelte(possible_browser) or - possible_browser.platform.GetDeviceTypeName() == 'Nexus 5X' or - possible_browser.platform.GetDeviceTypeName() == 'AOSP on BullHead'): - return True - - return False - - -@benchmark.Owner(emails=['nasko@chromium.org']) -class PageCyclerV2BasicOopifIsolated(_OopifBase): - """ A benchmark measuring performance of out-of-process iframes. """ - page_set = page_sets.OopifBasicPageSet - SUPPORTED_PLATFORMS = [story.expectations.ALL_DESKTOP] - - @classmethod - def Name(cls): - return 'page_cycler_v2_site_isolation.basic_oopif' - - def SetExtraBrowserOptions(self, options): - options.AppendExtraBrowserArgs(['--site-per-process']) - - def CreateStorySet(self, options): - return page_sets.OopifBasicPageSet(cache_temperatures=[ - cache_temperature.PCV1_COLD, cache_temperature.PCV1_WARM]) - - def GetExpectations(self): - class StoryExpectations(story.expectations.StoryExpectations): - def SetExpectations(self): - pass - return StoryExpectations() - - -@benchmark.Owner(emails=['nasko@chromium.org']) -class PageCyclerV2BasicOopif(_OopifBase): - """ A benchmark measuring performance of the out-of-process iframes page - set, without running in out-of-process iframes mode.. """ - page_set = page_sets.OopifBasicPageSet - SUPPORTED_PLATFORMS = [story.expectations.ALL_DESKTOP] - - @classmethod - def Name(cls): - return 'page_cycler_v2.basic_oopif' - - def CreateStorySet(self, options): - return page_sets.OopifBasicPageSet(cache_temperatures=[ - cache_temperature.PCV1_COLD, cache_temperature.PCV1_WARM]) - - def GetExpectations(self): - class StoryExpectations(story.expectations.StoryExpectations): - def SetExpectations(self): - pass - return StoryExpectations()
diff --git a/tools/perf/page_sets/data/oopif_basic.json b/tools/perf/page_sets/data/oopif_basic.json deleted file mode 100644 index 05307367..0000000 --- a/tools/perf/page_sets/data/oopif_basic.json +++ /dev/null
@@ -1,27 +0,0 @@ -{ - "archives": { - "http://arstechnica.com/": { - "DEFAULT": "oopif_basic_000.wpr" - }, - "http://booking.com": { - "DEFAULT": "oopif_basic_000.wpr" - }, - "http://www.cnn.com": { - "DEFAULT": "oopif_basic_000.wpr" - }, - "http://www.ebay.com": { - "DEFAULT": "oopif_basic_000.wpr" - }, - "http://www.fifa.com/": { - "DEFAULT": "oopif_basic_000.wpr" - }, - "http://www.nationalgeographic.com/": { - "DEFAULT": "oopif_basic_000.wpr" - }, - "http://www.rei.com/": { - "DEFAULT": "oopif_basic_000.wpr" - } - }, - "description": "Describes the Web Page Replay archives for a story set. Don't edit by hand! Use record_wpr for updating.", - "platform_specific": true -} \ No newline at end of file
diff --git a/tools/perf/page_sets/data/oopif_basic_000.wpr.sha1 b/tools/perf/page_sets/data/oopif_basic_000.wpr.sha1 deleted file mode 100644 index 8316337..0000000 --- a/tools/perf/page_sets/data/oopif_basic_000.wpr.sha1 +++ /dev/null
@@ -1 +0,0 @@ -4403d9d9a4878d07df2d22b82c2c2939c007eb8b \ No newline at end of file
diff --git a/tools/perf/page_sets/data/simple_mobile_sites.json b/tools/perf/page_sets/data/simple_mobile_sites.json index 529e3bf8..bc34d83 100644 --- a/tools/perf/page_sets/data/simple_mobile_sites.json +++ b/tools/perf/page_sets/data/simple_mobile_sites.json
@@ -1,25 +1,25 @@ { "archives": { "http://m.nytimes.com/": { - "DEFAULT": "simple_mobile_sites_002.wpr" + "DEFAULT": "simple_mobile_sites_002.wprgo" }, "http://m.us.wsj.com/": { - "DEFAULT": "simple_mobile_sites_002.wpr" + "DEFAULT": "simple_mobile_sites_002.wprgo" }, "http://www.apple.com/mac/": { - "DEFAULT": "simple_mobile_sites_002.wpr" + "DEFAULT": "simple_mobile_sites_002.wprgo" }, "http://www.ebay.co.uk/": { - "DEFAULT": "simple_mobile_sites_002.wpr" + "DEFAULT": "simple_mobile_sites_002.wprgo" }, "http://www.nyc.gov": { - "DEFAULT": "simple_mobile_sites_002.wpr" + "DEFAULT": "simple_mobile_sites_002.wprgo" }, "https://www.flickr.com/": { - "DEFAULT": "simple_mobile_sites_002.wpr" + "DEFAULT": "simple_mobile_sites_002.wprgo" }, "https://www.yahoo.com/": { - "DEFAULT": "simple_mobile_sites_002.wpr" + "DEFAULT": "simple_mobile_sites_002.wprgo" } }, "description": "Describes the Web Page Replay archives for a story set. Don't edit by hand! Use record_wpr for updating.",
diff --git a/tools/perf/page_sets/data/simple_mobile_sites_002.wpr.sha1 b/tools/perf/page_sets/data/simple_mobile_sites_002.wpr.sha1 deleted file mode 100644 index a9a38d4..0000000 --- a/tools/perf/page_sets/data/simple_mobile_sites_002.wpr.sha1 +++ /dev/null
@@ -1 +0,0 @@ -74b7f3166ef59c887988b21a39ff722ec621b1d4 \ No newline at end of file
diff --git a/tools/perf/page_sets/data/simple_mobile_sites_002.wprgo.sha1 b/tools/perf/page_sets/data/simple_mobile_sites_002.wprgo.sha1 new file mode 100644 index 0000000..0ff89ff --- /dev/null +++ b/tools/perf/page_sets/data/simple_mobile_sites_002.wprgo.sha1
@@ -0,0 +1 @@ +f485f5b4b805ddb196b69d4d14ce74e5868a9041 \ No newline at end of file
diff --git a/tools/perf/page_sets/oopif_basic_page_set.py b/tools/perf/page_sets/oopif_basic_page_set.py deleted file mode 100644 index 6aa886e..0000000 --- a/tools/perf/page_sets/oopif_basic_page_set.py +++ /dev/null
@@ -1,39 +0,0 @@ -# Copyright 2015 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. -from telemetry.page import cache_temperature as cache_temperature_module -from telemetry.page import page -from telemetry import story - -class OopifBasicPageSet(story.StorySet): - """ Basic set of pages used to measure performance of out-of-process - iframes. - """ - - def __init__(self, cache_temperatures=None): - super(OopifBasicPageSet, self).__init__( - archive_data_file='data/oopif_basic.json', - cloud_storage_bucket=story.PARTNER_BUCKET) - if cache_temperatures is None: - cache_temperatures = [cache_temperature_module.ANY] - - urls = [ - 'http://www.cnn.com', - 'http://www.ebay.com', - 'http://booking.com', - # Disabled because it causes flaky runs https://crbug.com/522870 - #'http://www.rei.com/', - 'http://www.fifa.com/', - # Disabled because it is flaky on Windows and Android - #'http://arstechnica.com/', - 'http://www.nationalgeographic.com/', - # Cross-site heavy! Enable them once they render without crashing. - #'http://www.nba.com/', - #'http://www.phonearena.com/', - #'http://slickdeals.net/', - #'http://www.163.com/', - ] - - for url in urls: - for temp in cache_temperatures: - self.AddStory(page.Page(url, self, cache_temperature=temp, name=url))
diff --git a/ui/aura/local/window_port_local.cc b/ui/aura/local/window_port_local.cc index f44680e..fc60d26d 100644 --- a/ui/aura/local/window_port_local.cc +++ b/ui/aura/local/window_port_local.cc
@@ -149,6 +149,10 @@ return local_surface_id_; } +viz::FrameSinkId WindowPortLocal::GetFrameSinkId() const { + return frame_sink_id_; +} + void WindowPortLocal::OnWindowAddedToRootWindow() { if (frame_sink_id_.is_valid()) window_->layer()->GetCompositor()->AddFrameSink(frame_sink_id_);
diff --git a/ui/aura/local/window_port_local.h b/ui/aura/local/window_port_local.h index cdaf21b1..68a29a2 100644 --- a/ui/aura/local/window_port_local.h +++ b/ui/aura/local/window_port_local.h
@@ -48,6 +48,7 @@ viz::SurfaceId GetSurfaceId() const override; void AllocateLocalSurfaceId() override; const viz::LocalSurfaceId& GetLocalSurfaceId() override; + viz::FrameSinkId GetFrameSinkId() const override; void OnWindowAddedToRootWindow() override; void OnWillRemoveWindowFromRootWindow() override; void OnEventTargetingPolicyChanged() override;
diff --git a/ui/aura/mus/DEPS b/ui/aura/mus/DEPS index cf9f8fc..1f379237 100644 --- a/ui/aura/mus/DEPS +++ b/ui/aura/mus/DEPS
@@ -13,9 +13,6 @@ "+mojo/public/cpp/system/platform_handle.h", "+services/ui/common/accelerator_util.h", "+services/ui/common/task_runner_test_base.h", - "+services/ui/public/cpp/gpu", - "+services/ui/public/cpp/property_type_converters.h", - "+services/ui/public/cpp/raster_thread_helper.h", - "+services/ui/public/cpp/client_layer_tree_frame_sink.h", + "+services/ui/public", "+ui/gl/gl_bindings.h", ]
diff --git a/ui/aura/mus/hit_test_data_provider_aura.cc b/ui/aura/mus/hit_test_data_provider_aura.cc index 078d113..db915077 100644 --- a/ui/aura/mus/hit_test_data_provider_aura.cc +++ b/ui/aura/mus/hit_test_data_provider_aura.cc
@@ -5,24 +5,23 @@ #include "ui/aura/mus/hit_test_data_provider_aura.h" #include "base/containers/adapters.h" -#include "ui/aura/mus/window_port_mus.h" +#include "services/ui/public/interfaces/window_tree_constants.mojom.h" #include "ui/aura/window.h" #include "ui/aura/window_targeter.h" namespace { -viz::mojom::HitTestRegionPtr CreateHitTestRegion( - const aura::WindowPortMus* window_port, - uint32_t flags, - const gfx::Rect& rect) { - const ui::Layer* layer = window_port->window()->layer(); +viz::mojom::HitTestRegionPtr CreateHitTestRegion(const aura::Window* window, + uint32_t flags, + const gfx::Rect& rect) { + const ui::Layer* layer = window->layer(); DCHECK(layer); auto hit_test_region = viz::mojom::HitTestRegion::New(); - DCHECK(window_port->GetFrameSinkId().is_valid()); - hit_test_region->frame_sink_id = window_port->GetFrameSinkId(); + DCHECK(window->GetFrameSinkId().is_valid()); + hit_test_region->frame_sink_id = window->GetFrameSinkId(); if (layer->GetPrimarySurfaceInfo()) { - DCHECK(window_port->GetFrameSinkId() == + DCHECK(window->GetFrameSinkId() == layer->GetPrimarySurfaceInfo()->id().frame_sink_id()); hit_test_region->local_surface_id = layer->GetPrimarySurfaceInfo()->id().local_surface_id(); @@ -83,7 +82,6 @@ gfx::Rect rect_mouse(child->bounds()); gfx::Rect rect_touch; bool touch_and_mouse_are_same = true; - const WindowPortMus* window_port = WindowPortMus::Get(child); uint32_t flags = child->layer()->GetPrimarySurfaceInfo() ? viz::mojom::kHitTestChildSurface : viz::mojom::kHitTestMine; @@ -107,7 +105,7 @@ if (rect.IsEmpty()) continue; hit_test_region_list->regions.push_back(CreateHitTestRegion( - window_port, + child, flags | viz::mojom::kHitTestMouse | viz::mojom::kHitTestTouch, rect)); } @@ -115,7 +113,7 @@ // The |child| has possibly same mouse and touch hit-test areas. if (!rect_mouse.IsEmpty()) { hit_test_region_list->regions.push_back(CreateHitTestRegion( - window_port, + child, flags | (touch_and_mouse_are_same ? (viz::mojom::kHitTestMouse | viz::mojom::kHitTestTouch) : viz::mojom::kHitTestMouse), @@ -123,7 +121,7 @@ } if (!touch_and_mouse_are_same && !rect_touch.IsEmpty()) { hit_test_region_list->regions.push_back(CreateHitTestRegion( - window_port, flags | viz::mojom::kHitTestTouch, rect_touch)); + child, flags | viz::mojom::kHitTestTouch, rect_touch)); } } }
diff --git a/ui/aura/mus/hit_test_data_provider_aura_unittest.cc b/ui/aura/mus/hit_test_data_provider_aura_unittest.cc index b73c30f..5f8611fe 100644 --- a/ui/aura/mus/hit_test_data_provider_aura_unittest.cc +++ b/ui/aura/mus/hit_test_data_provider_aura_unittest.cc
@@ -6,7 +6,6 @@ #include "components/viz/client/hit_test_data_provider.h" #include "ui/aura/client/aura_constants.h" -#include "ui/aura/mus/window_mus.h" #include "ui/aura/mus/window_port_mus.h" #include "ui/aura/test/aura_mus_test_base.h" #include "ui/aura/window.h" @@ -113,6 +112,8 @@ protected: const viz::HitTestDataProvider* hit_test_data_provider() const { + // TODO(varkha): Find a way to get the HitTestDataProvider without depending + // on WindowPortMus WindowPortMus* port = WindowPortMus::Get(root_.get()); return port->local_layer_tree_frame_sink_->hit_test_data_provider(); } @@ -148,8 +149,7 @@ EXPECT_EQ(region->flags, viz::mojom::kHitTestMine | viz::mojom::kHitTestMouse | viz::mojom::kHitTestTouch); - EXPECT_EQ(region->frame_sink_id, - WindowPortMus::Get(expected_order_1[i])->GetFrameSinkId()); + EXPECT_EQ(region->frame_sink_id, expected_order_1[i]->GetFrameSinkId()); EXPECT_EQ(region->rect.ToString(), expected_order_1[i]->bounds().ToString()); i++; @@ -168,8 +168,7 @@ EXPECT_EQ(region->flags, viz::mojom::kHitTestMine | viz::mojom::kHitTestMouse | viz::mojom::kHitTestTouch); - EXPECT_EQ(region->frame_sink_id, - WindowPortMus::Get(expected_order_2[i])->GetFrameSinkId()); + EXPECT_EQ(region->frame_sink_id, expected_order_2[i]->GetFrameSinkId()); EXPECT_EQ(region->rect.ToString(), expected_order_2[i]->bounds().ToString()); i++; @@ -201,8 +200,7 @@ ASSERT_EQ(hit_test_data->regions.size(), arraysize(expected_insets)); int i = 0; for (const auto& region : hit_test_data->regions) { - EXPECT_EQ(region->frame_sink_id, - WindowPortMus::Get(expected_windows[i])->GetFrameSinkId()); + EXPECT_EQ(region->frame_sink_id, expected_windows[i]->GetFrameSinkId()); EXPECT_EQ(region->flags, expected_flags[i]); gfx::Rect expected_bounds = expected_windows[i]->bounds(); expected_bounds.Inset(gfx::Insets(expected_insets[i])); @@ -242,8 +240,7 @@ ASSERT_EQ(hit_test_data->regions.size(), expected_bounds.size()); int i = 0; for (const auto& region : hit_test_data->regions) { - EXPECT_EQ(region->frame_sink_id, - WindowPortMus::Get(expected_windows[i])->GetFrameSinkId()); + EXPECT_EQ(region->frame_sink_id, expected_windows[i]->GetFrameSinkId()); EXPECT_EQ(region->flags, expected_flags); EXPECT_EQ(region->rect.ToString(), expected_bounds[i].ToString()); i++;
diff --git a/ui/aura/mus/window_port_mus.cc b/ui/aura/mus/window_port_mus.cc index 7b6223a3e..3b937f13 100644 --- a/ui/aura/mus/window_port_mus.cc +++ b/ui/aura/mus/window_port_mus.cc
@@ -64,12 +64,6 @@ return static_cast<WindowPortMus*>(WindowPort::Get(window)); } -viz::FrameSinkId WindowPortMus::GetFrameSinkId() const { - if (embed_frame_sink_id_.is_valid()) - return embed_frame_sink_id_; - return viz::FrameSinkId(0, server_id()); -} - void WindowPortMus::SetTextInputState(mojo::TextInputStatePtr state) { window_tree_client_->SetWindowTextInputState(this, std::move(state)); } @@ -134,6 +128,12 @@ return layer_tree_frame_sink; } +viz::FrameSinkId WindowPortMus::GetFrameSinkId() const { + if (embed_frame_sink_id_.is_valid()) + return embed_frame_sink_id_; + return viz::FrameSinkId(0, server_id()); +} + WindowPortMus::ServerChangeIdType WindowPortMus::ScheduleChange( const ServerChangeType type, const ServerChangeData& data) {
diff --git a/ui/aura/mus/window_port_mus.h b/ui/aura/mus/window_port_mus.h index 47cc985..b0d5d62 100644 --- a/ui/aura/mus/window_port_mus.h +++ b/ui/aura/mus/window_port_mus.h
@@ -66,10 +66,6 @@ return primary_surface_info_; } - // Returns either the FrameSinkId set by window server or its server_id with - // the client id part 0. - viz::FrameSinkId GetFrameSinkId() const; - void SetTextInputState(mojo::TextInputStatePtr state); void SetImeVisibility(bool visible, mojo::TextInputStatePtr state); @@ -97,6 +93,11 @@ scoped_refptr<viz::ContextProvider> context_provider, gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager); + // WindowPort: + // Returns either the FrameSinkId set by window server or its server_id with + // the client id part 0. + viz::FrameSinkId GetFrameSinkId() const override; + private: friend class WindowPortMusTestApi; friend class WindowTreeClient;
diff --git a/ui/aura/window.cc b/ui/aura/window.cc index 07409d9..e618ea8 100644 --- a/ui/aura/window.cc +++ b/ui/aura/window.cc
@@ -1026,6 +1026,10 @@ return port_->GetLocalSurfaceId(); } +viz::FrameSinkId Window::GetFrameSinkId() const { + return port_->GetFrameSinkId(); +} + void Window::OnPaintLayer(const ui::PaintContext& context) { Paint(context); }
diff --git a/ui/aura/window.h b/ui/aura/window.h index 62db430..15009ff 100644 --- a/ui/aura/window.h +++ b/ui/aura/window.h
@@ -328,6 +328,11 @@ // Gets the current viz::LocalSurfaceId. const viz::LocalSurfaceId& GetLocalSurfaceId() const; + // Returns the FrameSinkId. In LOCAL mode, this returns a valid FrameSinkId + // only if a LayerTreeFrameSink has been created. In MUS mode, this always + // return a valid FrameSinkId. + viz::FrameSinkId GetFrameSinkId() const; + protected: // Deletes (or removes if not owned by parent) all child windows. Intended for // use from the destructor.
diff --git a/ui/aura/window_port.h b/ui/aura/window_port.h index 5ab4d6c..47a6d22 100644 --- a/ui/aura/window_port.h +++ b/ui/aura/window_port.h
@@ -97,6 +97,9 @@ // factor. virtual const viz::LocalSurfaceId& GetLocalSurfaceId() = 0; + // This can return invalid FrameSinkId. + virtual viz::FrameSinkId GetFrameSinkId() const = 0; + virtual void OnWindowAddedToRootWindow() = 0; virtual void OnWillRemoveWindowFromRootWindow() = 0;
diff --git a/ui/aura/window_port_for_shutdown.cc b/ui/aura/window_port_for_shutdown.cc index 087f47e1..73fd7a9 100644 --- a/ui/aura/window_port_for_shutdown.cc +++ b/ui/aura/window_port_for_shutdown.cc
@@ -66,6 +66,10 @@ return local_surface_id_; } +viz::FrameSinkId WindowPortForShutdown::GetFrameSinkId() const { + return frame_sink_id_; +} + void WindowPortForShutdown::OnWindowAddedToRootWindow() {} void WindowPortForShutdown::OnWillRemoveWindowFromRootWindow() {}
diff --git a/ui/aura/window_port_for_shutdown.h b/ui/aura/window_port_for_shutdown.h index 8c94640..0807e61a 100644 --- a/ui/aura/window_port_for_shutdown.h +++ b/ui/aura/window_port_for_shutdown.h
@@ -41,12 +41,14 @@ viz::SurfaceId GetSurfaceId() const override; void AllocateLocalSurfaceId() override; const viz::LocalSurfaceId& GetLocalSurfaceId() override; + viz::FrameSinkId GetFrameSinkId() const override; void OnWindowAddedToRootWindow() override; void OnWillRemoveWindowFromRootWindow() override; void OnEventTargetingPolicyChanged() override; private: viz::LocalSurfaceId local_surface_id_; + viz::FrameSinkId frame_sink_id_; DISALLOW_COPY_AND_ASSIGN(WindowPortForShutdown); };
diff --git a/ui/display/mac/screen_mac.mm b/ui/display/mac/screen_mac.mm index da15115..11eca13 100644 --- a/ui/display/mac/screen_mac.mm +++ b/ui/display/mac/screen_mac.mm
@@ -90,10 +90,8 @@ base::FeatureList::IsEnabled(features::kColorCorrectRendering); if (base::mac::IsAtLeastOS10_12() && !color_correct_rendering_enabled) color_space = base::mac::GetSystemColorSpace(); - gfx::ICCProfile icc_profile = - gfx::ICCProfile::FromCGColorSpace(color_space); - icc_profile.HistogramDisplay(display.id()); - display.set_color_space(icc_profile.GetColorSpace()); + display.set_color_space( + gfx::ICCProfile::FromCGColorSpace(color_space).GetColorSpace()); } display.set_color_depth(NSBitsPerPixelFromDepth([screen depth])); display.set_depth_per_component(NSBitsPerSampleFromDepth([screen depth]));
diff --git a/ui/display/win/color_profile_reader.cc b/ui/display/win/color_profile_reader.cc index 2a61591..d1220cfd 100644 --- a/ui/display/win/color_profile_reader.cc +++ b/ui/display/win/color_profile_reader.cc
@@ -110,10 +110,9 @@ if (profile_data.empty()) { display_id_to_color_space_map_[display_id] = default_color_space_; } else { - gfx::ICCProfile icc_profile = - gfx::ICCProfile::FromData(profile_data.data(), profile_data.size()); - icc_profile.HistogramDisplay(display_id); - display_id_to_color_space_map_[display_id] = icc_profile.GetColorSpace(); + display_id_to_color_space_map_[display_id] = + gfx::ICCProfile::FromData(profile_data.data(), profile_data.size()) + .GetColorSpace(); } }
diff --git a/ui/gfx/icc_profile.cc b/ui/gfx/icc_profile.cc index 6067769..a982db5 100644 --- a/ui/gfx/icc_profile.cc +++ b/ui/gfx/icc_profile.cc
@@ -5,12 +5,10 @@ #include "ui/gfx/icc_profile.h" #include <list> -#include <set> #include "base/command_line.h" #include "base/containers/mru_cache.h" #include "base/lazy_instance.h" -#include "base/metrics/histogram_macros.h" #include "base/synchronization/lock.h" #include "third_party/skia/include/core/SkColorSpaceXform.h" #include "third_party/skia/include/core/SkICC.h" @@ -27,170 +25,32 @@ const uint64_t ICCProfile::test_id_a2b_only_ = 6; const uint64_t ICCProfile::test_id_overshoot_ = 7; -// A MRU cache of ICC profiles. The cache key is a uin64_t which a -// gfx::ColorSpace may use to refer back to an ICC profile in the cache. The -// data cached for each profile is the gfx::ICCProfile structure (which includes -// the associated gfx::ColorSpace approximations and SkColorSpace structures) -// and whether or not the ICC profile has been histogrammed. -class ICCProfileCache { - public: - // Allow keeping around a maximum of 16 cached ICC profiles. Beware that - // we will do a linear search thorugh currently-cached ICC profiles, - // when creating a new ICC profile. - static const size_t kMaxCachedICCProfiles = 16; - - ICCProfileCache() : id_to_icc_profile_mru_(kMaxCachedICCProfiles) {} - ~ICCProfileCache() {} - - // Add |icc_profile| to the cache. If |icc_profile| does not have an id set - // yet, assign an id to it. - void InsertAndSetIdIfNeeded(ICCProfile* icc_profile) { - base::AutoLock lock(lock_); - - if (FindByIdUnderLock(icc_profile->id_, icc_profile)) - return; - - if (FindByDataUnderLock(icc_profile->data_.data(), - icc_profile->data_.size(), icc_profile)) { - return; - } - - if (!icc_profile->id_) - icc_profile->id_ = next_unused_id_++; - - Entry entry; - entry.icc_profile = *icc_profile; - id_to_icc_profile_mru_.Put(icc_profile->id_, entry); - } - - // We maintain UMA histograms of display ICC profiles. Only histogram a - // display once for each |display_id| (because we will re-read the same - // ICC profile repeatedly when reading other display profiles, which will - // skew samples). Return whether or not we have histogrammed this profile - // for |display_id|. Ensure that all future calls will return true for - // |display_id|. - bool GetAndSetNeedsHistogram(uint64_t display_id, - const ICCProfile& icc_profile) { - base::AutoLock lock(lock_); - - auto found = id_to_icc_profile_mru_.Get(icc_profile.id_); - if (found != id_to_icc_profile_mru_.end()) - return false; - - std::set<int64_t>& histogrammed_display_ids = - found->second.histogrammed_display_ids; - if (histogrammed_display_ids.count(display_id)) - return false; - - histogrammed_display_ids.insert(display_id); - return true; - } - - // Move this ICC profile to the most recently used end of the cache, - // re-inserting if needed. - void TouchEntry(const ICCProfile& icc_profile) { - base::AutoLock lock(lock_); - - if (!icc_profile.id_) - return; - - // Look up the profile by id to move it to the front of the MRU. - auto found = id_to_icc_profile_mru_.Get(icc_profile.id_); - if (found != id_to_icc_profile_mru_.end()) - return; - - // If the entry was not found, insert it. - Entry entry; - entry.icc_profile = icc_profile; - id_to_icc_profile_mru_.Put(icc_profile.id_, entry); - } - - // Look up an ICC profile in the cache by its data (to ensure that the same - // data gets the same id every time). On success, return true and populate - // |icc_profile| with the associated profile. - bool FindByData(const void* data, size_t size, ICCProfile* icc_profile) { - base::AutoLock lock(lock_); - return FindByDataUnderLock(data, size, icc_profile); - } - - // Look up an ICC profile in the cache by its id. On success, return true and - // populate |icc_profile| with the associated profile. - bool FindById(uint64_t id, ICCProfile* icc_profile) { - base::AutoLock lock(lock_); - return FindByIdUnderLock(id, icc_profile); - } - - private: - struct Entry { - ICCProfile icc_profile; - - // The set of display ids which have have caused this ICC profile to be - // recorded in UMA histograms. Only record an ICC profile once per display - // id (since the same profile will be re-read repeatedly, e.g, when displays - // are resized). - std::set<int64_t> histogrammed_display_ids; - }; - - // Body for FindById, executed when the cache lock is already held. - bool FindByIdUnderLock(uint64_t id, ICCProfile* icc_profile) { - lock_.AssertAcquired(); - if (!id) - return false; - - auto found = id_to_icc_profile_mru_.Get(id); - if (found == id_to_icc_profile_mru_.end()) - return false; - - *icc_profile = found->second.icc_profile; - return true; - } - - // Body for FindByData, executed when the cache lock is already held. - bool FindByDataUnderLock(const void* data, - size_t size, - ICCProfile* icc_profile) { - lock_.AssertAcquired(); - if (size == 0) - return false; - - for (const auto& id_entry_pair : id_to_icc_profile_mru_) { - const ICCProfile& cached_profile = id_entry_pair.second.icc_profile; - const std::vector<char>& iter_data = cached_profile.data_; - if (iter_data.size() != size || memcmp(data, iter_data.data(), size)) - continue; - - *icc_profile = cached_profile; - id_to_icc_profile_mru_.Get(cached_profile.id_); - return true; - } - return false; - } - - // Start from-ICC-data IDs at the end of the hard-coded test id list above. - uint64_t next_unused_id_ = 10; - base::MRUCache<uint64_t, Entry> id_to_icc_profile_mru_; - - // Lock that must be held to access |id_to_icc_profile_mru_| and - // |next_unused_id_|. - base::Lock lock_; -}; - namespace { -static base::LazyInstance<ICCProfileCache>::DestructorAtExit g_cache = +// Allow keeping around a maximum of 8 cached ICC profiles. Beware that +// we will do a linear search thorugh currently-cached ICC profiles, +// when creating a new ICC profile. +const size_t kMaxCachedICCProfiles = 8; + +struct Cache { + Cache() : id_to_icc_profile_mru(kMaxCachedICCProfiles) {} + ~Cache() {} + + // Start from-ICC-data IDs at the end of the hard-coded test id list above. + uint64_t next_unused_id = 10; + base::MRUCache<uint64_t, ICCProfile> id_to_icc_profile_mru; + base::Lock lock; +}; +static base::LazyInstance<Cache>::DestructorAtExit g_cache = LAZY_INSTANCE_INITIALIZER; -} // namespace - -// static -ICCProfile::AnalyzeResult ICCProfile::ExtractColorSpaces( - const std::vector<char>& data, - gfx::ColorSpace* parametric_color_space, - float* parametric_tr_fn_max_error, - sk_sp<SkColorSpace>* useable_sk_color_space) { +void ExtractColorSpaces(const std::vector<char>& data, + gfx::ColorSpace* parametric_color_space, + bool* parametric_color_space_is_accurate, + sk_sp<SkColorSpace>* useable_sk_color_space) { // Initialize the output parameters as invalid. *parametric_color_space = gfx::ColorSpace(); - *parametric_tr_fn_max_error = 0; + *parametric_color_space_is_accurate = false; *useable_sk_color_space = nullptr; // Parse the profile and attempt to create a SkColorSpaceXform out of it. @@ -198,20 +58,20 @@ sk_sp<SkICC> sk_icc = SkICC::Make(data.data(), data.size()); if (!sk_icc) { DLOG(ERROR) << "Failed to parse ICC profile to SkICC."; - return kICCFailedToParse; + return; } sk_sp<SkColorSpace> sk_icc_color_space = SkColorSpace::MakeICC(data.data(), data.size()); if (!sk_icc_color_space) { DLOG(ERROR) << "Failed to parse ICC profile to SkColorSpace."; - return kICCFailedToExtractSkColorSpace; + return; } std::unique_ptr<SkColorSpaceXform> sk_color_space_xform = SkColorSpaceXform::New(sk_srgb_color_space.get(), sk_icc_color_space.get()); if (!sk_color_space_xform) { DLOG(ERROR) << "Parsed ICC profile but can't create SkColorSpaceXform."; - return kICCFailedToCreateXform; + return; } // Because this SkColorSpace can be used to construct a transform, mark it @@ -222,14 +82,15 @@ // If our SkColorSpace representation is sRGB then return that. if (SkColorSpace::Equals(sk_srgb_color_space.get(), sk_icc_color_space.get())) { - return kICCExtractedSRGBColorSpace; + *parametric_color_space_is_accurate = true; + return; } // A primary matrix is required for our parametric approximation. SkMatrix44 to_XYZD50_matrix; if (!sk_icc->toXYZD50(&to_XYZD50_matrix)) { DLOG(ERROR) << "Failed to extract ICC profile primary matrix."; - return kICCFailedToExtractMatrix; + return; } // Try to directly extract a numerical transfer function. @@ -237,7 +98,27 @@ if (sk_icc->isNumericalTransferFn(&exact_tr_fn)) { *parametric_color_space = gfx::ColorSpace::CreateCustom(to_XYZD50_matrix, exact_tr_fn); - return kICCExtractedMatrixAndAnalyticTrFn; + *parametric_color_space_is_accurate = true; + return; + } + + // If that fails, try to numerically approximate the transfer function. + SkColorSpaceTransferFn approx_tr_fn; + float approx_tr_fn_max_error = 0; + if (SkApproximateTransferFn(sk_icc, &approx_tr_fn_max_error, &approx_tr_fn)) { + const float kMaxError = 2.f / 256.f; + if (approx_tr_fn_max_error < kMaxError) { + *parametric_color_space = + gfx::ColorSpace::CreateCustom(to_XYZD50_matrix, approx_tr_fn); + *parametric_color_space_is_accurate = true; + return; + } else { + DLOG(ERROR) + << "Failed to accurately approximate transfer function, error: " + << 256.f * approx_tr_fn_max_error << "/256"; + } + } else { + DLOG(ERROR) << "Failed approximate transfer function."; } // If we fail to get a transfer function, use the sRGB transfer function, @@ -246,32 +127,10 @@ // SkColorSpace. *parametric_color_space = gfx::ColorSpace::CreateCustom( to_XYZD50_matrix, ColorSpace::TransferID::IEC61966_2_1); - - // Attempt to fit a parametric transfer function to the table data in the - // profile. - SkColorSpaceTransferFn approx_tr_fn; - if (!SkApproximateTransferFn(sk_icc, parametric_tr_fn_max_error, - &approx_tr_fn)) { - DLOG(ERROR) << "Failed approximate transfer function."; - return kICCFailedToConvergeToApproximateTrFn; - } - - // If this converged, but has too high error, use the sRGB transfer function - // from above. - const float kMaxError = 2.f / 256.f; - if (*parametric_tr_fn_max_error >= kMaxError) { - DLOG(ERROR) << "Failed to accurately approximate transfer function, error: " - << 256.f * (*parametric_tr_fn_max_error) << "/256"; - return kICCFailedToApproximateTrFnAccurately; - }; - - // If the error is sufficiently low, declare that the approximation is - // accurate. - *parametric_color_space = - gfx::ColorSpace::CreateCustom(to_XYZD50_matrix, approx_tr_fn); - return kICCExtractedMatrixAndApproximatedTrFn; } +} // namespace + ICCProfile::ICCProfile() = default; ICCProfile::ICCProfile(ICCProfile&& other) = default; ICCProfile::ICCProfile(const ICCProfile& other) = default; @@ -288,15 +147,7 @@ } bool ICCProfile::IsValid() const { - switch (analyze_result_) { - case kICCFailedToParse: - case kICCFailedToExtractSkColorSpace: - case kICCFailedToCreateXform: - return false; - default: - break; - } - return true; + return successfully_parsed_by_sk_icc_; } // static @@ -308,14 +159,30 @@ ICCProfile ICCProfile::FromDataWithId(const void* data, size_t size, uint64_t new_profile_id) { - ICCProfile icc_profile; - if (!size) - return icc_profile; + return ICCProfile(); + + const char* data_as_char = reinterpret_cast<const char*>(data); + { + // Linearly search the cached ICC profiles to find one with the same data. + // If it exists, re-use its id and touch it in the cache. + Cache& cache = g_cache.Get(); + base::AutoLock lock(cache.lock); + for (auto iter = cache.id_to_icc_profile_mru.begin(); + iter != cache.id_to_icc_profile_mru.end(); ++iter) { + const std::vector<char>& iter_data = iter->second.data_; + if (iter_data.size() != size || memcmp(data, iter_data.data(), size)) + continue; + auto found = cache.id_to_icc_profile_mru.Get(iter->second.id_); + return found->second; + } + if (!new_profile_id) + new_profile_id = cache.next_unused_id++; + } // Create a new cached id and add it to the cache. + ICCProfile icc_profile; icc_profile.id_ = new_profile_id; - const char* data_as_char = reinterpret_cast<const char*>(data); icc_profile.data_.insert(icc_profile.data_.begin(), data_as_char, data_as_char + size); icc_profile.ComputeColorSpaceAndCache(); @@ -336,91 +203,93 @@ } const ColorSpace& ICCProfile::GetColorSpace() const { - g_cache.Get().TouchEntry(*this); + // Move this ICC profile to the most recently used end of the cache, + // inserting if needed. + if (id_) { + Cache& cache = g_cache.Get(); + base::AutoLock lock(cache.lock); + auto found = cache.id_to_icc_profile_mru.Get(id_); + if (found == cache.id_to_icc_profile_mru.end()) + found = cache.id_to_icc_profile_mru.Put(id_, *this); + } return color_space_; } const ColorSpace& ICCProfile::GetParametricColorSpace() const { - g_cache.Get().TouchEntry(*this); + // Move this ICC profile to the most recently used end of the cache, + // inserting if needed. + if (id_) { + Cache& cache = g_cache.Get(); + base::AutoLock lock(cache.lock); + auto found = cache.id_to_icc_profile_mru.Get(id_); + if (found == cache.id_to_icc_profile_mru.end()) + found = cache.id_to_icc_profile_mru.Put(id_, *this); + } return parametric_color_space_; } // static bool ICCProfile::FromId(uint64_t id, ICCProfile* icc_profile) { - return g_cache.Get().FindById(id, icc_profile); + if (!id) + return false; + + Cache& cache = g_cache.Get(); + base::AutoLock lock(cache.lock); + + auto found = cache.id_to_icc_profile_mru.Get(id); + if (found == cache.id_to_icc_profile_mru.end()) + return false; + + *icc_profile = found->second; + return true; } void ICCProfile::ComputeColorSpaceAndCache() { - // Early out for empty entries. - if (data_.empty()) + if (!id_) return; - // If this id already exists in the cache, copy |this| from the cache entry. - if (g_cache.Get().FindById(id_, this)) - return; - - // If this data already exists in the cache, copy |this| from the cache entry. - if (g_cache.Get().FindByData(data_.data(), data_.size(), this)) - return; + // If this already exists in the cache, just update its |color_space_|. + { + Cache& cache = g_cache.Get(); + base::AutoLock lock(cache.lock); + auto found = cache.id_to_icc_profile_mru.Get(id_); + if (found != cache.id_to_icc_profile_mru.end()) { + color_space_ = found->second.color_space_; + parametric_color_space_ = found->second.parametric_color_space_; + successfully_parsed_by_sk_icc_ = + found->second.successfully_parsed_by_sk_icc_; + return; + } + } // Parse the ICC profile sk_sp<SkColorSpace> useable_sk_color_space; - analyze_result_ = - ExtractColorSpaces(data_, ¶metric_color_space_, - ¶metric_tr_fn_error_, &useable_sk_color_space); - switch (analyze_result_) { - case kICCExtractedSRGBColorSpace: - case kICCExtractedMatrixAndAnalyticTrFn: - case kICCExtractedMatrixAndApproximatedTrFn: - // Successfully and accurately extracted color space. - parametric_color_space_.icc_profile_id_ = id_; - color_space_ = parametric_color_space_; - break; - case kICCFailedToExtractRawTrFn: - case kICCFailedToExtractMatrix: - case kICCFailedToConvergeToApproximateTrFn: - case kICCFailedToApproximateTrFnAccurately: - // Successfully but extracted a color space, but it isn't accurate enough. - color_space_ = ColorSpace(ColorSpace::PrimaryID::ICC_BASED, - ColorSpace::TransferID::ICC_BASED); - color_space_.icc_profile_id_ = id_; - color_space_.icc_profile_sk_color_space_ = useable_sk_color_space; - break; - case kICCFailedToParse: - case kICCFailedToExtractSkColorSpace: - case kICCFailedToCreateXform: - // Can't even use this color space as a LUT. - DCHECK(!parametric_color_space_.IsValid()); - color_space_ = parametric_color_space_; - break; + bool parametric_color_space_is_accurate = false; + ExtractColorSpaces(data_, ¶metric_color_space_, + ¶metric_color_space_is_accurate, + &useable_sk_color_space); + if (parametric_color_space_is_accurate) { + successfully_parsed_by_sk_icc_ = true; + parametric_color_space_.icc_profile_id_ = id_; + color_space_ = parametric_color_space_; + } else if (useable_sk_color_space) { + successfully_parsed_by_sk_icc_ = true; + color_space_ = ColorSpace(ColorSpace::PrimaryID::ICC_BASED, + ColorSpace::TransferID::ICC_BASED); + color_space_.icc_profile_id_ = id_; + color_space_.icc_profile_sk_color_space_ = useable_sk_color_space; + } else { + successfully_parsed_by_sk_icc_ = false; + DCHECK(!color_space_.IsValid()); + color_space_ = parametric_color_space_; } // Add to the cache. - g_cache.Get().InsertAndSetIdIfNeeded(this); -} - -void ICCProfile::HistogramDisplay(int64_t display_id) const { - if (g_cache.Get().GetAndSetNeedsHistogram(display_id, *this)) - return; - - UMA_HISTOGRAM_ENUMERATION("Blink.ColorSpace.Destination.ICCResult", - analyze_result_, kICCProfileAnalyzeLast); - - // Add histograms for numerical approximation. - bool nonlinear_fit_converged = - analyze_result_ == kICCExtractedMatrixAndApproximatedTrFn || - analyze_result_ == kICCFailedToApproximateTrFnAccurately; - bool nonlinear_fit_did_not_converge = - analyze_result_ == kICCFailedToConvergeToApproximateTrFn; - if (nonlinear_fit_converged || nonlinear_fit_did_not_converge) { - UMA_HISTOGRAM_BOOLEAN("Blink.ColorSpace.Destination.NonlinearFitConverged", - nonlinear_fit_converged); - } - if (nonlinear_fit_converged) { - UMA_HISTOGRAM_CUSTOM_COUNTS( - "Blink.ColorSpace.Destination.NonlinearFitError", - static_cast<int>(parametric_tr_fn_error_ * 255), 0, 127, 16); + { + Cache& cache = g_cache.Get(); + base::AutoLock lock(cache.lock); + cache.id_to_icc_profile_mru.Put(id_, *this); } }
diff --git a/ui/gfx/icc_profile.h b/ui/gfx/icc_profile.h index 4049df8..03170ad 100644 --- a/ui/gfx/icc_profile.h +++ b/ui/gfx/icc_profile.h
@@ -23,8 +23,6 @@ namespace gfx { -class ICCProfileCache; - // Used to represent a full ICC profile, usually retrieved from a monitor. It // can be lossily compressed into a ColorSpace object. This structure should // only be sent from higher-privilege processes to lower-privilege processes, @@ -70,10 +68,6 @@ const std::vector<char>& GetData() const; - // Histogram how we this was approximated by a gfx::ColorSpace. Only - // histogram a given profile once per display. - void HistogramDisplay(int64_t display_id) const; - #if defined(OS_WIN) // This will read monitor ICC profiles from disk and cache the results for the // other functions to read. This should not be called on the UI or IO thread. @@ -82,22 +76,6 @@ #endif private: - // This must match ICCProfileAnalyzeResult enum in histograms.xml. - enum AnalyzeResult { - kICCExtractedMatrixAndAnalyticTrFn = 0, - kICCExtractedMatrixAndApproximatedTrFn = 1, - kICCFailedToConvergeToApproximateTrFn = 2, - kICCFailedToExtractRawTrFn = 3, - kICCFailedToExtractMatrix = 4, - kICCFailedToParse = 5, - kICCFailedToExtractSkColorSpace = 6, - kICCFailedToCreateXform = 7, - kICCFailedToApproximateTrFnAccurately = 8, - kICCExtractedSRGBColorSpace = 9, - kICCProfileAnalyzeLast = kICCExtractedSRGBColorSpace, - }; - - friend class ICCProfileCache; friend ICCProfile ICCProfileForTestingAdobeRGB(); friend ICCProfile ICCProfileForTestingColorSpin(); friend ICCProfile ICCProfileForTestingGenericRGB(); @@ -125,12 +103,6 @@ size_t size, uint64_t id); - static AnalyzeResult ExtractColorSpaces( - const std::vector<char>& data, - gfx::ColorSpace* parametric_color_space, - float* parametric_tr_fn_max_error, - sk_sp<SkColorSpace>* useable_sk_color_space); - void ComputeColorSpaceAndCache(); // This globally identifies this ICC profile. It is used to look up this ICC @@ -139,9 +111,6 @@ uint64_t id_ = 0; std::vector<char> data_; - // The result of attepting to extract a color space from the color profile. - AnalyzeResult analyze_result_ = kICCFailedToParse; - // |color_space| always links back to this ICC profile, and its SkColorSpace // is always equal to the SkColorSpace created from this ICCProfile. gfx::ColorSpace color_space_; @@ -150,10 +119,8 @@ // is accurate, and its SkColorSpace will always be parametrically created. gfx::ColorSpace parametric_color_space_; - // The L-infinity error of the parametric color space fit. This is undefined - // unless |analyze_result_| is kICCFailedToApproximateTrFnAccurately or - // kICCExtractedMatrixAndApproximatedTrFn. - float parametric_tr_fn_error_ = -1; + // This is set to true if SkICC successfully parsed this profile. + bool successfully_parsed_by_sk_icc_ = false; FRIEND_TEST_ALL_PREFIXES(SimpleColorSpace, BT709toSRGBICC); FRIEND_TEST_ALL_PREFIXES(SimpleColorSpace, GetColorSpace);
diff --git a/ui/ozone/platform/drm/BUILD.gn b/ui/ozone/platform/drm/BUILD.gn index 05f649d..732e2d52 100644 --- a/ui/ozone/platform/drm/BUILD.gn +++ b/ui/ozone/platform/drm/BUILD.gn
@@ -16,8 +16,6 @@ "common/drm_util.h", "common/scoped_drm_types.cc", "common/scoped_drm_types.h", - "cursor_proxy_mojo.cc", - "cursor_proxy_mojo.h", "gpu/crtc_controller.cc", "gpu/crtc_controller.h", "gpu/drm_buffer.cc", @@ -103,8 +101,10 @@ "host/drm_window_host_manager.h", "host/gpu_thread_adapter.h", "host/gpu_thread_observer.h", - "mus_thread_proxy.cc", - "mus_thread_proxy.h", + "host/host_cursor_proxy.cc", + "host/host_cursor_proxy.h", + "host/host_drm_device.cc", + "host/host_drm_device.h", "ozone_platform_gbm.cc", "ozone_platform_gbm.h", ]
diff --git a/ui/ozone/platform/drm/gpu/drm_thread.cc b/ui/ozone/platform/drm/gpu/drm_thread.cc index ad50d98..f8d5daa 100644 --- a/ui/ozone/platform/drm/gpu/drm_thread.cc +++ b/ui/ozone/platform/drm/gpu/drm_thread.cc
@@ -315,6 +315,14 @@ correction_matrix); } +void DrmThread::StartDrmDevice(StartDrmDeviceCallback callback) { + // We currently assume that |Init| always succeeds so return true to indicate + // when the DRM thread has completed launching. In particular, the invocation + // of the callback in the client triggers the invocation of DRM thread + // readiness observers. + std::move(callback).Run(true); +} + // DrmThread requires a BindingSet instead of a simple Binding because it will // be used from multiple threads in multiple processes. void DrmThread::AddBindingCursorDevice(
diff --git a/ui/ozone/platform/drm/gpu/drm_thread.h b/ui/ozone/platform/drm/gpu/drm_thread.h index c8e0cdc..973409b 100644 --- a/ui/ozone/platform/drm/gpu/drm_thread.h +++ b/ui/ozone/platform/drm/gpu/drm_thread.h
@@ -64,7 +64,8 @@ void Start(); - // Must be called on the DRM thread. + // Must be called on the DRM thread. All methods for use from the GPU thread. + // DrmThreadProxy (on GPU)thread) is the client for these methods. void CreateBuffer(gfx::AcceleratedWidget widget, const gfx::Size& size, gfx::BufferFormat format, @@ -76,9 +77,12 @@ std::vector<base::ScopedFD>&& fds, const std::vector<gfx::NativePixmapPlane>& planes, scoped_refptr<GbmBuffer>* buffer); - void GetScanoutFormats(gfx::AcceleratedWidget widget, std::vector<gfx::BufferFormat>* scanout_formats); + void AddBindingCursorDevice(ozone::mojom::DeviceCursorRequest request); + void AddBindingDrmDevice(ozone::mojom::DrmDeviceRequest request); + + // DrmWindowProxy (on GPU thread) is the client for these methods. void SchedulePageFlip(gfx::AcceleratedWidget widget, const std::vector<OverlayPlane>& planes, SwapCompletionOnceCallback callback); @@ -86,37 +90,27 @@ gfx::AcceleratedWidget widget, const gfx::VSyncProvider::UpdateVSyncCallback& callback); + // ozone::mojom::DrmDevice + void StartDrmDevice(StartDrmDeviceCallback callback) override; void CreateWindow(const gfx::AcceleratedWidget& widget) override; void DestroyWindow(const gfx::AcceleratedWidget& widget) override; void SetWindowBounds(const gfx::AcceleratedWidget& widget, const gfx::Rect& bounds) override; - void SetCursor(const gfx::AcceleratedWidget& widget, - const std::vector<SkBitmap>& bitmaps, - const gfx::Point& location, - int32_t frame_delay_ms) override; - void MoveCursor(const gfx::AcceleratedWidget& widget, - const gfx::Point& location) override; - void CheckOverlayCapabilities( - const gfx::AcceleratedWidget& widget, - const OverlaySurfaceCandidateList& overlays, - base::OnceCallback<void(const gfx::AcceleratedWidget&, - const OverlaySurfaceCandidateList&, - const OverlayStatusList&)> callback) override; + void TakeDisplayControl(base::OnceCallback<void(bool)> callback) override; + void RelinquishDisplayControl( + base::OnceCallback<void(bool)> callback) override; void RefreshNativeDisplays( base::OnceCallback<void(MovableDisplaySnapshots)> callback) override; + void AddGraphicsDevice(const base::FilePath& path, base::File file) override; + void RemoveGraphicsDevice(const base::FilePath& path) override; + void DisableNativeDisplay( + int64_t id, + base::OnceCallback<void(int64_t, bool)> callback) override; void ConfigureNativeDisplay( int64_t id, std::unique_ptr<display::DisplayMode> mode, const gfx::Point& origin, base::OnceCallback<void(int64_t, bool)> callback) override; - void DisableNativeDisplay( - int64_t id, - base::OnceCallback<void(int64_t, bool)> callback) override; - void TakeDisplayControl(base::OnceCallback<void(bool)> callback) override; - void RelinquishDisplayControl( - base::OnceCallback<void(bool)> callback) override; - void AddGraphicsDevice(const base::FilePath& path, base::File file) override; - void RemoveGraphicsDevice(const base::FilePath& path) override; void GetHDCPState(int64_t display_id, base::OnceCallback<void(int64_t, bool, display::HDCPState)> callback) override; @@ -128,16 +122,24 @@ const std::vector<display::GammaRampRGBEntry>& degamma_lut, const std::vector<display::GammaRampRGBEntry>& gamma_lut, const std::vector<float>& correction_matrix) override; + void CheckOverlayCapabilities( + const gfx::AcceleratedWidget& widget, + const OverlaySurfaceCandidateList& overlays, + base::OnceCallback<void(const gfx::AcceleratedWidget&, + const OverlaySurfaceCandidateList&, + const OverlayStatusList&)> callback) override; + + // ozone::mojom::DeviceCursor + void SetCursor(const gfx::AcceleratedWidget& widget, + const std::vector<SkBitmap>& bitmaps, + const gfx::Point& location, + int32_t frame_delay_ms) override; + void MoveCursor(const gfx::AcceleratedWidget& widget, + const gfx::Point& location) override; // base::Thread: void Init() override; - // Mojo support for DeviceCursorRequest. - void AddBindingCursorDevice(ozone::mojom::DeviceCursorRequest request); - - // Mojo support for DrmDevice requests. - void AddBindingDrmDevice(ozone::mojom::DrmDeviceRequest request); - private: std::unique_ptr<DrmDeviceManager> device_manager_; std::unique_ptr<ScanoutBufferGenerator> buffer_generator_;
diff --git a/ui/ozone/platform/drm/gpu/drm_thread_proxy.cc b/ui/ozone/platform/drm/gpu/drm_thread_proxy.cc index c3814f1..8d15f12 100644 --- a/ui/ozone/platform/drm/gpu/drm_thread_proxy.cc +++ b/ui/ozone/platform/drm/gpu/drm_thread_proxy.cc
@@ -22,6 +22,10 @@ messaging_proxy->SetDrmThread(&drm_thread_); } +void DrmThreadProxy::StartDrmThread() { + drm_thread_.Start(); +} + std::unique_ptr<DrmWindowProxy> DrmThreadProxy::CreateDrmWindowProxy( gfx::AcceleratedWidget widget) { return base::MakeUnique<DrmWindowProxy>(widget, &drm_thread_);
diff --git a/ui/ozone/platform/drm/gpu/drm_thread_proxy.h b/ui/ozone/platform/drm/gpu/drm_thread_proxy.h index af59604..c8a0b4b 100644 --- a/ui/ozone/platform/drm/gpu/drm_thread_proxy.h +++ b/ui/ozone/platform/drm/gpu/drm_thread_proxy.h
@@ -27,6 +27,8 @@ void BindThreadIntoMessagingProxy(InterThreadMessagingProxy* messaging_proxy); + void StartDrmThread(); + std::unique_ptr<DrmWindowProxy> CreateDrmWindowProxy( gfx::AcceleratedWidget widget);
diff --git a/ui/ozone/platform/drm/cursor_proxy_mojo.cc b/ui/ozone/platform/drm/host/host_cursor_proxy.cc similarity index 76% rename from ui/ozone/platform/drm/cursor_proxy_mojo.cc rename to ui/ozone/platform/drm/host/host_cursor_proxy.cc index c48ddca..ba5baeec 100644 --- a/ui/ozone/platform/drm/cursor_proxy_mojo.cc +++ b/ui/ozone/platform/drm/host/host_cursor_proxy.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 "ui/ozone/platform/drm/cursor_proxy_mojo.h" +#include "ui/ozone/platform/drm/host/host_cursor_proxy.h" #include "services/service_manager/public/cpp/connector.h" #include "services/ui/public/interfaces/constants.mojom.h" @@ -10,15 +10,15 @@ namespace ui { // We assume that this is invoked only on the UI thread. -CursorProxyMojo::CursorProxyMojo(service_manager::Connector* connector) +HostCursorProxy::HostCursorProxy(service_manager::Connector* connector) : connector_(connector->Clone()) { ui_thread_ref_ = base::PlatformThread::CurrentRef(); connector->BindInterface(ui::mojom::kServiceName, &main_cursor_ptr_); } -CursorProxyMojo::~CursorProxyMojo() {} +HostCursorProxy::~HostCursorProxy() {} -void CursorProxyMojo::CursorSet(gfx::AcceleratedWidget widget, +void HostCursorProxy::CursorSet(gfx::AcceleratedWidget widget, const std::vector<SkBitmap>& bitmaps, const gfx::Point& location, int frame_delay_ms) { @@ -30,7 +30,7 @@ } } -void CursorProxyMojo::Move(gfx::AcceleratedWidget widget, +void HostCursorProxy::Move(gfx::AcceleratedWidget widget, const gfx::Point& location) { InitializeOnEvdevIfNecessary(); if (ui_thread_ref_ == base::PlatformThread::CurrentRef()) { @@ -40,12 +40,12 @@ } } -// Evdev runs this method on starting. But if a CursorProxyMojo is created long +// Evdev runs this method on starting. But if a HostCursorProxy is created long // after Evdev has started (e.g. if the Viz process crashes (and the -// |CursorProxyMojo| self-destructs and then a new |CursorProxyMojo| is built +// |HostCursorProxy| self-destructs and then a new |HostCursorProxy| is built // when the GpuThread/DrmThread pair are once again running), we need to run it // on cursor motions. -void CursorProxyMojo::InitializeOnEvdevIfNecessary() { +void HostCursorProxy::InitializeOnEvdevIfNecessary() { if (ui_thread_ref_ != base::PlatformThread::CurrentRef()) { connector_->BindInterface(ui::mojom::kServiceName, &evdev_cursor_ptr_); }
diff --git a/ui/ozone/platform/drm/cursor_proxy_mojo.h b/ui/ozone/platform/drm/host/host_cursor_proxy.h similarity index 76% rename from ui/ozone/platform/drm/cursor_proxy_mojo.h rename to ui/ozone/platform/drm/host/host_cursor_proxy.h index e1bceff..42feece 100644 --- a/ui/ozone/platform/drm/cursor_proxy_mojo.h +++ b/ui/ozone/platform/drm/host/host_cursor_proxy.h
@@ -2,11 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef UI_OZONE_PLATFORM_DRM_CURSOR_PROXY_MOJO_H_ -#define UI_OZONE_PLATFORM_DRM_CURSOR_PROXY_MOJO_H_ +#ifndef UI_OZONE_PLATFORM_DRM_HOST_HOST_CURSOR_PROXY_H_ +#define UI_OZONE_PLATFORM_DRM_HOST_HOST_CURSOR_PROXY_H_ #include "ui/gfx/native_widget_types.h" -#include "ui/ozone/platform/drm/gpu/inter_thread_messaging_proxy.h" #include "ui/ozone/platform/drm/host/drm_cursor.h" #include "ui/ozone/public/interfaces/device_cursor.mojom.h" @@ -21,10 +20,10 @@ // pointer control via Mojo-style IPC. This code runs only in the mus-ws (i.e. // it's the client) and sends mouse pointer control messages to a less // priviledged process. -class CursorProxyMojo : public DrmCursorProxy { +class HostCursorProxy : public DrmCursorProxy { public: - explicit CursorProxyMojo(service_manager::Connector* connector); - ~CursorProxyMojo() override; + explicit HostCursorProxy(service_manager::Connector* connector); + ~HostCursorProxy() override; private: // DrmCursorProxy. @@ -42,9 +41,9 @@ ui::ozone::mojom::DeviceCursorPtr evdev_cursor_ptr_; base::PlatformThreadRef ui_thread_ref_; - DISALLOW_COPY_AND_ASSIGN(CursorProxyMojo); + DISALLOW_COPY_AND_ASSIGN(HostCursorProxy); }; } // namespace ui -#endif // UI_OZONE_PLATFORM_DRM_CURSOR_PROXY_MOJO_H_ +#endif // UI_OZONE_PLATFORM_DRM_HOST_HOST_CURSOR_PROXY_H_
diff --git a/ui/ozone/platform/drm/host/host_drm_device.cc b/ui/ozone/platform/drm/host/host_drm_device.cc new file mode 100644 index 0000000..628b3c2 --- /dev/null +++ b/ui/ozone/platform/drm/host/host_drm_device.cc
@@ -0,0 +1,348 @@ +// Copyright 2016 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 "ui/ozone/platform/drm/host/host_drm_device.h" + +#include "base/bind.h" +#include "base/run_loop.h" +#include "base/single_thread_task_runner.h" +#include "base/task_runner.h" +#include "base/threading/thread_task_runner_handle.h" +#include "services/service_manager/public/cpp/connector.h" +#include "services/ui/public/interfaces/constants.mojom.h" +#include "ui/display/types/display_snapshot.h" +#include "ui/ozone/platform/drm/common/drm_util.h" +#include "ui/ozone/platform/drm/host/drm_display_host_manager.h" +#include "ui/ozone/platform/drm/host/drm_overlay_manager.h" +#include "ui/ozone/platform/drm/host/host_cursor_proxy.h" + +namespace ui { + +HostDrmDevice::HostDrmDevice(DrmCursor* cursor, + service_manager::Connector* connector) + : cursor_(cursor), connector_(connector), weak_ptr_factory_(this) { + // Bind the viz process pointer here. + // TODO(rjkroege): Reconnect on error as that would indicate that the Viz + // process has failed. + connector->BindInterface(ui::mojom::kServiceName, &drm_device_ptr_); +} + +HostDrmDevice::~HostDrmDevice() { + DCHECK_CALLED_ON_VALID_THREAD(on_window_server_thread_); + for (GpuThreadObserver& observer : gpu_thread_observers_) + observer.OnGpuThreadRetired(); +} + +void HostDrmDevice::AsyncStartDrmDevice() { + auto callback = base::BindOnce(&HostDrmDevice::OnDrmServiceStartedCallback, + weak_ptr_factory_.GetWeakPtr()); + drm_device_ptr_->StartDrmDevice(std::move(callback)); +} + +void HostDrmDevice::BlockingStartDrmDevice() { + // Wait until startup related tasks posted to this thread that must precede + // blocking on + base::RunLoop().RunUntilIdle(); + + bool success; + drm_device_ptr_->StartDrmDevice(&success); + CHECK(success) + << "drm thread failed to successfully start in single process mode."; + if (!connected_) + OnDrmServiceStartedCallback(true); + return; +} + +void HostDrmDevice::OnDrmServiceStartedCallback(bool success) { + // This can be called multiple times in the course of single-threaded startup. + if (connected_) + return; + if (success == true) { + connected_ = true; + RunObservers(); + } + // TODO(rjkroege): Handle failure of launching a viz process. +} + +void HostDrmDevice::ProvideManagers(DrmDisplayHostManager* display_manager, + DrmOverlayManager* overlay_manager) { + display_manager_ = display_manager; + overlay_manager_ = overlay_manager; +} + +void HostDrmDevice::RunObservers() { + DCHECK_CALLED_ON_VALID_THREAD(on_window_server_thread_); + for (GpuThreadObserver& observer : gpu_thread_observers_) { + observer.OnGpuProcessLaunched(); + observer.OnGpuThreadReady(); + } + + // The cursor is special since it will process input events on the IO thread + // and can by-pass the UI thread. This means that we need to special case it + // and notify it after all other observers/handlers are notified. + cursor_->SetDrmCursorProxy(base::MakeUnique<HostCursorProxy>(connector_)); + + // TODO(rjkroege): Call ResetDrmCursorProxy when the mojo connection to the + // DRM thread is broken. +} + +void HostDrmDevice::AddGpuThreadObserver(GpuThreadObserver* observer) { + DCHECK_CALLED_ON_VALID_THREAD(on_window_server_thread_); + gpu_thread_observers_.AddObserver(observer); + if (IsConnected()) { + observer->OnGpuProcessLaunched(); + observer->OnGpuThreadReady(); + } +} + +void HostDrmDevice::RemoveGpuThreadObserver(GpuThreadObserver* observer) { + DCHECK_CALLED_ON_VALID_THREAD(on_window_server_thread_); + gpu_thread_observers_.RemoveObserver(observer); +} + +bool HostDrmDevice::IsConnected() { + DCHECK_CALLED_ON_VALID_THREAD(on_window_server_thread_); + + // TODO(rjkroege): Need to set to connected_ to false when we lose the Viz + // process connection. + return connected_; +} + +// Services needed for DrmDisplayHostMananger. +void HostDrmDevice::RegisterHandlerForDrmDisplayHostManager( + DrmDisplayHostManager* handler) { + DCHECK_CALLED_ON_VALID_THREAD(on_window_server_thread_); + display_manager_ = handler; +} + +void HostDrmDevice::UnRegisterHandlerForDrmDisplayHostManager() { + DCHECK_CALLED_ON_VALID_THREAD(on_window_server_thread_); + display_manager_ = nullptr; +} + +bool HostDrmDevice::GpuCreateWindow(gfx::AcceleratedWidget widget) { + DCHECK_CALLED_ON_VALID_THREAD(on_window_server_thread_); + if (!IsConnected()) + return false; + + drm_device_ptr_->CreateWindow(widget); + return true; +} + +bool HostDrmDevice::GpuDestroyWindow(gfx::AcceleratedWidget widget) { + DCHECK_CALLED_ON_VALID_THREAD(on_window_server_thread_); + if (!IsConnected()) + return false; + + drm_device_ptr_->DestroyWindow(widget); + return true; +} + +bool HostDrmDevice::GpuWindowBoundsChanged(gfx::AcceleratedWidget widget, + const gfx::Rect& bounds) { + DCHECK_CALLED_ON_VALID_THREAD(on_window_server_thread_); + if (!IsConnected()) + return false; + + drm_device_ptr_->SetWindowBounds(widget, bounds); + return true; +} + +// Services needed for DrmOverlayManager. +void HostDrmDevice::RegisterHandlerForDrmOverlayManager( + DrmOverlayManager* handler) { + // TODO(rjkroege): Permit overlay manager to run in viz when the display + // compositor runs in viz. + DCHECK_CALLED_ON_VALID_THREAD(on_window_server_thread_); + overlay_manager_ = handler; +} + +void HostDrmDevice::UnRegisterHandlerForDrmOverlayManager() { + DCHECK_CALLED_ON_VALID_THREAD(on_window_server_thread_); + overlay_manager_ = nullptr; +} + +bool HostDrmDevice::GpuCheckOverlayCapabilities( + gfx::AcceleratedWidget widget, + const OverlaySurfaceCandidateList& overlays) { + DCHECK_CALLED_ON_VALID_THREAD(on_window_server_thread_); + if (!IsConnected()) + return false; + + auto callback = + base::BindOnce(&HostDrmDevice::GpuCheckOverlayCapabilitiesCallback, + weak_ptr_factory_.GetWeakPtr()); + + drm_device_ptr_->CheckOverlayCapabilities(widget, overlays, + std::move(callback)); + return true; +} + +bool HostDrmDevice::GpuRefreshNativeDisplays() { + DCHECK_CALLED_ON_VALID_THREAD(on_window_server_thread_); + if (!IsConnected()) + return false; + auto callback = + base::BindOnce(&HostDrmDevice::GpuRefreshNativeDisplaysCallback, + weak_ptr_factory_.GetWeakPtr()); + drm_device_ptr_->RefreshNativeDisplays(std::move(callback)); + return true; +} + +bool HostDrmDevice::GpuConfigureNativeDisplay(int64_t id, + const DisplayMode_Params& pmode, + const gfx::Point& origin) { + DCHECK_CALLED_ON_VALID_THREAD(on_window_server_thread_); + if (!IsConnected()) + return false; + + // TODO(rjkroege): Remove the use of mode here. + auto mode = CreateDisplayModeFromParams(pmode); + auto callback = + base::BindOnce(&HostDrmDevice::GpuConfigureNativeDisplayCallback, + weak_ptr_factory_.GetWeakPtr()); + + drm_device_ptr_->ConfigureNativeDisplay(id, std::move(mode), origin, + std::move(callback)); + return true; +} + +bool HostDrmDevice::GpuDisableNativeDisplay(int64_t id) { + DCHECK_CALLED_ON_VALID_THREAD(on_window_server_thread_); + if (!IsConnected()) + return false; + auto callback = + base::BindOnce(&HostDrmDevice::GpuDisableNativeDisplayCallback, + weak_ptr_factory_.GetWeakPtr()); + drm_device_ptr_->DisableNativeDisplay(id, std::move(callback)); + return true; +} + +bool HostDrmDevice::GpuTakeDisplayControl() { + DCHECK_CALLED_ON_VALID_THREAD(on_window_server_thread_); + if (!IsConnected()) + return false; + auto callback = base::BindOnce(&HostDrmDevice::GpuTakeDisplayControlCallback, + weak_ptr_factory_.GetWeakPtr()); + drm_device_ptr_->TakeDisplayControl(std::move(callback)); + return true; +} + +bool HostDrmDevice::GpuRelinquishDisplayControl() { + DCHECK_CALLED_ON_VALID_THREAD(on_window_server_thread_); + if (!IsConnected()) + return false; + auto callback = + base::BindOnce(&HostDrmDevice::GpuRelinquishDisplayControlCallback, + weak_ptr_factory_.GetWeakPtr()); + drm_device_ptr_->TakeDisplayControl(std::move(callback)); + return true; +} + +bool HostDrmDevice::GpuAddGraphicsDevice(const base::FilePath& path, + base::ScopedFD fd) { + DCHECK_CALLED_ON_VALID_THREAD(on_window_server_thread_); + if (!IsConnected()) + return false; + base::File file(fd.release()); + drm_device_ptr_->AddGraphicsDevice(path, std::move(file)); + return true; +} + +bool HostDrmDevice::GpuRemoveGraphicsDevice(const base::FilePath& path) { + DCHECK_CALLED_ON_VALID_THREAD(on_window_server_thread_); + if (!IsConnected()) + return false; + drm_device_ptr_->RemoveGraphicsDevice(std::move(path)); + return true; +} + +bool HostDrmDevice::GpuGetHDCPState(int64_t display_id) { + DCHECK_CALLED_ON_VALID_THREAD(on_window_server_thread_); + if (!IsConnected()) + return false; + auto callback = base::BindOnce(&HostDrmDevice::GpuGetHDCPStateCallback, + weak_ptr_factory_.GetWeakPtr()); + drm_device_ptr_->GetHDCPState(display_id, std::move(callback)); + return true; +} + +bool HostDrmDevice::GpuSetHDCPState(int64_t display_id, + display::HDCPState state) { + DCHECK_CALLED_ON_VALID_THREAD(on_window_server_thread_); + if (!IsConnected()) + return false; + auto callback = base::BindOnce(&HostDrmDevice::GpuSetHDCPStateCallback, + weak_ptr_factory_.GetWeakPtr()); + drm_device_ptr_->SetHDCPState(display_id, state, std::move(callback)); + return true; +} + +bool HostDrmDevice::GpuSetColorCorrection( + int64_t id, + const std::vector<display::GammaRampRGBEntry>& degamma_lut, + const std::vector<display::GammaRampRGBEntry>& gamma_lut, + const std::vector<float>& correction_matrix) { + DCHECK_CALLED_ON_VALID_THREAD(on_window_server_thread_); + if (!IsConnected()) + return false; + + drm_device_ptr_->SetColorCorrection(id, degamma_lut, gamma_lut, + correction_matrix); + + return true; +} + +void HostDrmDevice::GpuCheckOverlayCapabilitiesCallback( + const gfx::AcceleratedWidget& widget, + const OverlaySurfaceCandidateList& overlays, + const OverlayStatusList& returns) const { + DCHECK_CALLED_ON_VALID_THREAD(on_window_server_thread_); + overlay_manager_->GpuSentOverlayResult(widget, overlays, returns); +} + +void HostDrmDevice::GpuConfigureNativeDisplayCallback(int64_t display_id, + bool success) const { + DCHECK_CALLED_ON_VALID_THREAD(on_window_server_thread_); + display_manager_->GpuConfiguredDisplay(display_id, success); +} + +// TODO(rjkroege): Remove the unnecessary conversion back into params. +void HostDrmDevice::GpuRefreshNativeDisplaysCallback( + std::vector<std::unique_ptr<display::DisplaySnapshot>> displays) const { + DCHECK_CALLED_ON_VALID_THREAD(on_window_server_thread_); + display_manager_->GpuHasUpdatedNativeDisplays( + CreateParamsFromSnapshot(displays)); +} + +void HostDrmDevice::GpuDisableNativeDisplayCallback(int64_t display_id, + bool success) const { + DCHECK_CALLED_ON_VALID_THREAD(on_window_server_thread_); + display_manager_->GpuConfiguredDisplay(display_id, success); +} + +void HostDrmDevice::GpuTakeDisplayControlCallback(bool success) const { + DCHECK_CALLED_ON_VALID_THREAD(on_window_server_thread_); + display_manager_->GpuTookDisplayControl(success); +} + +void HostDrmDevice::GpuRelinquishDisplayControlCallback(bool success) const { + DCHECK_CALLED_ON_VALID_THREAD(on_window_server_thread_); + display_manager_->GpuRelinquishedDisplayControl(success); +} + +void HostDrmDevice::GpuGetHDCPStateCallback(int64_t display_id, + bool success, + display::HDCPState state) const { + DCHECK_CALLED_ON_VALID_THREAD(on_window_server_thread_); + display_manager_->GpuReceivedHDCPState(display_id, success, state); +} + +void HostDrmDevice::GpuSetHDCPStateCallback(int64_t display_id, + bool success) const { + DCHECK_CALLED_ON_VALID_THREAD(on_window_server_thread_); + display_manager_->GpuUpdatedHDCPState(display_id, success); +} + +} // namespace ui
diff --git a/ui/ozone/platform/drm/mus_thread_proxy.h b/ui/ozone/platform/drm/host/host_drm_device.h similarity index 66% rename from ui/ozone/platform/drm/mus_thread_proxy.h rename to ui/ozone/platform/drm/host/host_drm_device.h index 49f6b5fa..47c5b18 100644 --- a/ui/ozone/platform/drm/mus_thread_proxy.h +++ b/ui/ozone/platform/drm/host/host_drm_device.h
@@ -2,24 +2,23 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef UI_OZONE_PLATFORM_DRM_MUS_THREAD_PROXY_H_ -#define UI_OZONE_PLATFORM_DRM_MUS_THREAD_PROXY_H_ +#ifndef UI_OZONE_PLATFORM_DRM_HOST_HOST_DRM_DEVICE_H_ +#define UI_OZONE_PLATFORM_DRM_HOST_HOST_DRM_DEVICE_H_ #include "base/callback.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "base/observer_list.h" #include "base/synchronization/lock.h" +#include "base/threading/thread_checker.h" #include "ui/gfx/native_widget_types.h" -#include "ui/ozone/platform/drm/common/display_types.h" -#include "ui/ozone/platform/drm/gpu/inter_thread_messaging_proxy.h" #include "ui/ozone/platform/drm/host/drm_cursor.h" #include "ui/ozone/platform/drm/host/gpu_thread_adapter.h" #include "ui/ozone/public/interfaces/device_cursor.mojom.h" #include "ui/ozone/public/interfaces/drm_device.mojom.h" -namespace base { -class SingleThreadTaskRunner; +namespace display { +class DisplaySnapshot; } namespace service_manager { @@ -27,37 +26,30 @@ } namespace ui { - class DrmDisplayHostManager; class DrmOverlayManager; -class DrmThread; class GpuThreadObserver; -class MusThreadProxy; -// TODO(rjkroege): Originally we had planned on running the window server, gpu, -// compositor and drm threads together in the same process. However, system -// security requires separating event handling and embedding decisions (the -// window server) into a process separate from the viz server -// (//services/viz/README.md). The separated implementation remains incomplete -// and will be completed in subsequent CLs. At that point, this class will -// become the viz host for ozone services and a separate class will contain the -// viz service (DRM interface.) -class MusThreadProxy : public GpuThreadAdapter, - public InterThreadMessagingProxy { +// This is the Viz host-side library for the DRM device service provided by the +// viz process. +class HostDrmDevice : public GpuThreadAdapter { public: - MusThreadProxy(DrmCursor* cursor, service_manager::Connector* connector); - ~MusThreadProxy() override; + HostDrmDevice(DrmCursor* cursor, service_manager::Connector* connector); + ~HostDrmDevice() override; - void StartDrmThread(); + // Start the DRM service. Runs the |OnDrmServiceStartedCallback| when the + // service has launched and initiates the remaining startup. + void AsyncStartDrmDevice(); + + // Blocks until the DRM service has come up. Use this entry point only when + // supporting launch of the service where the ozone UI and GPU + // reponsibilities are performed by the same underlying thread. + void BlockingStartDrmDevice(); + void ProvideManagers(DrmDisplayHostManager* display_manager, DrmOverlayManager* overlay_manager); - // InterThreadMessagingProxy. - // TODO(rjkroege): Remove when mojo everywhere. - void SetDrmThread(DrmThread* thread) override; - - // This is the core functionality. They are invoked when we have a main - // thread, a gpu thread and we have called initialize on both. + // GpuThreadAdapter void AddGpuThreadObserver(GpuThreadObserver* observer) override; void RemoveGpuThreadObserver(GpuThreadObserver* observer) override; bool IsConnected() override; @@ -101,8 +93,9 @@ const gfx::Rect& bounds) override; private: + void OnDrmServiceStartedCallback(bool success); + void PollForSingleThreadReady(int previous_delay); void RunObservers(); - void DispatchObserversFromDrmThread(); void GpuCheckOverlayCapabilitiesCallback( const gfx::AcceleratedWidget& widget, @@ -112,7 +105,8 @@ void GpuConfigureNativeDisplayCallback(int64_t display_id, bool success) const; - void GpuRefreshNativeDisplaysCallback(MovableDisplaySnapshots displays) const; + void GpuRefreshNativeDisplaysCallback( + std::vector<std::unique_ptr<display::DisplaySnapshot>> displays) const; void GpuDisableNativeDisplayCallback(int64_t display_id, bool success) const; void GpuTakeDisplayControlCallback(bool success) const; void GpuRelinquishDisplayControlCallback(bool success) const; @@ -121,32 +115,24 @@ display::HDCPState state) const; void GpuSetHDCPStateCallback(int64_t display_id, bool success) const; - scoped_refptr<base::SingleThreadTaskRunner> ws_task_runner_; - // Mojo implementation of the DrmDevice. - ui::ozone::mojom::DrmDevicePtr gpu_adapter_; - - // TODO(rjkroege): Remove this in a subsequent CL (http://crbug.com/620927) - DrmThread* drm_thread_; // Not owned. - - // Guards for multi-theaded access to drm_thread_. - base::Lock lock_; + ui::ozone::mojom::DrmDevicePtr drm_device_ptr_; DrmDisplayHostManager* display_manager_; // Not owned. DrmOverlayManager* overlay_manager_; // Not owned. DrmCursor* cursor_; // Not owned. service_manager::Connector* connector_; + THREAD_CHECKER(on_window_server_thread_); + bool connected_ = false; base::ObserverList<GpuThreadObserver> gpu_thread_observers_; - base::ThreadChecker on_window_server_thread_; + base::WeakPtrFactory<HostDrmDevice> weak_ptr_factory_; - base::WeakPtrFactory<MusThreadProxy> weak_ptr_factory_; - - DISALLOW_COPY_AND_ASSIGN(MusThreadProxy); + DISALLOW_COPY_AND_ASSIGN(HostDrmDevice); }; } // namespace ui -#endif // UI_OZONE_PLATFORM_DRM_MUS_THREAD_PROXY_H_ +#endif // UI_OZONE_PLATFORM_DRM_HOST_HOST_DRM_DEVICE_H_
diff --git a/ui/ozone/platform/drm/mus_thread_proxy.cc b/ui/ozone/platform/drm/mus_thread_proxy.cc deleted file mode 100644 index 95fb8621..0000000 --- a/ui/ozone/platform/drm/mus_thread_proxy.cc +++ /dev/null
@@ -1,346 +0,0 @@ -// Copyright 2016 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 "ui/ozone/platform/drm/mus_thread_proxy.h" - -#include "base/bind.h" -#include "base/single_thread_task_runner.h" -#include "base/task_runner.h" -#include "base/threading/thread_task_runner_handle.h" -#include "services/service_manager/public/cpp/connector.h" -#include "services/ui/public/interfaces/constants.mojom.h" -#include "ui/display/types/display_snapshot.h" -#include "ui/ozone/platform/drm/common/drm_util.h" -#include "ui/ozone/platform/drm/cursor_proxy_mojo.h" -#include "ui/ozone/platform/drm/gpu/drm_thread.h" -#include "ui/ozone/platform/drm/gpu/proxy_helpers.h" -#include "ui/ozone/platform/drm/host/drm_display_host_manager.h" -#include "ui/ozone/platform/drm/host/drm_overlay_manager.h" - -namespace ui { - -MusThreadProxy::MusThreadProxy(DrmCursor* cursor, - service_manager::Connector* connector) - : ws_task_runner_(base::ThreadTaskRunnerHandle::Get()), - drm_thread_(nullptr), - cursor_(cursor), - connector_(connector), - weak_ptr_factory_(this) { - // Bind the viz process pointer here. - connector->BindInterface(ui::mojom::kServiceName, &gpu_adapter_); -} - -MusThreadProxy::~MusThreadProxy() { - DCHECK(on_window_server_thread_.CalledOnValidThread()); - for (GpuThreadObserver& observer : gpu_thread_observers_) - observer.OnGpuThreadRetired(); -} - -// TODO(rjkroege): Relocate to a viz process specific class. -void MusThreadProxy::SetDrmThread(DrmThread* thread) { - base::AutoLock acquire(lock_); - drm_thread_ = thread; -} - -void MusThreadProxy::ProvideManagers(DrmDisplayHostManager* display_manager, - DrmOverlayManager* overlay_manager) { - display_manager_ = display_manager; - overlay_manager_ = overlay_manager; -} - -// TODO(rjkroege): Relocate to a viz process specific class. -void MusThreadProxy::StartDrmThread() { - DCHECK(drm_thread_); - drm_thread_->Start(); - - drm_thread_->task_runner()->PostTask( - FROM_HERE, base::Bind(&MusThreadProxy::DispatchObserversFromDrmThread, - base::Unretained(this))); -} - -// TODO(rjkroege): Relocate to a viz process specific class. -void MusThreadProxy::DispatchObserversFromDrmThread() { - ws_task_runner_->PostTask(FROM_HERE, base::Bind(&MusThreadProxy::RunObservers, - base::Unretained(this))); -} - -void MusThreadProxy::RunObservers() { - DCHECK(on_window_server_thread_.CalledOnValidThread()); - for (GpuThreadObserver& observer : gpu_thread_observers_) { - // TODO(rjkroege): This needs to be different when gpu process split - // happens. - observer.OnGpuProcessLaunched(); - observer.OnGpuThreadReady(); - } - - // The cursor is special since it will process input events on the IO thread - // and can by-pass the UI thread. This means that we need to special case it - // and notify it after all other observers/handlers are notified. - cursor_->SetDrmCursorProxy(base::MakeUnique<CursorProxyMojo>(connector_)); - - // TODO(rjkroege): Call ResetDrmCursorProxy when the mojo connection to the - // DRM thread is broken. -} - -void MusThreadProxy::AddGpuThreadObserver(GpuThreadObserver* observer) { - DCHECK(on_window_server_thread_.CalledOnValidThread()); - - gpu_thread_observers_.AddObserver(observer); - if (IsConnected()) { - // TODO(rjkroege): This needs to be different when gpu process split - // happens. - observer->OnGpuProcessLaunched(); - observer->OnGpuThreadReady(); - } -} - -void MusThreadProxy::RemoveGpuThreadObserver(GpuThreadObserver* observer) { - DCHECK(on_window_server_thread_.CalledOnValidThread()); - gpu_thread_observers_.RemoveObserver(observer); -} - -bool MusThreadProxy::IsConnected() { - DCHECK(on_window_server_thread_.CalledOnValidThread()); - base::AutoLock acquire(lock_); - if (drm_thread_) - return drm_thread_->IsRunning(); - return false; -} - -// Services needed for DrmDisplayHostMananger. -void MusThreadProxy::RegisterHandlerForDrmDisplayHostManager( - DrmDisplayHostManager* handler) { - DCHECK(on_window_server_thread_.CalledOnValidThread()); - display_manager_ = handler; -} - -void MusThreadProxy::UnRegisterHandlerForDrmDisplayHostManager() { - DCHECK(on_window_server_thread_.CalledOnValidThread()); - display_manager_ = nullptr; -} - -bool MusThreadProxy::GpuCreateWindow(gfx::AcceleratedWidget widget) { - DCHECK(on_window_server_thread_.CalledOnValidThread()); - if (!drm_thread_ || !drm_thread_->IsRunning()) - return false; - - gpu_adapter_->CreateWindow(widget); - return true; -} - -bool MusThreadProxy::GpuDestroyWindow(gfx::AcceleratedWidget widget) { - DCHECK(on_window_server_thread_.CalledOnValidThread()); - if (!drm_thread_ || !drm_thread_->IsRunning()) - return false; - - gpu_adapter_->DestroyWindow(widget); - return true; -} - -bool MusThreadProxy::GpuWindowBoundsChanged(gfx::AcceleratedWidget widget, - const gfx::Rect& bounds) { - DCHECK(on_window_server_thread_.CalledOnValidThread()); - if (!drm_thread_ || !drm_thread_->IsRunning()) - return false; - - gpu_adapter_->SetWindowBounds(widget, bounds); - return true; -} - -// Services needed for DrmOverlayManager. -void MusThreadProxy::RegisterHandlerForDrmOverlayManager( - DrmOverlayManager* handler) { - // TODO(rjkroege): Permit overlay manager to run in viz when the display - // compositor runs in viz. - DCHECK(on_window_server_thread_.CalledOnValidThread()); - overlay_manager_ = handler; -} - -void MusThreadProxy::UnRegisterHandlerForDrmOverlayManager() { - DCHECK(on_window_server_thread_.CalledOnValidThread()); - overlay_manager_ = nullptr; -} - -bool MusThreadProxy::GpuCheckOverlayCapabilities( - gfx::AcceleratedWidget widget, - const OverlaySurfaceCandidateList& overlays) { - DCHECK(on_window_server_thread_.CalledOnValidThread()); - if (!drm_thread_ || !drm_thread_->IsRunning()) - return false; - - auto callback = - base::BindOnce(&MusThreadProxy::GpuCheckOverlayCapabilitiesCallback, - weak_ptr_factory_.GetWeakPtr()); - - gpu_adapter_->CheckOverlayCapabilities(widget, overlays, std::move(callback)); - return true; -} - -bool MusThreadProxy::GpuRefreshNativeDisplays() { - DCHECK(on_window_server_thread_.CalledOnValidThread()); - if (!drm_thread_ || !drm_thread_->IsRunning()) - return false; - auto callback = - base::BindOnce(&MusThreadProxy::GpuRefreshNativeDisplaysCallback, - weak_ptr_factory_.GetWeakPtr()); - gpu_adapter_->RefreshNativeDisplays(std::move(callback)); - return true; -} - -bool MusThreadProxy::GpuConfigureNativeDisplay(int64_t id, - const DisplayMode_Params& pmode, - const gfx::Point& origin) { - DCHECK(on_window_server_thread_.CalledOnValidThread()); - if (!drm_thread_ || !drm_thread_->IsRunning()) - return false; - - // TODO(rjkroege): Remove the use of mode here. - auto mode = CreateDisplayModeFromParams(pmode); - auto callback = - base::BindOnce(&MusThreadProxy::GpuConfigureNativeDisplayCallback, - weak_ptr_factory_.GetWeakPtr()); - - gpu_adapter_->ConfigureNativeDisplay(id, std::move(mode), origin, - std::move(callback)); - return true; -} - -bool MusThreadProxy::GpuDisableNativeDisplay(int64_t id) { - DCHECK(on_window_server_thread_.CalledOnValidThread()); - if (!drm_thread_ || !drm_thread_->IsRunning()) - return false; - auto callback = - base::BindOnce(&MusThreadProxy::GpuDisableNativeDisplayCallback, - weak_ptr_factory_.GetWeakPtr()); - gpu_adapter_->DisableNativeDisplay(id, std::move(callback)); - return true; -} - -bool MusThreadProxy::GpuTakeDisplayControl() { - DCHECK(on_window_server_thread_.CalledOnValidThread()); - if (!drm_thread_ || !drm_thread_->IsRunning()) - return false; - auto callback = base::BindOnce(&MusThreadProxy::GpuTakeDisplayControlCallback, - weak_ptr_factory_.GetWeakPtr()); - gpu_adapter_->TakeDisplayControl(std::move(callback)); - return true; -} - -bool MusThreadProxy::GpuRelinquishDisplayControl() { - DCHECK(on_window_server_thread_.CalledOnValidThread()); - if (!drm_thread_ || !drm_thread_->IsRunning()) - return false; - auto callback = - base::BindOnce(&MusThreadProxy::GpuRelinquishDisplayControlCallback, - weak_ptr_factory_.GetWeakPtr()); - gpu_adapter_->TakeDisplayControl(std::move(callback)); - return true; -} - -bool MusThreadProxy::GpuAddGraphicsDevice(const base::FilePath& path, - base::ScopedFD fd) { - DCHECK(on_window_server_thread_.CalledOnValidThread()); - if (!drm_thread_ || !drm_thread_->IsRunning()) - return false; - base::File file(fd.release()); - gpu_adapter_->AddGraphicsDevice(path, std::move(file)); - return true; -} - -bool MusThreadProxy::GpuRemoveGraphicsDevice(const base::FilePath& path) { - DCHECK(on_window_server_thread_.CalledOnValidThread()); - if (!drm_thread_ || !drm_thread_->IsRunning()) - return false; - gpu_adapter_->RemoveGraphicsDevice(std::move(path)); - return true; -} - -bool MusThreadProxy::GpuGetHDCPState(int64_t display_id) { - DCHECK(on_window_server_thread_.CalledOnValidThread()); - if (!drm_thread_ || !drm_thread_->IsRunning()) - return false; - auto callback = base::BindOnce(&MusThreadProxy::GpuGetHDCPStateCallback, - weak_ptr_factory_.GetWeakPtr()); - gpu_adapter_->GetHDCPState(display_id, std::move(callback)); - return true; -} - -bool MusThreadProxy::GpuSetHDCPState(int64_t display_id, - display::HDCPState state) { - DCHECK(on_window_server_thread_.CalledOnValidThread()); - if (!drm_thread_ || !drm_thread_->IsRunning()) - return false; - auto callback = base::BindOnce(&MusThreadProxy::GpuSetHDCPStateCallback, - weak_ptr_factory_.GetWeakPtr()); - gpu_adapter_->SetHDCPState(display_id, state, std::move(callback)); - return true; -} - -bool MusThreadProxy::GpuSetColorCorrection( - int64_t id, - const std::vector<display::GammaRampRGBEntry>& degamma_lut, - const std::vector<display::GammaRampRGBEntry>& gamma_lut, - const std::vector<float>& correction_matrix) { - DCHECK(on_window_server_thread_.CalledOnValidThread()); - if (!drm_thread_ || !drm_thread_->IsRunning()) - return false; - - gpu_adapter_->SetColorCorrection(id, degamma_lut, gamma_lut, - correction_matrix); - - return true; -} - -void MusThreadProxy::GpuCheckOverlayCapabilitiesCallback( - const gfx::AcceleratedWidget& widget, - const OverlaySurfaceCandidateList& overlays, - const OverlayStatusList& returns) const { - DCHECK(on_window_server_thread_.CalledOnValidThread()); - overlay_manager_->GpuSentOverlayResult(widget, overlays, returns); -} - -void MusThreadProxy::GpuConfigureNativeDisplayCallback(int64_t display_id, - bool success) const { - DCHECK(on_window_server_thread_.CalledOnValidThread()); - display_manager_->GpuConfiguredDisplay(display_id, success); -} - -// TODO(rjkroege): Remove the unnecessary conversion back into params. -void MusThreadProxy::GpuRefreshNativeDisplaysCallback( - MovableDisplaySnapshots displays) const { - DCHECK(on_window_server_thread_.CalledOnValidThread()); - display_manager_->GpuHasUpdatedNativeDisplays( - CreateParamsFromSnapshot(displays)); -} - -void MusThreadProxy::GpuDisableNativeDisplayCallback(int64_t display_id, - bool success) const { - DCHECK(on_window_server_thread_.CalledOnValidThread()); - display_manager_->GpuConfiguredDisplay(display_id, success); -} - -void MusThreadProxy::GpuTakeDisplayControlCallback(bool success) const { - DCHECK(on_window_server_thread_.CalledOnValidThread()); - display_manager_->GpuTookDisplayControl(success); -} - -void MusThreadProxy::GpuRelinquishDisplayControlCallback(bool success) const { - DCHECK(on_window_server_thread_.CalledOnValidThread()); - display_manager_->GpuRelinquishedDisplayControl(success); -} - -void MusThreadProxy::GpuGetHDCPStateCallback(int64_t display_id, - bool success, - display::HDCPState state) const { - DCHECK(on_window_server_thread_.CalledOnValidThread()); - display_manager_->GpuReceivedHDCPState(display_id, success, state); -} - -void MusThreadProxy::GpuSetHDCPStateCallback(int64_t display_id, - bool success) const { - DCHECK(on_window_server_thread_.CalledOnValidThread()); - display_manager_->GpuUpdatedHDCPState(display_id, success); -} - -} // namespace ui
diff --git a/ui/ozone/platform/drm/ozone_platform_gbm.cc b/ui/ozone/platform/drm/ozone_platform_gbm.cc index e4152dd..1de8eab6 100644 --- a/ui/ozone/platform/drm/ozone_platform_gbm.cc +++ b/ui/ozone/platform/drm/ozone_platform_gbm.cc
@@ -18,6 +18,7 @@ #include "base/macros.h" #include "base/memory/ptr_util.h" #include "base/memory/weak_ptr.h" +#include "base/threading/platform_thread.h" #include "base/threading/thread_task_runner_handle.h" #include "services/service_manager/public/cpp/binder_registry.h" #include "ui/base/cursor/ozone/bitmap_cursor_factory_ozone.h" @@ -26,7 +27,6 @@ #include "ui/events/ozone/evdev/event_factory_evdev.h" #include "ui/events/ozone/layout/keyboard_layout_engine_manager.h" #include "ui/ozone/platform/drm/common/drm_util.h" -#include "ui/ozone/platform/drm/cursor_proxy_mojo.h" #include "ui/ozone/platform/drm/gpu/drm_device_generator.h" #include "ui/ozone/platform/drm/gpu/drm_device_manager.h" #include "ui/ozone/platform/drm/gpu/drm_gpu_display_manager.h" @@ -43,7 +43,7 @@ #include "ui/ozone/platform/drm/host/drm_overlay_manager.h" #include "ui/ozone/platform/drm/host/drm_window_host.h" #include "ui/ozone/platform/drm/host/drm_window_host_manager.h" -#include "ui/ozone/platform/drm/mus_thread_proxy.h" +#include "ui/ozone/platform/drm/host/host_drm_device.h" #include "ui/ozone/public/cursor_factory_ozone.h" #include "ui/ozone/public/gpu_platform_support_host.h" #include "ui/ozone/public/ozone_platform.h" @@ -146,7 +146,7 @@ const gfx::Rect& bounds) override { GpuThreadAdapter* adapter = gpu_platform_support_host_.get(); if (using_mojo_ || single_process_) { - adapter = mus_thread_proxy_.get(); + adapter = host_drm_device_.get(); } std::unique_ptr<DrmWindowHost> platform_window(new DrmWindowHost( @@ -169,6 +169,7 @@ // via mojo IPC. single_process_ = args.single_process; using_mojo_ = args.connector != nullptr; + host_thread_ = base::PlatformThread::CurrentRef(); DCHECK(!(using_mojo_ && !single_process_)) << "Multiprocess Mojo is not supported yet."; @@ -194,9 +195,9 @@ gl_api_loader_.reset(new GlApiLoader()); if (using_mojo_) { - mus_thread_proxy_ = - base::MakeUnique<MusThreadProxy>(cursor_.get(), args.connector); - adapter = mus_thread_proxy_.get(); + host_drm_device_ = + base::MakeUnique<HostDrmDevice>(cursor_.get(), args.connector); + adapter = host_drm_device_.get(); } else { gpu_platform_support_host_.reset( new DrmGpuPlatformSupportHost(cursor_.get())); @@ -211,22 +212,26 @@ cursor_factory_ozone_.reset(new BitmapCursorFactoryOzone); if (using_mojo_) { - mus_thread_proxy_->ProvideManagers(display_manager_.get(), - overlay_manager_.get()); + host_drm_device_->ProvideManagers(display_manager_.get(), + overlay_manager_.get()); + host_drm_device_->AsyncStartDrmDevice(); } } + void InitializeGPU(const InitParams& args) override { // TODO(rjkroege): services/ui should initialize this with a connector. // However, in-progress refactorings in services/ui make it difficult to // require this at present. Set using_mojo_ like below once this is // complete. + // TODO(rjk): Make it possible to turn this on. // using_mojo_ = args.connector != nullptr; gpu_task_runner_ = base::ThreadTaskRunnerHandle::Get(); - InterThreadMessagingProxy* itmp; - if (using_mojo_) { - itmp = mus_thread_proxy_.get(); - } else { + + if (!single_process_) gl_api_loader_.reset(new GlApiLoader()); + + InterThreadMessagingProxy* itmp; + if (!using_mojo_) { scoped_refptr<DrmThreadMessageProxy> message_proxy( new DrmThreadMessageProxy()); itmp = message_proxy.get(); @@ -236,11 +241,12 @@ // NOTE: Can't start the thread here since this is called before sandbox // initialization in multi-process Chrome. In mus, we start the DRM thread. drm_thread_proxy_.reset(new DrmThreadProxy()); - drm_thread_proxy_->BindThreadIntoMessagingProxy(itmp); surface_factory_.reset(new GbmSurfaceFactory(drm_thread_proxy_.get())); - if (using_mojo_) { - mus_thread_proxy_->StartDrmThread(); + if (!using_mojo_) { + drm_thread_proxy_->BindThreadIntoMessagingProxy(itmp); + } else { + drm_thread_proxy_->StartDrmThread(); } // When the viz process (and hence the gpu portion of ozone/gbm) is @@ -255,26 +261,38 @@ for (auto& request : pending_gpu_adapter_requests_) drm_thread_proxy_->AddBindingDrmDevice(std::move(request)); pending_gpu_adapter_requests_.clear(); + + // If InitializeGPU and InitializeUI are invoked on the same thread, startup + // sequencing is complicated because tasks are queued on the unbound mojo + // pipe connecting the UI (the host) to the DRM thread before the DRM thread + // is launched above. Special case this sequence vis the + // BlockingStartDrmDevice API. + // TODO(rjkroege): In a future when we have completed splitting Viz, it will + // be possible to simplify this logic. + if (using_mojo_ && single_process_ && + host_thread_ == base::PlatformThread::CurrentRef()) { + CHECK(host_drm_device_) + << "Mojo single-process mode requires a HostDrmDevice."; + host_drm_device_->BlockingStartDrmDevice(); + } } private: bool using_mojo_; bool single_process_; - - // Bridges the DRM, GPU and main threads in mus. This must be destroyed last. - std::unique_ptr<MusThreadProxy> mus_thread_proxy_; + base::PlatformThreadRef host_thread_; // Objects in the GPU process. std::unique_ptr<DrmThreadProxy> drm_thread_proxy_; std::unique_ptr<GlApiLoader> gl_api_loader_; std::unique_ptr<GbmSurfaceFactory> surface_factory_; scoped_refptr<IPC::MessageFilter> gpu_message_filter_; + scoped_refptr<base::SingleThreadTaskRunner> gpu_task_runner_; - // TODO(rjkroege,sadrul): Once the mus gpu process split happens, this can go - // away. + // TODO(rjkroege,sadrul): Provide a more elegant solution for this issue when + // running in single process mode. std::vector<ozone::mojom::DeviceCursorRequest> pending_cursor_requests_; std::vector<ozone::mojom::DrmDeviceRequest> pending_gpu_adapter_requests_; - scoped_refptr<base::SingleThreadTaskRunner> gpu_task_runner_; // Objects in the Browser process. std::unique_ptr<DeviceManager> device_manager_; @@ -282,10 +300,17 @@ std::unique_ptr<DrmWindowHostManager> window_manager_; std::unique_ptr<DrmCursor> cursor_; std::unique_ptr<EventFactoryEvdev> event_factory_ozone_; - std::unique_ptr<DrmGpuPlatformSupportHost> gpu_platform_support_host_; std::unique_ptr<DrmDisplayHostManager> display_manager_; std::unique_ptr<DrmOverlayManager> overlay_manager_; + // gpu_platform_support_host_ is the IPC bridge to the GPU process while + // host_drm_device_ is the mojo bridge to the Viz process. Only one can be in + // use at any time. + // TODO(rjkroege): Remove gpu_platform_support_host_ once ozone/drm with mojo + // has reached the stable channel. + std::unique_ptr<DrmGpuPlatformSupportHost> gpu_platform_support_host_; + std::unique_ptr<HostDrmDevice> host_drm_device_; + #if BUILDFLAG(USE_XKBCOMMON) XkbEvdevCodes xkb_evdev_code_converter_; #endif
diff --git a/ui/ozone/public/interfaces/drm_device.mojom b/ui/ozone/public/interfaces/drm_device.mojom index 0c7ddcd..eede424 100644 --- a/ui/ozone/public/interfaces/drm_device.mojom +++ b/ui/ozone/public/interfaces/drm_device.mojom
@@ -20,6 +20,10 @@ // All functions in DrmDevice are implemented by the lower privilege viz // process. interface DrmDevice { + // Starts the DRM service and returns true on success. + [Sync] + StartDrmDevice() => (bool success); + // Creates scanout capable DRM buffers to back |widget|. CreateWindow(gfx.mojom.AcceleratedWidget widget);
diff --git a/ui/views/BUILD.gn b/ui/views/BUILD.gn index e242311..6a7ad028 100644 --- a/ui/views/BUILD.gn +++ b/ui/views/BUILD.gn
@@ -53,6 +53,7 @@ "animation/ink_drop_ripple_observer.h", "animation/ink_drop_state.h", "animation/ink_drop_stub.h", + "animation/ink_drop_util.h", "animation/scroll_animator.h", "animation/square_ink_drop_ripple.h", "background.h", @@ -251,6 +252,7 @@ "animation/ink_drop_ripple.cc", "animation/ink_drop_state.cc", "animation/ink_drop_stub.cc", + "animation/ink_drop_util.cc", "animation/scroll_animator.cc", "animation/square_ink_drop_ripple.cc", "background.cc",
diff --git a/ui/views/animation/flood_fill_ink_drop_ripple.cc b/ui/views/animation/flood_fill_ink_drop_ripple.cc index 7f2c4c1..849ee7dc 100644 --- a/ui/views/animation/flood_fill_ink_drop_ripple.cc +++ b/ui/views/animation/flood_fill_ink_drop_ripple.cc
@@ -14,6 +14,7 @@ #include "ui/gfx/animation/animation.h" #include "ui/gfx/geometry/point_conversions.h" #include "ui/gfx/geometry/vector2d_f.h" +#include "ui/views/animation/ink_drop_util.h" namespace { @@ -426,6 +427,10 @@ circle_layer_delegate_.GetCenteringOffset(); transform.Translate(-drawn_center_offset.x(), -drawn_center_offset.y()); + // Add subpixel correction to the transform. + transform.ConcatTransform(GetTransformSubpixelCorrection( + transform, painted_layer_.device_scale_factor())); + return transform; }
diff --git a/ui/views/animation/flood_fill_ink_drop_ripple_unittest.cc b/ui/views/animation/flood_fill_ink_drop_ripple_unittest.cc index 44ea59f..f61dae86 100644 --- a/ui/views/animation/flood_fill_ink_drop_ripple_unittest.cc +++ b/ui/views/animation/flood_fill_ink_drop_ripple_unittest.cc
@@ -7,6 +7,7 @@ #include "testing/gtest/include/gtest/gtest.h" #include "ui/gfx/geometry/insets.h" #include "ui/gfx/geometry/point.h" +#include "ui/gfx/geometry/point_conversions.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/size.h" #include "ui/views/animation/test/flood_fill_ink_drop_ripple_test_api.h" @@ -29,10 +30,11 @@ SK_ColorWHITE, 0.175f); FloodFillInkDropRippleTestApi test_api(&ripple); - gfx::Point actual_center = test_api.GetDrawnCenterPoint(); + gfx::Point3F actual_center(gfx::PointF(test_api.GetDrawnCenterPoint())); test_api.TransformPoint(10, &actual_center); - EXPECT_EQ(expected_center_point, actual_center); + EXPECT_EQ(expected_center_point, + gfx::ToRoundedPoint(actual_center.AsPointF())); } TEST(FloodFillInkDropRippleTest, MaxDistanceToCorners) { @@ -107,5 +109,40 @@ activated_transform.ApproximatelyEqual(pending_activated_transform)); } +TEST(FloodFillInkDropRippleTest, TransformIsPixelAligned) { + const float kEpsilon = 0.001f; + + const gfx::Size host_size(11, 11); + // Keep the draw center different from the the host center to have a non zero + // offset in the transformation. + const gfx::Point center_point(host_size.width() / 3, host_size.height() / 3); + const SkColor color = SK_ColorYELLOW; + const float visible_opacity = 0.3f; + + FloodFillInkDropRipple ripple(host_size, center_point, color, + visible_opacity); + FloodFillInkDropRippleTestApi test_api(&ripple); + + for (auto dsf : {1.25, 1.33, 1.5, 1.6, 1.75, 1.8, 2.25}) { + SCOPED_TRACE(testing::Message() + << std::endl + << "Device Scale Factor: " << dsf << std::endl); + ripple.GetRootLayer()->OnDeviceScaleFactorChanged(dsf); + gfx::Point3F ripple_origin; + + test_api.TransformPoint(host_size.width() / 2, &ripple_origin); + + // Apply device scale factor to get the final offset. + gfx::Transform dsf_transform; + dsf_transform.Scale(dsf, dsf); + dsf_transform.TransformPoint(&ripple_origin); + + EXPECT_NEAR(ripple_origin.x(), gfx::ToRoundedInt(ripple_origin.x()), + kEpsilon); + EXPECT_NEAR(ripple_origin.y(), gfx::ToRoundedInt(ripple_origin.y()), + kEpsilon); + } +} + } // namespace test } // namespace views
diff --git a/ui/views/animation/ink_drop_highlight.cc b/ui/views/animation/ink_drop_highlight.cc index effde49..98c9030 100644 --- a/ui/views/animation/ink_drop_highlight.cc +++ b/ui/views/animation/ink_drop_highlight.cc
@@ -17,6 +17,7 @@ #include "ui/gfx/geometry/insets.h" #include "ui/views/animation/ink_drop_highlight_observer.h" #include "ui/views/animation/ink_drop_painted_layer_delegates.h" +#include "ui/views/animation/ink_drop_util.h" namespace views { @@ -161,6 +162,11 @@ size_.height() == 0 ? 0 : size.height() / size_.height()); gfx::Vector2dF layer_offset = layer_delegate_->GetCenteringOffset(); transform.Translate(-layer_offset.x(), -layer_offset.y()); + + // Add subpixel correction to the transform. + transform.ConcatTransform( + GetTransformSubpixelCorrection(transform, layer_->device_scale_factor())); + return transform; }
diff --git a/ui/views/animation/ink_drop_highlight_unittest.cc b/ui/views/animation/ink_drop_highlight_unittest.cc index 94dc954..95380db 100644 --- a/ui/views/animation/ink_drop_highlight_unittest.cc +++ b/ui/views/animation/ink_drop_highlight_unittest.cc
@@ -10,10 +10,12 @@ #include "base/memory/ptr_util.h" #include "base/time/time.h" #include "testing/gtest/include/gtest/gtest.h" +#include "ui/compositor/layer.h" #include "ui/compositor/scoped_animation_duration_scale_mode.h" #include "ui/gfx/animation/animation.h" #include "ui/gfx/animation/animation_test_api.h" #include "ui/gfx/geometry/size.h" +#include "ui/gfx/transform.h" #include "ui/views/animation/test/ink_drop_highlight_test_api.h" #include "ui/views/animation/test/test_ink_drop_highlight_observer.h" @@ -206,5 +208,35 @@ false /* explode */); } +TEST_F(InkDropHighlightTest, TransformIsPixelAligned) { + const float kEpsilon = 0.001f; + gfx::Size highlight_size(10, 10); + InitHighlight(base::MakeUnique<InkDropHighlight>( + highlight_size, 3, gfx::PointF(3.5f, 3.5f), SK_ColorYELLOW)); + const gfx::PointF layer_origin( + ink_drop_highlight()->layer()->bounds().origin()); + for (auto dsf : {1.25, 1.33, 1.5, 1.6, 1.75, 1.8, 2.25}) { + SCOPED_TRACE(testing::Message() + << std::endl + << "Device Scale Factor: " << dsf << std::endl); + ink_drop_highlight()->layer()->OnDeviceScaleFactorChanged(dsf); + + const gfx::SizeF size(highlight_size); + gfx::Transform transform = test_api()->CalculateTransform(size); + gfx::Point3F transformed_layer_origin(layer_origin.x(), layer_origin.y(), + 0); + transform.TransformPoint(&transformed_layer_origin); + + // Apply device scale factor to get the final offset. + gfx::Transform dsf_transform; + dsf_transform.Scale(dsf, dsf); + dsf_transform.TransformPoint(&transformed_layer_origin); + EXPECT_NEAR(transformed_layer_origin.x(), + gfx::ToRoundedInt(transformed_layer_origin.x()), kEpsilon); + EXPECT_NEAR(transformed_layer_origin.y(), + gfx::ToRoundedInt(transformed_layer_origin.y()), kEpsilon); + } +} + } // namespace test } // namespace views
diff --git a/ui/views/animation/ink_drop_mask.cc b/ui/views/animation/ink_drop_mask.cc index d95286d9..104c4b3 100644 --- a/ui/views/animation/ink_drop_mask.cc +++ b/ui/views/animation/ink_drop_mask.cc
@@ -48,9 +48,15 @@ flags.setAntiAlias(true); ui::PaintRecorder recorder(context, layer()->size()); - gfx::RectF bounds(layer()->bounds()); - bounds.Inset(mask_insets_); - recorder.canvas()->DrawRoundRect(bounds, corner_radius_, flags); + const float dsf = recorder.canvas()->UndoDeviceScaleFactor(); + + gfx::RectF masking_bound(layer()->bounds()); + masking_bound.Inset(mask_insets_); + + const gfx::Rect masking_bound_scaled = + gfx::ScaleToRoundedRect(gfx::ToNearestRect(masking_bound), dsf); + recorder.canvas()->DrawRoundRect(masking_bound_scaled, corner_radius_ * dsf, + flags); } // CircleInkDropMask
diff --git a/ui/views/animation/ink_drop_util.cc b/ui/views/animation/ink_drop_util.cc new file mode 100644 index 0000000..4344d479 --- /dev/null +++ b/ui/views/animation/ink_drop_util.cc
@@ -0,0 +1,54 @@ +// 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 "ui/views/animation/ink_drop_util.h" + +#include <math.h> + +#include "base/logging.h" +#include "ui/gfx/geometry/point3_f.h" +#include "ui/gfx/geometry/safe_integer_conversions.h" +#include "ui/gfx/geometry/vector2d_f.h" +#include "ui/gfx/transform.h" + +namespace views { + +gfx::Transform GetTransformSubpixelCorrection(const gfx::Transform& transform, + float device_scale_factor) { + gfx::Point3F origin; + transform.TransformPoint(&origin); + + const gfx::Vector2dF offset_in_dip = origin.AsPointF().OffsetFromOrigin(); + + // Scale the origin to screen space + origin.Scale(device_scale_factor); + + // Compute the rounded offset in screen space and finally unscale it back to + // DIP space. + gfx::Vector2dF aligned_offset_in_dip = origin.AsPointF().OffsetFromOrigin(); + aligned_offset_in_dip.set_x(gfx::ToRoundedInt(aligned_offset_in_dip.x())); + aligned_offset_in_dip.set_y(gfx::ToRoundedInt(aligned_offset_in_dip.y())); + aligned_offset_in_dip.Scale(1.f / device_scale_factor); + + // Compute the subpixel offset correction and apply it to the transform. + gfx::Transform subpixel_correction; + subpixel_correction.Translate(aligned_offset_in_dip - offset_in_dip); +#if DCHECK_IS_ON() + const float kEpsilon = 0.0001f; + gfx::Point3F offset; + + gfx::Transform transform_corrected(transform); + transform_corrected.ConcatTransform(subpixel_correction); + transform_corrected.TransformPoint(&offset); + offset.Scale(device_scale_factor); + + if (!std::isnan(offset.x())) + DCHECK_LT(std::abs(gfx::ToRoundedInt(offset.x()) - offset.x()), kEpsilon); + if (!std::isnan(offset.y())) + DCHECK_LT(std::abs(gfx::ToRoundedInt(offset.y()) - offset.y()), kEpsilon); +#endif + return subpixel_correction; +} + +} // namespace views
diff --git a/ui/views/animation/ink_drop_util.h b/ui/views/animation/ink_drop_util.h new file mode 100644 index 0000000..883b789 --- /dev/null +++ b/ui/views/animation/ink_drop_util.h
@@ -0,0 +1,27 @@ +// 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 UI_VIEWS_ANIMATION_INK_DROP_UTIL_H_ +#define UI_VIEWS_ANIMATION_INK_DROP_UTIL_H_ + +#include "ui/views/views_export.h" + +namespace gfx { +class Transform; +} // namespace gfx + +namespace views { + +// A layer |transform| may add an offset to its layer relative to the parent +// layer. This offset does not take into consideration the subpixel positioning. +// A subpixel correction needs to be applied to make sure the layers are pixel +// aligned after the transform is applied. Use this function to compute the +// subpixel correction transform. +VIEWS_EXPORT gfx::Transform GetTransformSubpixelCorrection( + const gfx::Transform& transform, + float device_scale_factor); + +} // namespace views + +#endif // UI_VIEWS_ANIMATION_INK_DROP_UTIL_H_
diff --git a/ui/views/animation/test/flood_fill_ink_drop_ripple_test_api.cc b/ui/views/animation/test/flood_fill_ink_drop_ripple_test_api.cc index 11ee71d..b567302 100644 --- a/ui/views/animation/test/flood_fill_ink_drop_ripple_test_api.cc +++ b/ui/views/animation/test/flood_fill_ink_drop_ripple_test_api.cc
@@ -23,7 +23,7 @@ FloodFillInkDropRippleTestApi::~FloodFillInkDropRippleTestApi() {} void FloodFillInkDropRippleTestApi::TransformPoint(float radius, - gfx::Point* point) { + gfx::Point3F* point) { ink_drop_ripple()->CalculateTransform(radius).TransformPoint(point); }
diff --git a/ui/views/animation/test/flood_fill_ink_drop_ripple_test_api.h b/ui/views/animation/test/flood_fill_ink_drop_ripple_test_api.h index 7e83d96..2793dcdb 100644 --- a/ui/views/animation/test/flood_fill_ink_drop_ripple_test_api.h +++ b/ui/views/animation/test/flood_fill_ink_drop_ripple_test_api.h
@@ -28,7 +28,7 @@ // Transforms |point| into the FloodFillInkDropRipples clip layer coordinate // space for the given radius. - void TransformPoint(float radius, gfx::Point* point); + void TransformPoint(float radius, gfx::Point3F* point); // Returns the center point that the ripple is drawn at in the original Canvas // coordinate space.
diff --git a/ui/views/animation/test/ink_drop_highlight_test_api.cc b/ui/views/animation/test/ink_drop_highlight_test_api.cc index 77ba8fb2..4111c89 100644 --- a/ui/views/animation/test/ink_drop_highlight_test_api.cc +++ b/ui/views/animation/test/ink_drop_highlight_test_api.cc
@@ -26,5 +26,10 @@ return animators; } +gfx::Transform InkDropHighlightTestApi::CalculateTransform( + const gfx::SizeF& size) { + return ink_drop_highlight()->CalculateTransform(size); +} + } // namespace test } // namespace views
diff --git a/ui/views/animation/test/ink_drop_highlight_test_api.h b/ui/views/animation/test/ink_drop_highlight_test_api.h index e542b8a..c7bec20 100644 --- a/ui/views/animation/test/ink_drop_highlight_test_api.h +++ b/ui/views/animation/test/ink_drop_highlight_test_api.h
@@ -10,6 +10,8 @@ #include "base/macros.h" #include "ui/compositor/test/multi_layer_animator_test_controller.h" #include "ui/compositor/test/multi_layer_animator_test_controller_delegate.h" +#include "ui/gfx/geometry/size_f.h" +#include "ui/gfx/transform.h" namespace ui { class LayerAnimator; @@ -33,6 +35,8 @@ // MultiLayerAnimatorTestControllerDelegate: std::vector<ui::LayerAnimator*> GetLayerAnimators() override; + gfx::Transform CalculateTransform(const gfx::SizeF& size); + protected: InkDropHighlight* ink_drop_highlight() { return static_cast<const InkDropHighlightTestApi*>(this)
diff --git a/ui/views/controls/textfield/textfield.cc b/ui/views/controls/textfield/textfield.cc index 99f1a30f6..94be6ec 100644 --- a/ui/views/controls/textfield/textfield.cc +++ b/ui/views/controls/textfield/textfield.cc
@@ -1984,7 +1984,7 @@ location.set_x(GetMirroredXForRect(location)); location.set_height( std::min(location.height(), - GetVisibleBounds().height() - location.y() - location.y())); + GetContentsBounds().height() - location.y() - location.y())); cursor_view_.SetBoundsRect(location); }
diff --git a/ui/views/controls/textfield/textfield_unittest.cc b/ui/views/controls/textfield/textfield_unittest.cc index 88f29d8..a58d14f 100644 --- a/ui/views/controls/textfield/textfield_unittest.cc +++ b/ui/views/controls/textfield/textfield_unittest.cc
@@ -3217,6 +3217,23 @@ GetCursorBounds().height()); } +// Verify that cursor view height is independent of its parent view height. +TEST_F(TextfieldTest, CursorViewHeightAtDiffDSF) { + InitTextfield(); + textfield_->SetBounds(0, 0, 100, 100); + textfield_->SetCursorEnabled(true); + SendKeyEvent('a'); + EXPECT_TRUE(test_api_->IsCursorVisible()); + int height = test_api_->GetCursorViewRect().height(); + + // update the size of its parent view size and verify that the height of the + // cursor view stays the same. + View* parent = textfield_->parent(); + parent->SetBounds(0, 0, 50, height - 2); + SendKeyEvent('b'); + EXPECT_EQ(height, test_api_->GetCursorViewRect().height()); +} + // Check if the text cursor is always at the end of the textfield after the // text overflows from the textfield. If the textfield size changes, check if // the text cursor's location is updated accordingly.
diff --git a/ui/views/widget/desktop_aura/desktop_screen_x11.cc b/ui/views/widget/desktop_aura/desktop_screen_x11.cc index df8884e7..c31728ca 100644 --- a/ui/views/widget/desktop_aura/desktop_screen_x11.cc +++ b/ui/views/widget/desktop_aura/desktop_screen_x11.cc
@@ -377,9 +377,8 @@ // TODO(ccameron): Populate this based on this specific display. // http://crbug.com/735613 if (!display::Display::HasForceColorProfile()) { - gfx::ICCProfile icc_profile = gfx::ICCProfile::FromBestMonitor(); - icc_profile.HistogramDisplay(display.id()); - display.set_color_space(icc_profile.GetColorSpace()); + display.set_color_space( + gfx::ICCProfile::FromBestMonitor().GetColorSpace()); } displays.push_back(display);
diff --git a/url/gurl.cc b/url/gurl.cc index 45c45b10b..dbf09b8 100644 --- a/url/gurl.cc +++ b/url/gurl.cc
@@ -509,14 +509,14 @@ #endif // WIN32 -bool GURL::DomainIs(base::StringPiece lower_ascii_domain) const { +bool GURL::DomainIs(base::StringPiece canonical_domain) const { if (!is_valid_) return false; // FileSystem URLs have empty host_piece, so check this first. - if (SchemeIsFileSystem() && inner_url_) - return inner_url_->DomainIs(lower_ascii_domain); - return url::DomainIs(host_piece(), lower_ascii_domain); + if (inner_url_ && SchemeIsFileSystem()) + return inner_url_->DomainIs(canonical_domain); + return url::DomainIs(host_piece(), canonical_domain); } bool GURL::EqualsIgnoringRef(const GURL& other) const {
diff --git a/url/gurl.h b/url/gurl.h index 091ff68..2d9940b 100644 --- a/url/gurl.h +++ b/url/gurl.h
@@ -397,11 +397,13 @@ // "www.google.com", this will return true for "com", "google.com", and // "www.google.com". // - // The input domain should be lower-case ASCII to match the canonicalized - // scheme. This call is more efficient than getting the host and check - // whether host has the specific domain or not because no copies or - // object constructions are done. - bool DomainIs(base::StringPiece lower_ascii_domain) const; + // The input domain should match host canonicalization rules. i.e. the input + // show be lowercase except for escape chars. + // + // This call is more efficient than getting the host and checking whether the + // host has the specific domain or not because no copies or object + // constructions are done. + bool DomainIs(base::StringPiece canonical_domain) const; // Checks whether or not two URLs are differing only in the ref (the part // after the # character).
diff --git a/url/gurl_unittest.cc b/url/gurl_unittest.cc index 464d08a..7545c97 100644 --- a/url/gurl_unittest.cc +++ b/url/gurl_unittest.cc
@@ -658,6 +658,11 @@ GURL invalid_url("google.com"); EXPECT_FALSE(invalid_url.is_valid()); EXPECT_FALSE(invalid_url.DomainIs("google.com")); + + GURL url_with_escape_chars("https://www.,.test"); + EXPECT_TRUE(url_with_escape_chars.is_valid()); + EXPECT_EQ(url_with_escape_chars.host(), "www.%2C.test"); + EXPECT_TRUE(url_with_escape_chars.DomainIs("%2C.test")); } TEST(GURLTest, DomainIsTerminatingDotBehavior) {
diff --git a/url/origin.cc b/url/origin.cc index d15ba43f..81908281 100644 --- a/url/origin.cc +++ b/url/origin.cc
@@ -170,8 +170,8 @@ return GetPhysicalOrigin().IsSameOriginWith(other.GetPhysicalOrigin()); } -bool Origin::DomainIs(base::StringPiece lower_ascii_domain) const { - return !unique_ && url::DomainIs(tuple_.host(), lower_ascii_domain); +bool Origin::DomainIs(base::StringPiece canonical_domain) const { + return !unique_ && url::DomainIs(tuple_.host(), canonical_domain); } bool Origin::operator<(const Origin& other) const {
diff --git a/url/origin.h b/url/origin.h index c5bdf63..8b59b5a 100644 --- a/url/origin.h +++ b/url/origin.h
@@ -161,7 +161,7 @@ GURL GetURL() const; // Same as GURL::DomainIs. If |this| origin is unique, then returns false. - bool DomainIs(base::StringPiece lower_ascii_domain) const; + bool DomainIs(base::StringPiece canonical_domain) const; // Allows Origin to be used as a key in STL (for example, a std::set or // std::map).
diff --git a/url/url_util.cc b/url/url_util.cc index c026453b..1942f79e 100644 --- a/url/url_util.cc +++ b/url/url_util.cc
@@ -672,28 +672,27 @@ return DoFindAndCompareScheme(str, str_len, compare, found_scheme); } -bool DomainIs(base::StringPiece canonicalized_host, - base::StringPiece lower_ascii_domain) { - if (canonicalized_host.empty() || lower_ascii_domain.empty()) +bool DomainIs(base::StringPiece canonical_host, + base::StringPiece canonical_domain) { + if (canonical_host.empty() || canonical_domain.empty()) return false; // If the host name ends with a dot but the input domain doesn't, then we // ignore the dot in the host name. - size_t host_len = canonicalized_host.length(); - if (canonicalized_host.back() == '.' && lower_ascii_domain.back() != '.') + size_t host_len = canonical_host.length(); + if (canonical_host.back() == '.' && canonical_domain.back() != '.') --host_len; - if (host_len < lower_ascii_domain.length()) + if (host_len < canonical_domain.length()) return false; // |host_first_pos| is the start of the compared part of the host name, not // start of the whole host name. const char* host_first_pos = - canonicalized_host.data() + host_len - lower_ascii_domain.length(); + canonical_host.data() + host_len - canonical_domain.length(); - if (!base::LowerCaseEqualsASCII( - base::StringPiece(host_first_pos, lower_ascii_domain.length()), - lower_ascii_domain)) { + if (base::StringPiece(host_first_pos, canonical_domain.length()) != + canonical_domain) { return false; } @@ -701,7 +700,7 @@ // if the host name is longer than the input domain name, then the character // immediately before the compared part should be a dot. For example, // www.google.com has domain "google.com", but www.iamnotgoogle.com does not. - if (lower_ascii_domain[0] != '.' && host_len > lower_ascii_domain.length() && + if (canonical_domain[0] != '.' && host_len > canonical_domain.length() && *(host_first_pos - 1) != '.') { return false; }
diff --git a/url/url_util.h b/url/url_util.h index 643c29d8..7486bf7 100644 --- a/url/url_util.h +++ b/url/url_util.h
@@ -173,16 +173,16 @@ // Hosts ---------------------------------------------------------------------- -// Returns true if the |canonicalized_host| matches or is in the same domain as -// the given |lower_ascii_domain| string. For example, if the canonicalized -// hostname is "www.google.com", this will return true for "com", "google.com", -// and "www.google.com" domains. +// Returns true if the |canonical_host| matches or is in the same domain as the +// given |canonical_domain| string. For example, if the canonicalized hostname +// is "www.google.com", this will return true for "com", "google.com", and +// "www.google.com" domains. // // If either of the input StringPieces is empty, the return value is false. The -// input domain should be a lower-case ASCII string in order to match the -// canonicalized host. -URL_EXPORT bool DomainIs(base::StringPiece canonicalized_host, - base::StringPiece lower_ascii_domain); +// input domain should match host canonicalization rules. i.e. it should be +// lowercase except for escape chars. +URL_EXPORT bool DomainIs(base::StringPiece canonical_host, + base::StringPiece canonical_domain); // Returns true if the hostname is an IP address. Note: this function isn't very // cheap, as it must re-parse the host to verify.