Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "chrome/browser/media/router/event_page_request_manager.h" | |
| 6 | |
| 7 #include "base/bind.h" | |
| 8 #include "base/logging.h" | |
| 9 #include "base/macros.h" | |
| 10 #include "chrome/browser/media/router/mojo/media_router_mojo_metrics.h" | |
| 11 #include "extensions/browser/event_page_tracker.h" | |
| 12 #include "extensions/browser/process_manager.h" | |
| 13 #include "extensions/browser/process_manager_factory.h" | |
| 14 | |
| 15 namespace media_router { | |
| 16 | |
| 17 EventPageRequestManager::~EventPageRequestManager() = default; | |
| 18 | |
| 19 void EventPageRequestManager::Shutdown() { | |
| 20 event_page_tracker_ = nullptr; | |
| 21 } | |
| 22 | |
| 23 void EventPageRequestManager::SetWakeReason( | |
| 24 MediaRouteProviderWakeReason reason) { | |
| 25 DCHECK(reason != MediaRouteProviderWakeReason::TOTAL_COUNT); | |
| 26 if (current_wake_reason_ == MediaRouteProviderWakeReason::TOTAL_COUNT) | |
| 27 current_wake_reason_ = reason; | |
| 28 } | |
| 29 | |
| 30 void EventPageRequestManager::SetExtensionId(const std::string& extension_id) { | |
| 31 media_route_provider_extension_id_ = extension_id; | |
| 32 } | |
| 33 | |
| 34 void EventPageRequestManager::RunOrDefer(base::OnceClosure request) { | |
| 35 if (mojo_connections_ready_) { | |
| 36 DCHECK(!media_route_provider_extension_id_.empty()); | |
| 37 std::move(request).Run(); | |
| 38 } else { | |
| 39 EnqueueRequest(std::move(request)); | |
| 40 if (IsEventPageSuspended()) | |
| 41 AttemptWakeEventPage(); | |
| 42 } | |
| 43 } | |
| 44 | |
| 45 void EventPageRequestManager::OnMojoConnectionsReady() { | |
| 46 if (IsEventPageSuspended()) { | |
| 47 DVLOG(1) | |
| 48 << "OnMojoConnectionsReady was called while extension is suspended."; | |
| 49 SetWakeReason(MediaRouteProviderWakeReason::REGISTER_MEDIA_ROUTE_PROVIDER); | |
| 50 AttemptWakeEventPage(); | |
| 51 return; | |
| 52 } | |
| 53 | |
| 54 mojo_connections_ready_ = true; | |
| 55 for (auto& next_request : pending_requests_) | |
| 56 std::move(next_request).Run(); | |
| 57 pending_requests_.clear(); | |
| 58 wakeup_attempt_count_ = 0; | |
| 59 } | |
| 60 | |
| 61 void EventPageRequestManager::OnMojoConnectionError() { | |
| 62 mojo_connections_ready_ = false; | |
| 63 | |
| 64 // If this method is invoked while there are pending requests, then | |
| 65 // it means we tried to wake the extension, but weren't able to complete the | |
| 66 // connection to media route provider. Since we do not know whether the error | |
| 67 // is transient, reattempt the wakeup. | |
| 68 if (!pending_requests_.empty()) { | |
| 69 DLOG(ERROR) << "A connection error while there are pending requests."; | |
| 70 SetWakeReason(MediaRouteProviderWakeReason::CONNECTION_ERROR); | |
| 71 AttemptWakeEventPage(); | |
| 72 } | |
| 73 } | |
| 74 | |
| 75 EventPageRequestManager::EventPageRequestManager( | |
| 76 content::BrowserContext* context) | |
| 77 : event_page_tracker_(extensions::ProcessManager::Get(context)), | |
| 78 current_wake_reason_(MediaRouteProviderWakeReason::TOTAL_COUNT), | |
| 79 weak_factory_(this) {} | |
| 80 | |
| 81 void EventPageRequestManager::EnqueueRequest(base::OnceClosure closure) { | |
|
imcheng
2017/06/30 00:17:38
s/closure/request for consistency.
takumif
2017/07/01 01:16:44
Done.
| |
| 82 pending_requests_.push_back(std::move(closure)); | |
| 83 if (pending_requests_.size() > kMaxPendingRequests) { | |
| 84 DLOG(ERROR) << "Reached max queue size. Dropping oldest request."; | |
| 85 pending_requests_.pop_front(); | |
| 86 } | |
| 87 DVLOG(2) << "EnqueueRequest (queue-length=" << pending_requests_.size() | |
| 88 << ")"; | |
| 89 } | |
| 90 | |
| 91 void EventPageRequestManager::DrainPendingRequests() { | |
| 92 DLOG(ERROR) << "Draining request queue. (queue-length=" | |
| 93 << pending_requests_.size() << ")"; | |
| 94 pending_requests_.clear(); | |
| 95 } | |
| 96 | |
| 97 bool EventPageRequestManager::IsEventPageSuspended() { | |
| 98 return !event_page_tracker_ || event_page_tracker_->IsEventPageSuspended( | |
| 99 media_route_provider_extension_id_); | |
| 100 } | |
| 101 | |
| 102 void EventPageRequestManager::AttemptWakeEventPage() { | |
| 103 ++wakeup_attempt_count_; | |
| 104 if (wakeup_attempt_count_ > kMaxWakeupAttemptCount) { | |
| 105 DLOG(ERROR) << "Attempted too many times to wake up event page."; | |
| 106 DrainPendingRequests(); | |
| 107 wakeup_attempt_count_ = 0; | |
| 108 MediaRouterMojoMetrics::RecordMediaRouteProviderWakeup( | |
| 109 MediaRouteProviderWakeup::ERROR_TOO_MANY_RETRIES); | |
| 110 return; | |
| 111 } | |
| 112 | |
| 113 DVLOG(1) << "Attempting to wake up event page: attempt " | |
| 114 << wakeup_attempt_count_; | |
| 115 if (!event_page_tracker_) { | |
| 116 DLOG(ERROR) << "Attempted to wake up event page without a valid event page" | |
| 117 "tracker"; | |
| 118 return; | |
| 119 } | |
| 120 | |
| 121 // This return false if the extension is already awake. | |
| 122 // Callback is bound using WeakPtr because |event_page_tracker_| outlives | |
| 123 // |this|. | |
| 124 if (!event_page_tracker_->WakeEventPage( | |
| 125 media_route_provider_extension_id_, | |
| 126 base::Bind(&EventPageRequestManager::OnWakeComplete, | |
| 127 weak_factory_.GetWeakPtr()))) { | |
| 128 DLOG(ERROR) << "Failed to schedule a wakeup for event page."; | |
| 129 } | |
| 130 } | |
| 131 | |
| 132 void EventPageRequestManager::OnWakeComplete(bool success) { | |
| 133 if (success) { | |
| 134 MediaRouterMojoMetrics::RecordMediaRouteProviderWakeReason( | |
| 135 current_wake_reason_); | |
| 136 ClearWakeReason(); | |
| 137 MediaRouterMojoMetrics::RecordMediaRouteProviderWakeup( | |
| 138 MediaRouteProviderWakeup::SUCCESS); | |
| 139 return; | |
| 140 } | |
| 141 | |
| 142 // This is likely an non-retriable error. Drop the pending requests. | |
| 143 DLOG(ERROR) << "An error encountered while waking the event page."; | |
| 144 ClearWakeReason(); | |
| 145 DrainPendingRequests(); | |
| 146 MediaRouterMojoMetrics::RecordMediaRouteProviderWakeup( | |
| 147 MediaRouteProviderWakeup::ERROR_UNKNOWN); | |
| 148 } | |
| 149 | |
| 150 void EventPageRequestManager::ClearWakeReason() { | |
| 151 DCHECK(current_wake_reason_ != MediaRouteProviderWakeReason::TOTAL_COUNT); | |
| 152 current_wake_reason_ = MediaRouteProviderWakeReason::TOTAL_COUNT; | |
| 153 } | |
| 154 | |
| 155 } // namespace media_router | |
| OLD | NEW |