Index: content/browser/service_worker/service_worker_client_utils.cc |
diff --git a/content/browser/service_worker/service_worker_client_utils.cc b/content/browser/service_worker/service_worker_client_utils.cc |
index 2888bd48de6fa6f1f0374f70b58940686f576798..1211e4f3119e4927b46b54abb3a05e5a04e13087 100644 |
--- a/content/browser/service_worker/service_worker_client_utils.cc |
+++ b/content/browser/service_worker/service_worker_client_utils.cc |
@@ -102,6 +102,7 @@ class OpenURLObserver : public WebContentsObserver { |
ServiceWorkerClientInfo GetWindowClientInfoOnUI( |
int render_process_id, |
int render_frame_id, |
+ base::TimeTicks create_time, |
const std::string& client_uuid) { |
DCHECK_CURRENTLY_ON(BrowserThread::UI); |
RenderFrameHostImpl* render_frame_host = |
@@ -117,12 +118,13 @@ ServiceWorkerClientInfo GetWindowClientInfoOnUI( |
render_frame_host->IsFocused(), render_frame_host->GetLastCommittedURL(), |
render_frame_host->GetParent() ? REQUEST_CONTEXT_FRAME_TYPE_NESTED |
: REQUEST_CONTEXT_FRAME_TYPE_TOP_LEVEL, |
- render_frame_host->frame_tree_node()->last_focus_time(), |
+ render_frame_host->frame_tree_node()->last_focus_time(), create_time, |
blink::kWebServiceWorkerClientTypeWindow); |
} |
ServiceWorkerClientInfo FocusOnUI(int render_process_id, |
int render_frame_id, |
+ base::TimeTicks create_time, |
const std::string& client_uuid) { |
DCHECK_CURRENTLY_ON(BrowserThread::UI); |
RenderFrameHostImpl* render_frame_host = |
@@ -146,7 +148,7 @@ ServiceWorkerClientInfo FocusOnUI(int render_process_id, |
web_contents->Activate(); |
return GetWindowClientInfoOnUI(render_process_id, render_frame_id, |
- client_uuid); |
+ create_time, client_uuid); |
} |
// This is only called for main frame navigations in OpenWindowOnUI(). |
@@ -274,7 +276,8 @@ void DidNavigate(const base::WeakPtr<ServiceWorkerContextCore>& context, |
BrowserThread::PostTaskAndReplyWithResult( |
BrowserThread::UI, FROM_HERE, |
base::Bind(&GetWindowClientInfoOnUI, provider_host->process_id(), |
- provider_host->route_id(), provider_host->client_uuid()), |
+ provider_host->route_id(), provider_host->create_time(), |
+ provider_host->client_uuid()), |
base::Bind(callback, SERVICE_WORKER_OK)); |
return; |
} |
@@ -286,11 +289,13 @@ void DidNavigate(const base::WeakPtr<ServiceWorkerContextCore>& context, |
void AddWindowClient( |
ServiceWorkerProviderHost* host, |
- std::vector<std::tuple<int, int, std::string>>* client_info) { |
+ std::vector<std::tuple<int, int, base::TimeTicks, std::string>>* |
+ client_info) { |
DCHECK_CURRENTLY_ON(BrowserThread::IO); |
if (host->client_type() != blink::kWebServiceWorkerClientTypeWindow) |
return; |
client_info->push_back(std::make_tuple(host->process_id(), host->frame_id(), |
+ host->create_time(), |
host->client_uuid())); |
} |
@@ -309,21 +314,22 @@ void AddNonWindowClient(ServiceWorkerProviderHost* host, |
host->client_uuid(), blink::kWebPageVisibilityStateHidden, |
false, // is_focused |
host->document_url(), REQUEST_CONTEXT_FRAME_TYPE_NONE, base::TimeTicks(), |
- host_client_type); |
+ host->create_time(), host_client_type); |
clients->push_back(client_info); |
} |
void OnGetWindowClientsOnUI( |
- // The tuple contains process_id, frame_id, client_uuid. |
- const std::vector<std::tuple<int, int, std::string>>& clients_info, |
+ // The tuple contains process_id, frame_id, create_time, client_uuid. |
+ const std::vector<std::tuple<int, int, base::TimeTicks, std::string>>& |
+ clients_info, |
const GURL& script_url, |
- const GetWindowClientsCallback& callback) { |
+ const GetWindowClientsCallback& callback, |
+ std::unique_ptr<ServiceWorkerClients> clients) { |
DCHECK_CURRENTLY_ON(BrowserThread::UI); |
- std::unique_ptr<ServiceWorkerClients> clients(new ServiceWorkerClients); |
for (const auto& it : clients_info) { |
ServiceWorkerClientInfo info = GetWindowClientInfoOnUI( |
- std::get<0>(it), std::get<1>(it), std::get<2>(it)); |
+ std::get<0>(it), std::get<1>(it), std::get<2>(it), std::get<3>(it)); |
// If the request to the provider_host returned an empty |
// ServiceWorkerClientInfo, that means that it wasn't possible to associate |
@@ -345,37 +351,53 @@ void OnGetWindowClientsOnUI( |
base::Bind(callback, base::Passed(&clients))); |
} |
-struct ServiceWorkerClientInfoSortMRU { |
+struct ServiceWorkerClientInfoSort { |
bool operator()(const ServiceWorkerClientInfo& a, |
const ServiceWorkerClientInfo& b) const { |
- return a.last_focus_time > b.last_focus_time; |
+ // Clients for windows should be appeared earlier. |
+ if (a.client_type == blink::kWebServiceWorkerClientTypeWindow && |
+ b.client_type != blink::kWebServiceWorkerClientTypeWindow) { |
+ return true; |
+ } |
+ if (a.client_type != blink::kWebServiceWorkerClientTypeWindow && |
+ b.client_type == blink::kWebServiceWorkerClientTypeWindow) { |
+ return false; |
+ } |
+ |
+ // Clients focused recently should be appeared earlier. |
+ if (a.last_focus_time != b.last_focus_time) |
+ return a.last_focus_time > b.last_focus_time; |
+ |
+ // Clients created before should be appeared earlier. |
+ return a.create_time < b.create_time; |
} |
}; |
void DidGetClients(const ClientsCallback& callback, |
- ServiceWorkerClients* clients) { |
+ std::unique_ptr<ServiceWorkerClients> clients) { |
DCHECK_CURRENTLY_ON(BrowserThread::IO); |
- // Sort clients so that the most recently active tab is in the front. |
- std::sort(clients->begin(), clients->end(), ServiceWorkerClientInfoSortMRU()); |
+ std::sort(clients->begin(), clients->end(), ServiceWorkerClientInfoSort()); |
- callback.Run(clients); |
+ callback.Run(std::move(clients)); |
} |
void GetNonWindowClients(const base::WeakPtr<ServiceWorkerVersion>& controller, |
const ServiceWorkerClientQueryOptions& options, |
- ServiceWorkerClients* clients) { |
+ const ClientsCallback& callback, |
+ std::unique_ptr<ServiceWorkerClients> clients) { |
DCHECK_CURRENTLY_ON(BrowserThread::IO); |
if (!options.include_uncontrolled) { |
for (auto& controllee : controller->controllee_map()) |
- AddNonWindowClient(controllee.second, options, clients); |
+ AddNonWindowClient(controllee.second, options, clients.get()); |
} else if (controller->context()) { |
GURL origin = controller->script_url().GetOrigin(); |
for (auto it = controller->context()->GetClientProviderHostIterator(origin); |
!it->IsAtEnd(); it->Advance()) { |
- AddNonWindowClient(it->GetProviderHost(), options, clients); |
+ AddNonWindowClient(it->GetProviderHost(), options, clients.get()); |
} |
} |
+ DidGetClients(callback, std::move(clients)); |
} |
void DidGetWindowClients(const base::WeakPtr<ServiceWorkerVersion>& controller, |
@@ -383,19 +405,22 @@ void DidGetWindowClients(const base::WeakPtr<ServiceWorkerVersion>& controller, |
const ClientsCallback& callback, |
std::unique_ptr<ServiceWorkerClients> clients) { |
DCHECK_CURRENTLY_ON(BrowserThread::IO); |
- if (options.client_type == blink::kWebServiceWorkerClientTypeAll) |
- GetNonWindowClients(controller, options, clients.get()); |
- DidGetClients(callback, clients.get()); |
+ if (options.client_type == blink::kWebServiceWorkerClientTypeAll) { |
+ GetNonWindowClients(controller, options, callback, std::move(clients)); |
+ return; |
+ } |
+ DidGetClients(callback, std::move(clients)); |
} |
void GetWindowClients(const base::WeakPtr<ServiceWorkerVersion>& controller, |
const ServiceWorkerClientQueryOptions& options, |
- const ClientsCallback& callback) { |
+ const ClientsCallback& callback, |
+ std::unique_ptr<ServiceWorkerClients> clients) { |
DCHECK_CURRENTLY_ON(BrowserThread::IO); |
DCHECK(options.client_type == blink::kWebServiceWorkerClientTypeWindow || |
options.client_type == blink::kWebServiceWorkerClientTypeAll); |
- std::vector<std::tuple<int, int, std::string>> clients_info; |
+ std::vector<std::tuple<int, int, base::TimeTicks, std::string>> clients_info; |
if (!options.include_uncontrolled) { |
for (auto& controllee : controller->controllee_map()) |
AddWindowClient(controllee.second, &clients_info); |
@@ -408,8 +433,7 @@ void GetWindowClients(const base::WeakPtr<ServiceWorkerVersion>& controller, |
} |
if (clients_info.empty()) { |
- DidGetWindowClients(controller, options, callback, |
- base::WrapUnique(new ServiceWorkerClients)); |
+ DidGetWindowClients(controller, options, callback, std::move(clients)); |
return; |
} |
@@ -417,7 +441,8 @@ void GetWindowClients(const base::WeakPtr<ServiceWorkerVersion>& controller, |
BrowserThread::UI, FROM_HERE, |
base::Bind( |
&OnGetWindowClientsOnUI, clients_info, controller->script_url(), |
- base::Bind(&DidGetWindowClients, controller, options, callback))); |
+ base::Bind(&DidGetWindowClients, controller, options, callback), |
+ base::Passed(&clients))); |
} |
} // namespace |
@@ -430,7 +455,8 @@ void FocusWindowClient(ServiceWorkerProviderHost* provider_host, |
BrowserThread::PostTaskAndReplyWithResult( |
BrowserThread::UI, FROM_HERE, |
base::Bind(&FocusOnUI, provider_host->process_id(), |
- provider_host->frame_id(), provider_host->client_uuid()), |
+ provider_host->frame_id(), provider_host->create_time(), |
+ provider_host->client_uuid()), |
callback); |
} |
@@ -476,7 +502,8 @@ void GetClient(ServiceWorkerProviderHost* provider_host, |
BrowserThread::PostTaskAndReplyWithResult( |
BrowserThread::UI, FROM_HERE, |
base::Bind(&GetWindowClientInfoOnUI, provider_host->process_id(), |
- provider_host->route_id(), provider_host->client_uuid()), |
+ provider_host->route_id(), provider_host->create_time(), |
+ provider_host->client_uuid()), |
callback); |
return; |
} |
@@ -485,7 +512,8 @@ void GetClient(ServiceWorkerProviderHost* provider_host, |
provider_host->client_uuid(), blink::kWebPageVisibilityStateHidden, |
false, // is_focused |
provider_host->document_url(), REQUEST_CONTEXT_FRAME_TYPE_NONE, |
- base::TimeTicks(), provider_host->client_type()); |
+ base::TimeTicks(), provider_host->create_time(), |
+ provider_host->client_type()); |
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, |
base::Bind(callback, client_info)); |
} |
@@ -495,21 +523,20 @@ void GetClients(const base::WeakPtr<ServiceWorkerVersion>& controller, |
const ClientsCallback& callback) { |
DCHECK_CURRENTLY_ON(BrowserThread::IO); |
- ServiceWorkerClients clients; |
+ auto clients = base::MakeUnique<ServiceWorkerClients>(); |
if (!controller->HasControllee() && !options.include_uncontrolled) { |
- DidGetClients(callback, &clients); |
+ DidGetClients(callback, std::move(clients)); |
return; |
} |
// For Window clients we want to query the info on the UI thread first. |
if (options.client_type == blink::kWebServiceWorkerClientTypeWindow || |
options.client_type == blink::kWebServiceWorkerClientTypeAll) { |
- GetWindowClients(controller, options, callback); |
+ GetWindowClients(controller, options, callback, std::move(clients)); |
return; |
} |
- GetNonWindowClients(controller, options, &clients); |
- DidGetClients(callback, &clients); |
+ GetNonWindowClients(controller, options, callback, std::move(clients)); |
} |
} // namespace service_worker_client_utils |