OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/browser/service_worker/service_worker_version.h" | 5 #include "content/browser/service_worker/service_worker_version.h" |
6 | 6 |
7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
8 #include "base/memory/ref_counted.h" | 8 #include "base/memory/ref_counted.h" |
9 #include "base/metrics/histogram_macros.h" | 9 #include "base/metrics/histogram_macros.h" |
10 #include "base/stl_util.h" | 10 #include "base/stl_util.h" |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
85 template <typename IDMAP, typename... Params> | 85 template <typename IDMAP, typename... Params> |
86 void RunIDMapCallbacks(IDMAP* callbacks, const Params&... params) { | 86 void RunIDMapCallbacks(IDMAP* callbacks, const Params&... params) { |
87 typename IDMAP::iterator iter(callbacks); | 87 typename IDMAP::iterator iter(callbacks); |
88 while (!iter.IsAtEnd()) { | 88 while (!iter.IsAtEnd()) { |
89 iter.GetCurrentValue()->Run(params...); | 89 iter.GetCurrentValue()->Run(params...); |
90 iter.Advance(); | 90 iter.Advance(); |
91 } | 91 } |
92 callbacks->Clear(); | 92 callbacks->Clear(); |
93 } | 93 } |
94 | 94 |
| 95 template <typename CallbackType, typename... Params> |
| 96 bool RunIDMapCallback(IDMap<CallbackType, IDMapOwnPointer>* callbacks, |
| 97 int request_id, |
| 98 const Params&... params) { |
| 99 CallbackType* callback = callbacks->Lookup(request_id); |
| 100 if (!callback) |
| 101 return false; |
| 102 |
| 103 callback->Run(params...); |
| 104 callbacks->Remove(request_id); |
| 105 return true; |
| 106 } |
| 107 |
95 void RunStartWorkerCallback( | 108 void RunStartWorkerCallback( |
96 const StatusCallback& callback, | 109 const StatusCallback& callback, |
97 scoped_refptr<ServiceWorkerRegistration> protect, | 110 scoped_refptr<ServiceWorkerRegistration> protect, |
98 ServiceWorkerStatusCode status) { | 111 ServiceWorkerStatusCode status) { |
99 callback.Run(status); | 112 callback.Run(status); |
100 } | 113 } |
101 | 114 |
102 // A callback adapter to start a |task| after StartWorker. | 115 // A callback adapter to start a |task| after StartWorker. |
103 void RunTaskAfterStartWorker( | 116 void RunTaskAfterStartWorker( |
104 base::WeakPtr<ServiceWorkerVersion> version, | 117 base::WeakPtr<ServiceWorkerVersion> version, |
(...skipping 30 matching lines...) Expand all Loading... |
135 // Transfering the message ports failed, so destroy the ports. | 148 // Transfering the message ports failed, so destroy the ports. |
136 for (const TransferredMessagePort& port : sent_message_ports) { | 149 for (const TransferredMessagePort& port : sent_message_ports) { |
137 MessagePortService::GetInstance()->ClosePort(port.id); | 150 MessagePortService::GetInstance()->ClosePort(port.id); |
138 } | 151 } |
139 callback.Run(status); | 152 callback.Run(status); |
140 } | 153 } |
141 | 154 |
142 void RunErrorCrossOriginConnectCallback( | 155 void RunErrorCrossOriginConnectCallback( |
143 const ServiceWorkerVersion::CrossOriginConnectCallback& callback, | 156 const ServiceWorkerVersion::CrossOriginConnectCallback& callback, |
144 ServiceWorkerStatusCode status) { | 157 ServiceWorkerStatusCode status) { |
145 callback.Run(status, false); | 158 callback.Run(status, false /* accept_connection */); |
146 } | 159 } |
147 | 160 |
148 using WindowOpenedCallback = base::Callback<void(int, int)>; | 161 using WindowOpenedCallback = base::Callback<void(int, int)>; |
149 | 162 |
150 // The WindowOpenedObserver class is a WebContentsObserver that will wait for a | 163 // The WindowOpenedObserver class is a WebContentsObserver that will wait for a |
151 // new Window's WebContents to be initialized, run the |callback| passed to its | 164 // new Window's WebContents to be initialized, run the |callback| passed to its |
152 // constructor then self destroy. | 165 // constructor then self destroy. |
153 // The callback will receive the process and frame ids. If something went wrong | 166 // The callback will receive the process and frame ids. If something went wrong |
154 // those will be (kInvalidUniqueID, MSG_ROUTING_NONE). | 167 // those will be (kInvalidUniqueID, MSG_ROUTING_NONE). |
155 // The callback will be called in the IO thread. | 168 // The callback will be called in the IO thread. |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
297 clients.push_back(info); | 310 clients.push_back(info); |
298 } | 311 } |
299 | 312 |
300 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, | 313 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, |
301 base::Bind(callback, clients)); | 314 base::Bind(callback, clients)); |
302 } | 315 } |
303 | 316 |
304 } // namespace | 317 } // namespace |
305 | 318 |
306 const int ServiceWorkerVersion::kStartWorkerTimeoutMinutes = 5; | 319 const int ServiceWorkerVersion::kStartWorkerTimeoutMinutes = 5; |
| 320 const int ServiceWorkerVersion::kRequestTimeoutMinutes = 5; |
307 | 321 |
308 ServiceWorkerVersion::ServiceWorkerVersion( | 322 ServiceWorkerVersion::ServiceWorkerVersion( |
309 ServiceWorkerRegistration* registration, | 323 ServiceWorkerRegistration* registration, |
310 const GURL& script_url, | 324 const GURL& script_url, |
311 int64 version_id, | 325 int64 version_id, |
312 base::WeakPtr<ServiceWorkerContextCore> context) | 326 base::WeakPtr<ServiceWorkerContextCore> context) |
313 : version_id_(version_id), | 327 : version_id_(version_id), |
314 registration_id_(kInvalidServiceWorkerVersionId), | 328 registration_id_(kInvalidServiceWorkerVersionId), |
315 script_url_(script_url), | 329 script_url_(script_url), |
316 status_(NEW), | 330 status_(NEW), |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
529 base::Bind(&self::DispatchFetchEvent, | 543 base::Bind(&self::DispatchFetchEvent, |
530 weak_factory_.GetWeakPtr(), | 544 weak_factory_.GetWeakPtr(), |
531 request, | 545 request, |
532 prepare_callback, | 546 prepare_callback, |
533 fetch_callback))); | 547 fetch_callback))); |
534 return; | 548 return; |
535 } | 549 } |
536 | 550 |
537 prepare_callback.Run(); | 551 prepare_callback.Run(); |
538 | 552 |
539 int request_id = fetch_callbacks_.Add(new FetchCallback(fetch_callback)); | 553 int request_id = AddRequest(fetch_callback, &fetch_callbacks_, REQUEST_FETCH); |
540 ServiceWorkerStatusCode status = embedded_worker_->SendMessage( | 554 ServiceWorkerStatusCode status = embedded_worker_->SendMessage( |
541 ServiceWorkerMsg_FetchEvent(request_id, request)); | 555 ServiceWorkerMsg_FetchEvent(request_id, request)); |
542 if (status != SERVICE_WORKER_OK) { | 556 if (status != SERVICE_WORKER_OK) { |
543 fetch_callbacks_.Remove(request_id); | 557 fetch_callbacks_.Remove(request_id); |
544 RunSoon(base::Bind(&RunErrorFetchCallback, | 558 RunSoon(base::Bind(&RunErrorFetchCallback, |
545 fetch_callback, | 559 fetch_callback, |
546 SERVICE_WORKER_ERROR_FAILED)); | 560 SERVICE_WORKER_ERROR_FAILED)); |
547 } | 561 } |
548 } | 562 } |
549 | 563 |
550 void ServiceWorkerVersion::DispatchSyncEvent(const StatusCallback& callback) { | 564 void ServiceWorkerVersion::DispatchSyncEvent(const StatusCallback& callback) { |
551 DCHECK_EQ(ACTIVATED, status()) << status(); | 565 DCHECK_EQ(ACTIVATED, status()) << status(); |
552 | 566 |
553 if (!base::CommandLine::ForCurrentProcess()->HasSwitch( | 567 if (!base::CommandLine::ForCurrentProcess()->HasSwitch( |
554 switches::kEnableServiceWorkerSync)) { | 568 switches::kEnableServiceWorkerSync)) { |
555 callback.Run(SERVICE_WORKER_ERROR_ABORT); | 569 callback.Run(SERVICE_WORKER_ERROR_ABORT); |
556 return; | 570 return; |
557 } | 571 } |
558 | 572 |
559 if (running_status() != RUNNING) { | 573 if (running_status() != RUNNING) { |
560 // Schedule calling this method after starting the worker. | 574 // Schedule calling this method after starting the worker. |
561 StartWorker(base::Bind(&RunTaskAfterStartWorker, | 575 StartWorker(base::Bind(&RunTaskAfterStartWorker, |
562 weak_factory_.GetWeakPtr(), callback, | 576 weak_factory_.GetWeakPtr(), callback, |
563 base::Bind(&self::DispatchSyncEvent, | 577 base::Bind(&self::DispatchSyncEvent, |
564 weak_factory_.GetWeakPtr(), | 578 weak_factory_.GetWeakPtr(), |
565 callback))); | 579 callback))); |
566 return; | 580 return; |
567 } | 581 } |
568 | 582 |
569 int request_id = sync_callbacks_.Add(new StatusCallback(callback)); | 583 int request_id = AddRequest(callback, &sync_callbacks_, REQUEST_SYNC); |
570 ServiceWorkerStatusCode status = embedded_worker_->SendMessage( | 584 ServiceWorkerStatusCode status = embedded_worker_->SendMessage( |
571 ServiceWorkerMsg_SyncEvent(request_id)); | 585 ServiceWorkerMsg_SyncEvent(request_id)); |
572 if (status != SERVICE_WORKER_OK) { | 586 if (status != SERVICE_WORKER_OK) { |
573 sync_callbacks_.Remove(request_id); | 587 sync_callbacks_.Remove(request_id); |
574 RunSoon(base::Bind(callback, status)); | 588 RunSoon(base::Bind(callback, status)); |
575 } | 589 } |
576 } | 590 } |
577 | 591 |
578 void ServiceWorkerVersion::DispatchNotificationClickEvent( | 592 void ServiceWorkerVersion::DispatchNotificationClickEvent( |
579 const StatusCallback& callback, | 593 const StatusCallback& callback, |
580 const std::string& notification_id, | 594 const std::string& notification_id, |
581 const PlatformNotificationData& notification_data) { | 595 const PlatformNotificationData& notification_data) { |
582 DCHECK_EQ(ACTIVATED, status()) << status(); | 596 DCHECK_EQ(ACTIVATED, status()) << status(); |
583 if (running_status() != RUNNING) { | 597 if (running_status() != RUNNING) { |
584 // Schedule calling this method after starting the worker. | 598 // Schedule calling this method after starting the worker. |
585 StartWorker(base::Bind(&RunTaskAfterStartWorker, | 599 StartWorker(base::Bind(&RunTaskAfterStartWorker, |
586 weak_factory_.GetWeakPtr(), callback, | 600 weak_factory_.GetWeakPtr(), callback, |
587 base::Bind(&self::DispatchNotificationClickEvent, | 601 base::Bind(&self::DispatchNotificationClickEvent, |
588 weak_factory_.GetWeakPtr(), | 602 weak_factory_.GetWeakPtr(), |
589 callback, notification_id, | 603 callback, notification_id, |
590 notification_data))); | 604 notification_data))); |
591 return; | 605 return; |
592 } | 606 } |
593 | 607 |
594 int request_id = | 608 int request_id = AddRequest(callback, ¬ification_click_callbacks_, |
595 notification_click_callbacks_.Add(new StatusCallback(callback)); | 609 REQUEST_NOTIFICATION_CLICK); |
596 ServiceWorkerStatusCode status = embedded_worker_->SendMessage( | 610 ServiceWorkerStatusCode status = embedded_worker_->SendMessage( |
597 ServiceWorkerMsg_NotificationClickEvent(request_id, | 611 ServiceWorkerMsg_NotificationClickEvent(request_id, |
598 notification_id, | 612 notification_id, |
599 notification_data)); | 613 notification_data)); |
600 if (status != SERVICE_WORKER_OK) { | 614 if (status != SERVICE_WORKER_OK) { |
601 notification_click_callbacks_.Remove(request_id); | 615 notification_click_callbacks_.Remove(request_id); |
602 RunSoon(base::Bind(callback, status)); | 616 RunSoon(base::Bind(callback, status)); |
603 } | 617 } |
604 } | 618 } |
605 | 619 |
606 void ServiceWorkerVersion::DispatchPushEvent(const StatusCallback& callback, | 620 void ServiceWorkerVersion::DispatchPushEvent(const StatusCallback& callback, |
607 const std::string& data) { | 621 const std::string& data) { |
608 DCHECK_EQ(ACTIVATED, status()) << status(); | 622 DCHECK_EQ(ACTIVATED, status()) << status(); |
609 if (running_status() != RUNNING) { | 623 if (running_status() != RUNNING) { |
610 // Schedule calling this method after starting the worker. | 624 // Schedule calling this method after starting the worker. |
611 StartWorker(base::Bind(&RunTaskAfterStartWorker, | 625 StartWorker(base::Bind(&RunTaskAfterStartWorker, |
612 weak_factory_.GetWeakPtr(), callback, | 626 weak_factory_.GetWeakPtr(), callback, |
613 base::Bind(&self::DispatchPushEvent, | 627 base::Bind(&self::DispatchPushEvent, |
614 weak_factory_.GetWeakPtr(), | 628 weak_factory_.GetWeakPtr(), |
615 callback, data))); | 629 callback, data))); |
616 return; | 630 return; |
617 } | 631 } |
618 | 632 |
619 int request_id = push_callbacks_.Add(new StatusCallback(callback)); | 633 int request_id = AddRequest(callback, &push_callbacks_, REQUEST_PUSH); |
620 ServiceWorkerStatusCode status = embedded_worker_->SendMessage( | 634 ServiceWorkerStatusCode status = embedded_worker_->SendMessage( |
621 ServiceWorkerMsg_PushEvent(request_id, data)); | 635 ServiceWorkerMsg_PushEvent(request_id, data)); |
622 if (status != SERVICE_WORKER_OK) { | 636 if (status != SERVICE_WORKER_OK) { |
623 push_callbacks_.Remove(request_id); | 637 push_callbacks_.Remove(request_id); |
624 RunSoon(base::Bind(callback, status)); | 638 RunSoon(base::Bind(callback, status)); |
625 } | 639 } |
626 } | 640 } |
627 | 641 |
628 void ServiceWorkerVersion::DispatchGeofencingEvent( | 642 void ServiceWorkerVersion::DispatchGeofencingEvent( |
629 const StatusCallback& callback, | 643 const StatusCallback& callback, |
(...skipping 15 matching lines...) Expand all Loading... |
645 callback, | 659 callback, |
646 base::Bind(&self::DispatchGeofencingEvent, | 660 base::Bind(&self::DispatchGeofencingEvent, |
647 weak_factory_.GetWeakPtr(), | 661 weak_factory_.GetWeakPtr(), |
648 callback, | 662 callback, |
649 event_type, | 663 event_type, |
650 region_id, | 664 region_id, |
651 region))); | 665 region))); |
652 return; | 666 return; |
653 } | 667 } |
654 | 668 |
655 int request_id = geofencing_callbacks_.Add(new StatusCallback(callback)); | 669 int request_id = |
| 670 AddRequest(callback, &geofencing_callbacks_, REQUEST_GEOFENCING); |
656 ServiceWorkerStatusCode status = | 671 ServiceWorkerStatusCode status = |
657 embedded_worker_->SendMessage(ServiceWorkerMsg_GeofencingEvent( | 672 embedded_worker_->SendMessage(ServiceWorkerMsg_GeofencingEvent( |
658 request_id, event_type, region_id, region)); | 673 request_id, event_type, region_id, region)); |
659 if (status != SERVICE_WORKER_OK) { | 674 if (status != SERVICE_WORKER_OK) { |
660 geofencing_callbacks_.Remove(request_id); | 675 geofencing_callbacks_.Remove(request_id); |
661 RunSoon(base::Bind(callback, status)); | 676 RunSoon(base::Bind(callback, status)); |
662 } | 677 } |
663 } | 678 } |
664 | 679 |
665 void ServiceWorkerVersion::DispatchCrossOriginConnectEvent( | 680 void ServiceWorkerVersion::DispatchCrossOriginConnectEvent( |
(...skipping 10 matching lines...) Expand all Loading... |
676 if (running_status() != RUNNING) { | 691 if (running_status() != RUNNING) { |
677 // Schedule calling this method after starting the worker. | 692 // Schedule calling this method after starting the worker. |
678 StartWorker( | 693 StartWorker( |
679 base::Bind(&RunTaskAfterStartWorker, weak_factory_.GetWeakPtr(), | 694 base::Bind(&RunTaskAfterStartWorker, weak_factory_.GetWeakPtr(), |
680 base::Bind(&RunErrorCrossOriginConnectCallback, callback), | 695 base::Bind(&RunErrorCrossOriginConnectCallback, callback), |
681 base::Bind(&self::DispatchCrossOriginConnectEvent, | 696 base::Bind(&self::DispatchCrossOriginConnectEvent, |
682 weak_factory_.GetWeakPtr(), callback, client))); | 697 weak_factory_.GetWeakPtr(), callback, client))); |
683 return; | 698 return; |
684 } | 699 } |
685 | 700 |
686 int request_id = cross_origin_connect_callbacks_.Add( | 701 int request_id = AddRequest(callback, &cross_origin_connect_callbacks_, |
687 new CrossOriginConnectCallback(callback)); | 702 REQUEST_CROSS_ORIGIN_CONNECT); |
688 ServiceWorkerStatusCode status = embedded_worker_->SendMessage( | 703 ServiceWorkerStatusCode status = embedded_worker_->SendMessage( |
689 ServiceWorkerMsg_CrossOriginConnectEvent(request_id, client)); | 704 ServiceWorkerMsg_CrossOriginConnectEvent(request_id, client)); |
690 if (status != SERVICE_WORKER_OK) { | 705 if (status != SERVICE_WORKER_OK) { |
691 cross_origin_connect_callbacks_.Remove(request_id); | 706 cross_origin_connect_callbacks_.Remove(request_id); |
692 RunSoon(base::Bind(callback, status, false)); | 707 RunSoon(base::Bind(callback, status, false)); |
693 } | 708 } |
694 } | 709 } |
695 | 710 |
696 void ServiceWorkerVersion::DispatchCrossOriginMessageEvent( | 711 void ServiceWorkerVersion::DispatchCrossOriginMessageEvent( |
697 const NavigatorConnectClient& client, | 712 const NavigatorConnectClient& client, |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
773 if (is_doomed_) | 788 if (is_doomed_) |
774 return; | 789 return; |
775 is_doomed_ = true; | 790 is_doomed_ = true; |
776 if (!HasControllee()) | 791 if (!HasControllee()) |
777 DoomInternal(); | 792 DoomInternal(); |
778 } | 793 } |
779 | 794 |
780 void ServiceWorkerVersion::SetDevToolsAttached(bool attached) { | 795 void ServiceWorkerVersion::SetDevToolsAttached(bool attached) { |
781 embedded_worker()->set_devtools_attached(attached); | 796 embedded_worker()->set_devtools_attached(attached); |
782 if (attached) { | 797 if (attached) { |
| 798 // TODO(falken): Canceling the timeouts when debugging could cause |
| 799 // heisenbugs; we should instead run them as normal show an educational |
| 800 // message in DevTools when they occur. crbug.com/470419 |
| 801 |
783 // Don't record the startup time metric once DevTools is attached. | 802 // Don't record the startup time metric once DevTools is attached. |
784 ClearTick(&start_time_); | 803 ClearTick(&start_time_); |
785 skip_recording_startup_time_ = true; | 804 skip_recording_startup_time_ = true; |
| 805 |
| 806 // Cancel request timeouts. |
| 807 SetAllRequestTimes(base::TimeTicks()); |
786 return; | 808 return; |
787 } | 809 } |
788 if (!start_callbacks_.empty()) { | 810 if (!start_callbacks_.empty()) { |
789 // Reactivate the timer for start timeout. | 811 // Reactivate the timer for start timeout. |
790 DCHECK(timeout_timer_.IsRunning()); | 812 DCHECK(timeout_timer_.IsRunning()); |
791 DCHECK(running_status() == STARTING || running_status() == STOPPING) | 813 DCHECK(running_status() == STARTING || running_status() == STOPPING) |
792 << running_status(); | 814 << running_status(); |
793 RestartTick(&start_time_); | 815 RestartTick(&start_time_); |
794 } | 816 } |
| 817 |
| 818 // Reactivate request timeouts. |
| 819 SetAllRequestTimes(base::TimeTicks::Now()); |
795 } | 820 } |
796 | 821 |
797 void ServiceWorkerVersion::SetMainScriptHttpResponseInfo( | 822 void ServiceWorkerVersion::SetMainScriptHttpResponseInfo( |
798 const net::HttpResponseInfo& http_info) { | 823 const net::HttpResponseInfo& http_info) { |
799 main_script_http_info_.reset(new net::HttpResponseInfo(http_info)); | 824 main_script_http_info_.reset(new net::HttpResponseInfo(http_info)); |
800 } | 825 } |
801 | 826 |
802 const net::HttpResponseInfo* | 827 const net::HttpResponseInfo* |
803 ServiceWorkerVersion::GetMainScriptHttpResponseInfo() { | 828 ServiceWorkerVersion::GetMainScriptHttpResponseInfo() { |
804 return main_script_http_info_.get(); | 829 return main_script_http_info_.get(); |
805 } | 830 } |
806 | 831 |
| 832 ServiceWorkerVersion::RequestInfo::RequestInfo(int id, RequestType type) |
| 833 : id(id), type(type), time(base::TimeTicks::Now()) { |
| 834 } |
| 835 |
| 836 ServiceWorkerVersion::RequestInfo::~RequestInfo() { |
| 837 } |
| 838 |
807 void ServiceWorkerVersion::OnScriptLoaded() { | 839 void ServiceWorkerVersion::OnScriptLoaded() { |
808 DCHECK_EQ(STARTING, running_status()); | 840 DCHECK_EQ(STARTING, running_status()); |
809 // Activate ping/pong now that JavaScript execution will start. | 841 // Activate ping/pong now that JavaScript execution will start. |
810 ping_state_ = PINGING; | 842 ping_state_ = PINGING; |
811 } | 843 } |
812 | 844 |
813 void ServiceWorkerVersion::OnStarting() { | 845 void ServiceWorkerVersion::OnStarting() { |
814 FOR_EACH_OBSERVER(Listener, listeners_, OnRunningStateChanged(this)); | 846 FOR_EACH_OBSERVER(Listener, listeners_, OnRunningStateChanged(this)); |
815 } | 847 } |
816 | 848 |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
959 ServiceWorkerStatusCode status) { | 991 ServiceWorkerStatusCode status) { |
960 if (status != SERVICE_WORKER_OK) | 992 if (status != SERVICE_WORKER_OK) |
961 RunCallbacks(this, &start_callbacks_, status); | 993 RunCallbacks(this, &start_callbacks_, status); |
962 } | 994 } |
963 | 995 |
964 void ServiceWorkerVersion::DispatchInstallEventAfterStartWorker( | 996 void ServiceWorkerVersion::DispatchInstallEventAfterStartWorker( |
965 const StatusCallback& callback) { | 997 const StatusCallback& callback) { |
966 DCHECK_EQ(RUNNING, running_status()) | 998 DCHECK_EQ(RUNNING, running_status()) |
967 << "Worker stopped too soon after it was started."; | 999 << "Worker stopped too soon after it was started."; |
968 | 1000 |
969 int request_id = install_callbacks_.Add(new StatusCallback(callback)); | 1001 int request_id = AddRequest(callback, &install_callbacks_, REQUEST_INSTALL); |
970 ServiceWorkerStatusCode status = embedded_worker_->SendMessage( | 1002 ServiceWorkerStatusCode status = embedded_worker_->SendMessage( |
971 ServiceWorkerMsg_InstallEvent(request_id)); | 1003 ServiceWorkerMsg_InstallEvent(request_id)); |
972 if (status != SERVICE_WORKER_OK) { | 1004 if (status != SERVICE_WORKER_OK) { |
973 install_callbacks_.Remove(request_id); | 1005 install_callbacks_.Remove(request_id); |
974 RunSoon(base::Bind(callback, status)); | 1006 RunSoon(base::Bind(callback, status)); |
975 } | 1007 } |
976 } | 1008 } |
977 | 1009 |
978 void ServiceWorkerVersion::DispatchActivateEventAfterStartWorker( | 1010 void ServiceWorkerVersion::DispatchActivateEventAfterStartWorker( |
979 const StatusCallback& callback) { | 1011 const StatusCallback& callback) { |
980 DCHECK_EQ(RUNNING, running_status()) | 1012 DCHECK_EQ(RUNNING, running_status()) |
981 << "Worker stopped too soon after it was started."; | 1013 << "Worker stopped too soon after it was started."; |
982 | 1014 |
983 int request_id = activate_callbacks_.Add(new StatusCallback(callback)); | 1015 int request_id = AddRequest(callback, &activate_callbacks_, REQUEST_ACTIVATE); |
984 ServiceWorkerStatusCode status = | 1016 ServiceWorkerStatusCode status = |
985 embedded_worker_->SendMessage(ServiceWorkerMsg_ActivateEvent(request_id)); | 1017 embedded_worker_->SendMessage(ServiceWorkerMsg_ActivateEvent(request_id)); |
986 if (status != SERVICE_WORKER_OK) { | 1018 if (status != SERVICE_WORKER_OK) { |
987 activate_callbacks_.Remove(request_id); | 1019 activate_callbacks_.Remove(request_id); |
988 RunSoon(base::Bind(callback, status)); | 1020 RunSoon(base::Bind(callback, status)); |
989 } | 1021 } |
990 } | 1022 } |
991 | 1023 |
992 void ServiceWorkerVersion::OnGetClients( | 1024 void ServiceWorkerVersion::OnGetClients( |
993 int request_id, | 1025 int request_id, |
(...skipping 540 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1534 base::TimeDelta::FromMinutes(kStartWorkerTimeoutMinutes)) { | 1566 base::TimeDelta::FromMinutes(kStartWorkerTimeoutMinutes)) { |
1535 DCHECK(running_status() == STARTING || running_status() == STOPPING) | 1567 DCHECK(running_status() == STARTING || running_status() == STOPPING) |
1536 << running_status(); | 1568 << running_status(); |
1537 scoped_refptr<ServiceWorkerVersion> protect(this); | 1569 scoped_refptr<ServiceWorkerVersion> protect(this); |
1538 RunCallbacks(this, &start_callbacks_, SERVICE_WORKER_ERROR_TIMEOUT); | 1570 RunCallbacks(this, &start_callbacks_, SERVICE_WORKER_ERROR_TIMEOUT); |
1539 if (running_status() == STARTING) | 1571 if (running_status() == STARTING) |
1540 embedded_worker_->Stop(); | 1572 embedded_worker_->Stop(); |
1541 return; | 1573 return; |
1542 } | 1574 } |
1543 | 1575 |
1544 // This check occurs after the start_time_ timeout check, since in that case | 1576 // Requests have not finished within a certain period. |
1545 // the start callbacks should fail with ERROR_TIMEOUT. In the other timeout | 1577 bool request_timed_out = false; |
1546 // checks, there's nothing more to do as the worker is already stopping. | 1578 while (!requests_.empty()) { |
| 1579 RequestInfo info = requests_.front(); |
| 1580 if (GetTickDuration(info.time) < |
| 1581 base::TimeDelta::FromMinutes(kRequestTimeoutMinutes)) |
| 1582 break; |
| 1583 if (OnRequestTimeout(info)) |
| 1584 request_timed_out = true; |
| 1585 requests_.pop(); |
| 1586 } |
| 1587 if (request_timed_out && running_status() != STOPPING) |
| 1588 embedded_worker_->Stop(); |
| 1589 |
| 1590 // For the timeouts below, there are no callbacks to timeout so there is |
| 1591 // nothing more to do if the worker is already stopping. |
1547 if (running_status() == STOPPING) | 1592 if (running_status() == STOPPING) |
1548 return; | 1593 return; |
1549 | 1594 |
1550 // The worker has been idle for longer than a certain period. | 1595 // The worker has been idle for longer than a certain period. |
1551 if (GetTickDuration(idle_time_) > | 1596 if (GetTickDuration(idle_time_) > |
1552 base::TimeDelta::FromSeconds(kIdleWorkerTimeoutSeconds)) { | 1597 base::TimeDelta::FromSeconds(kIdleWorkerTimeoutSeconds)) { |
1553 StopWorkerIfIdle(); | 1598 StopWorkerIfIdle(); |
1554 return; | 1599 return; |
1555 } | 1600 } |
1556 | 1601 |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1674 IDMAP* callbacks, | 1719 IDMAP* callbacks, |
1675 int request_id) { | 1720 int request_id) { |
1676 callbacks->Remove(request_id); | 1721 callbacks->Remove(request_id); |
1677 if (is_doomed_) { | 1722 if (is_doomed_) { |
1678 // The stop should be already scheduled, but try to stop immediately, in | 1723 // The stop should be already scheduled, but try to stop immediately, in |
1679 // order to release worker resources soon. | 1724 // order to release worker resources soon. |
1680 StopWorkerIfIdle(); | 1725 StopWorkerIfIdle(); |
1681 } | 1726 } |
1682 } | 1727 } |
1683 | 1728 |
| 1729 template <typename CallbackType> |
| 1730 int ServiceWorkerVersion::AddRequest( |
| 1731 const CallbackType& callback, |
| 1732 IDMap<CallbackType, IDMapOwnPointer>* callback_map, |
| 1733 RequestType request_type) { |
| 1734 int request_id = callback_map->Add(new CallbackType(callback)); |
| 1735 requests_.push(RequestInfo(request_id, request_type)); |
| 1736 return request_id; |
| 1737 } |
| 1738 |
| 1739 bool ServiceWorkerVersion::OnRequestTimeout(const RequestInfo& info) { |
| 1740 switch (info.type) { |
| 1741 case REQUEST_ACTIVATE: |
| 1742 return RunIDMapCallback(&activate_callbacks_, info.id, |
| 1743 SERVICE_WORKER_ERROR_TIMEOUT); |
| 1744 case REQUEST_INSTALL: |
| 1745 return RunIDMapCallback(&install_callbacks_, info.id, |
| 1746 SERVICE_WORKER_ERROR_TIMEOUT); |
| 1747 case REQUEST_FETCH: |
| 1748 return RunIDMapCallback( |
| 1749 &fetch_callbacks_, info.id, SERVICE_WORKER_ERROR_TIMEOUT, |
| 1750 /* The other args are ignored for non-OK status. */ |
| 1751 SERVICE_WORKER_FETCH_EVENT_RESULT_FALLBACK, ServiceWorkerResponse()); |
| 1752 case REQUEST_SYNC: |
| 1753 return RunIDMapCallback(&sync_callbacks_, info.id, |
| 1754 SERVICE_WORKER_ERROR_TIMEOUT); |
| 1755 case REQUEST_NOTIFICATION_CLICK: |
| 1756 return RunIDMapCallback(¬ification_click_callbacks_, info.id, |
| 1757 SERVICE_WORKER_ERROR_TIMEOUT); |
| 1758 case REQUEST_PUSH: |
| 1759 return RunIDMapCallback(&push_callbacks_, info.id, |
| 1760 SERVICE_WORKER_ERROR_TIMEOUT); |
| 1761 case REQUEST_GEOFENCING: |
| 1762 return RunIDMapCallback(&geofencing_callbacks_, info.id, |
| 1763 SERVICE_WORKER_ERROR_TIMEOUT); |
| 1764 case REQUEST_CROSS_ORIGIN_CONNECT: |
| 1765 return RunIDMapCallback(&cross_origin_connect_callbacks_, info.id, |
| 1766 SERVICE_WORKER_ERROR_TIMEOUT, |
| 1767 false /* accept_connection */); |
| 1768 } |
| 1769 NOTREACHED() << "Got unexpected request type: " << info.type; |
| 1770 return false; |
| 1771 } |
| 1772 |
| 1773 void ServiceWorkerVersion::SetAllRequestTimes(const base::TimeTicks& ticks) { |
| 1774 std::queue<RequestInfo> new_requests; |
| 1775 while (!requests_.empty()) { |
| 1776 RequestInfo info = requests_.front(); |
| 1777 info.time = ticks; |
| 1778 new_requests.push(info); |
| 1779 requests_.pop(); |
| 1780 } |
| 1781 requests_ = new_requests; |
| 1782 } |
| 1783 |
1684 } // namespace content | 1784 } // namespace content |
OLD | NEW |