Issue metadata
Sign in to add a comment
|
Service workers cannot start up inside <webview>
Reported by
ch...@radiusnetworks.com,
Nov 3 2017
|
||||||||||||||||||||||
Issue descriptionUserAgent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36 Platform: 9901.54.0 (Official Build) beta-channel sumo Steps to reproduce the problem: 1. Disable/Disconnect Network 2. Reboot Chrome Machine into Kiosk App What is the expected behavior? When the Chrome App launches for the first time, it should load the remote URL into the webview. Once loaded, the webapp's service worker should cache all its resources. Once loaded, the application should now serve all its resources from cache and not need to make external network requests. You can launch the Chrome App on Chrome OS in kiosk mode and it will cache its resources. Rebooting the app with the network on runs as expected and the resources are served from cache. What went wrong? If you turn off the network interface on the Chrome OS machine, unplug the ethernet cable (if it has a wired connection), or turn the power off on the wifi access point, the PWA will frequently fails to load, resulting in a "Dinosaur" screen with a ERR_INTERNET_DISCONNECTED message. It's important to note that this offline behavior is not consistent: Sometimes it will load properly, sometimes it will not. Did this work before? N/A Chrome version: 62.0.3202.74 Channel: beta OS Version: 62.0.3202.74 Flash Version: Attached the code for an example app that reproduces the error. Additionally the same source can be found on github here: https://github.com/RadiusNetworks/chrome-pwa-app-test The issue appeared in Kiosk as well as running the app interactively on the desktop. This was not an issue on M60 on the stable channel: Google Chrome Version 60.0.3112.114 Platform Version 9592.96.0 (Official Build) stable-channel ninja Firmware Version Google_Ninja.5216.383.7
,
Nov 7 2017
Watching this run on v62 Beta on a slow network (vs no network) I am also getting a time out error:
<webview>: The load has aborted with error -7: ERR_TIMED_OUT.
,
Nov 7 2017
Apologies, that last comment said I was running v62, but I am actually on v63. The current system information:
Google Chrome Version
63.0.3239.26
Platform Version
10032.21.0 (Official Build) beta-channel veyron_tiger
Firmware Version
Google_Veyron_Tiger.6588.237.0
,
Nov 7 2017
Please let us know if you are seeing this issue in M62 stable. Thanks.
,
Nov 7 2017
,
Nov 9 2017
I was able to reproduce this with M62 stable. Followed the these steps:
- Load the example app as a kiosk app in CDM
- Launch the app and allow all content to cache
- Reboot into the chrome desktop and disable wi-fi (or unplug the network cable)
- Reboot back into the kiosk app
- The dinosaur "There is no internet" error screen will be shown, but was expecting the cached content from the PWA
ChromeOS details:
Google Chrome Version
62.0.3202.82
Platform Version
9901.66.0 (Official Build) stable-channel veyron_tiger
Firmware Version
Google_Veyron_Tiger.6588.237.0
TPM Firmware Version
34080
,
Nov 9 2017
Hey Sergey, it looks like a regression with WebView. Can you please look into it?
,
Nov 15 2017
Why is this a regression? I don't see that this ever worked? But yes, if this app is using a service worker we should understand why network calls are failing since it shouldn't rely on that. This might be an interesting bug for isandrk@ to look at, btw.
,
Nov 15 2017
Ivan, could you try to reproduce it. I think the unexpected part here is "this offline behavior is not consistent: Sometimes it will load properly, sometimes it will not."
,
Nov 16 2017
Haven't reproduced it yet, but took a wild stab at it. Caches have a pre-determined maximum size, and when things get over or close to it, some things need to get evicted - perhaps that's what's happening here (and the "inconsistency" of the cache makes me suspect that this is maybe the culprit). Chris: Can you try using the navigator.storage.persist API to get a persistent cache that won't get evicted and tell me if it fixes the problem? Thanks! Links: [1] http://deanhume.com/home/blogpost/persistent-storage-api--building-for-the-offline-web/10161 [2] https://storage.spec.whatwg.org/
,
Nov 16 2017
Chris: Actually another question - do you see this behaviour only in kiosks, or do you also see it in regular sessions?
,
Nov 16 2017
,
Nov 16 2017
Added the call:
Persistent storage granted? true
Will test this in offline mode and report back.
Not sure we are exceeding the "pre-determined maximum size", since our proof of concept test app comes in at 22kb for the total size for all files and images. Is there a way to query for what this value is from an app?
We have seen this in both kiosk and running the app in a regular chrome desktop session. But most of the testing has been done in kiosk mode.
,
Nov 21 2017
We had the chance to test with the addition of the `navigator.storage.persist` API. Unfortunately still able to reproduce the issue.
,
Nov 22 2017
Since this is not kiosk specific, I will transfer this to someone who's more knowledgeable in this area. Devlin: do you perhaps know who's a good owner for this?
,
Nov 22 2017
This seems to be a problem between <webview> and service worker. Assigning to wjmaclean@ for webview triage; cc falken@ for SW expertise. chris@, one thing that would be good to confirm is whether you have been able to reproduce this outside of a webview (i.e., just a PWA, skipping the Chrome App wrapper and kiosk mode).
,
Nov 22 2017
Oh, this is interesting. When running the PWA on Chrome OS in the normal Chrome browser it works as expected. And on that same machine I ran the Chrome app with the embedded `webview` tag, and that exhibited problems. I was able to run them side-by-side and reproduce the problem in one but not the other. The details of this testing: I have two versions of the PWA app running here: - PWA embedded in in a `webview` running in a Chrome App, aka "Chrome App" - PWA running in the browser, aka the "Browser App" I ran through the following test cases: 1. Turn off wifi at the device 2. Reboot the device with wifi turned off 3. Disconnect upstream network access to the internet from the wifi router Test case 1: Turn off wifi at the device - Browser App works as expected - Chrome App works as expected Test case 2: Reboot the device with wifi turned off - Browser App works as expected - Chrome App loads with a full screen dinosaur (see "no-network" screenshot) Test case 3: Disconnect upstream network - Browser App works as expected - Chrome App fails to load video content that is rotated in a frame (see "dissconnect-upstream" screenshot) The results of these tests with the Chrome App match the behavior of the same app running in Kiosk mode.
,
Nov 22 2017
So this sounds a lot like Issue 711486, which had a work-around fix landed for it in 63.0.3233.0 and that was also merged back to 62.0.3202.72. What version of Chrome was used for the tests reported in c#17 ?
,
Nov 24 2017
62.0.3202.82 is the version we are testing. We will update to the latest 62 stable and reverify
,
Nov 27 2017
The full details of the version that we are testing with: Google Chrome Version 62.0.3202.82 Platform Version 9901.66.0 (Official Build) stable-channel veyron_mickey Firmware Version Google_Veyron_Mickey.6588.264.0 This looks like it is past the version were the fix was backported. Can you confirm that we would expect it to work .82? We are continuing to test and it is failing consistently per #17 on 62.0.3202.82. Happy to provide more details if that is helpful.
,
Nov 28 2017
falken@ - Is there any chance this could be an issue with the service workers that handled offline caches for PWAs not correctly picking up on the WebView's different storage partition?
,
Nov 29 2017
Is the service worker relying on indexeddb? Could this be https://bugs.chromium.org/p/chromium/issues/detail?id=783159#c5
,
Nov 29 2017
This isn't Android WebView, it's BrowserTag WebView (for Chrome apps) ... though presumably the bug could affect both.
,
Nov 29 2017
Regarding c#22, I have little idea how the BrowserTag WebView storage partition differs from the usual one. But I presume if the service worker was registered while in that storage partition and Cache Storage caches were installed while in that storage partition, then when loading a page while in that storage partition you'll get the service worker and caches. ServiceWorkerContext and CacheStorageContext hang off of StoragePartition here: https://cs.chromium.org/chromium/src/content/public/browser/storage_partition.h?l=87&rcl=b29928a66d4b3b9d379249d23e383abfd4544efe I can't find old/existing bugs about BrowserTag WebView and ServiceWorker. I'm not aware of anything recently that could have regressed this, except for the IndexedDB thing above, though I suspect that should only affect Android WebView.
,
Nov 29 2017
The service worker at https://github.com/RadiusNetworks/chrome-pwa-app-test does not appear to use IndexedDB. Is it possible to minimize the service worker to something that just returns `new Response('hello world');` in the fetch event? And could we bisect this easily on Linux or does it require building and installing an entire Chrome OS on a Chromebook?
,
Nov 29 2017
Just to confirm, non of the apps where we've seen this issue are using IndexedDB. Do make heavy use of service workers for caching however.
,
Dec 1 2017
I've been poking at this using a CrOS + Linux build. I see that when the app is run we get [40234:40263:1201/131045.273375:ERROR:service_worker_registration_status.cc(97)] NOTREACHED() hit. The error is SERVICE_WORKER_ERROR_IPC_FAILED I haven't (yet) been able to simulate loss of network connectivity in my Linux test environment, but it seems the service worker is just not running at all? The guest's console prints out the following: Registration failed with UnknownError: Failed to register a ServiceWorker: IPC connection was closed or IPC error has occurred.
,
Dec 1 2017
falken@ - here are some more details on the detection of the IPC failure, any thoughts? So the IPC failure is being detected in EmbeddedWorkerInstance::SendStartWorker(), at https://cs.chromium.org/chromium/src/content/browser/service_worker/embedded_worker_instance.cc?rcl=2049eab9c7aebd498738ef8375d927b7ecc30b34&l=650 Here is the complete logging output from the time I start my test CrOS + Linux session until the chrome app has loaded (note the service_manager.cc errors): ATTENTION: default value of option force_s3tc_enable overridden by environment. [4366:4366:1201/145225.109140:ERROR:sandbox_linux.cc(375)] InitializeSandbox() called with multiple threads in process gpu-process. [4329:4329:1201/145225.144525:ERROR:input_method_manager_impl.cc(1031)] IMEEngine for "fgoepimhcoialccpbmpnnblemnepkkao" is not registered [4329:4329:1201/145225.171934:ERROR:network_sms_handler.cc(410)] NetworkSmsHandler: No list value for: Devices [4329:4360:1201/145225.620084:ERROR:service_manager.cc(158)] Connection InterfaceProviderSpec prevented service: content_browser from binding interface: content::mojom::Child exposed by: nacl_loader [4329:4360:1201/145225.620151:ERROR:service_manager.cc(158)] Connection InterfaceProviderSpec prevented service: content_browser from binding interface: content::mojom::ChildControl exposed by: nacl_loader [4329:4360:1201/145225.623168:ERROR:service_manager.cc(158)] Connection InterfaceProviderSpec prevented service: content_browser from binding interface: content::mojom::ChildHistogramFetcherFactory exposed by: nacl_loader [1,1994708864:19:52:25.623343] Native Client module will be loaded at base address 0x00004cea00000000 [4329:4329:1201/145235.151637:ERROR:tab_manager_delegate_chromeos.cc(82)] Set OOM score error: <-- Output below this line occurs when I start the "Chrome PWA Test" app --> <-- Lines starting with wjm: and the stacktrace are from debugging code I've added to my test build --> wjm: EmbeddedWorkerInstance::SendStartWorker() IPC_FAILED [4329:4360:1201/145251.913447:ERROR:service_worker_registration_status.cc(29)] status = 9 wjm: GetServiceWorkerErrorTypeForRegistration() [4329:4360:1201/145251.913469:ERROR:service_worker_registration_status.cc(73)] SERVICE_WORKER_ERROR_IPC_FAILED #0 0x55912d8a053c base::debug::StackTrace::StackTrace() #1 0x55912c5988be content::GetServiceWorkerErrorTypeForRegistration() #2 0x55912c58a544 content::ServiceWorkerProviderHost::RegistrationComplete() #3 0x55912c58d6b8 _ZN4base8internal7InvokerINS0_9BindStateIMN7content25ServiceWorkerProviderHostEFvNS_12OnceCallbackIFvN5blink5mojom22ServiceWorkerErrorTypeERKNS_8OptionalINSt3__112basic_stringIcNSA_11char_traitsIcEENSA_9allocatorIcEEEEEEN4mojo9StructPtrINS7_35ServiceWorkerRegistrationObjectInfoEEEEEElNS3_23ServiceWorkerStatusCodeERKSG_lEJNS_7WeakPtrIS4_EESP_lEEEFvSQ_SS_lEE7RunOnceEPNS0_13BindStateBaseESQ_SS_l #4 0x55912c2c36d7 _ZN4base8internal31AdaptCallbackForRepeatingHelperIJN7storage15QuotaStatusCodeEllEE3RunES3_ll #5 0x55912c5907fe content::ServiceWorkerRegisterJob::CompleteInternal() #6 0x55912c591328 content::ServiceWorkerRegisterJob::OnStartWorkerFinished() #7 0x55912c5bcf2a _ZN4base8internal7InvokerINS0_9BindStateIZN7content20ServiceWorkerVersion39DidEnsureLiveRegistrationForStartWorkerENS3_20ServiceWorkerMetrics9EventTypeENS4_6StatusEbNS_12OnceCallbackIFvNS3_23ServiceWorkerStatusCodeEEEES9_13scoped_refptrINS3_25ServiceWorkerRegistrationEEE3$_0JSB_SE_EEESA_E7RunOnceEPNS0_13BindStateBaseES9_ #8 0x55912c5b9e95 content::ServiceWorkerVersion::OnStartSentAndScriptEvaluated() #9 0x55912c546e9f content::EmbeddedWorkerInstance::OnStartFailed() #10 0x55912c5479e3 content::EmbeddedWorkerInstance::StartTask::OnSetupCompleted() #11 0x55912c5481cb _ZN4base8internal13FunctorTraitsIMN7content22EmbeddedWorkerInstance9StartTaskEFvNS2_23ServiceWorkerStatusCodeENSt3__110unique_ptrINS2_25EmbeddedWorkerStartParamsENS6_14default_deleteIS8_EEEENS7_INS2_27ServiceWorkerProcessManager20AllocatedProcessInfoENS9_ISD_EEEENS7_INS3_13DevToolsProxyENS9_ISG_EEEEEvE6InvokeINS_7WeakPtrIS4_EEJS5_SB_SF_SI_EEEvSK_OT_DpOT0_ #12 0x55912c548125 _ZN4base8internal7InvokerINS0_9BindStateIMN7content22EmbeddedWorkerInstance9StartTaskEFvNS3_23ServiceWorkerStatusCodeENSt3__110unique_ptrINS3_25EmbeddedWorkerStartParamsENS7_14default_deleteIS9_EEEENS8_INS3_27ServiceWorkerProcessManager20AllocatedProcessInfoENSA_ISE_EEEENS8_INS4_13DevToolsProxyENSA_ISH_EEEEEJNS_7WeakPtrIS5_EEEEEFvS6_SC_SG_SJ_EE7RunOnceEPNS0_13BindStateBaseES6_OSC_OSG_OSJ_ #13 0x55912c547e82 _ZN4base8internal13FunctorTraitsINS_12OnceCallbackIFvN7content23ServiceWorkerStatusCodeENSt3__110unique_ptrINS3_25EmbeddedWorkerStartParamsENS5_14default_deleteIS7_EEEENS6_INS3_27ServiceWorkerProcessManager20AllocatedProcessInfoENS8_ISC_EEEENS6_INS3_22EmbeddedWorkerInstance13DevToolsProxyENS8_ISG_EEEEEEEvE6InvokeISK_JS4_SA_SE_SI_EEEvOT_DpOT0_ #14 0x55912d8a0caf base::debug::TaskAnnotator::RunTask() #15 0x55912d8b83e7 base::MessageLoop::RunTask() #16 0x55912d8b88c9 base::MessageLoop::DoWork() #17 0x55912d8b9a39 base::MessagePumpLibevent::Run() #18 0x55912d8d6904 base::RunLoop::Run() #19 0x55912c2a6b78 content::BrowserThreadImpl::IOThreadRun() #20 0x55912c2a6d06 content::BrowserThreadImpl::Run() #21 0x55912d8fcecd base::Thread::ThreadMain() #22 0x55912d8f7e5d base::(anonymous namespace)::ThreadFunc() #23 0x7fd71e494184 start_thread #24 0x7fd71b193ffd clone [4329:4360:1201/145252.047846:ERROR:service_worker_registration_status.cc(100)] NOTREACHED() hit.
,
Dec 4 2017
Thanks for the output! The IPC error code is a signal that the process we selected the service worker to run isn't setup as expected at this point in the startup process. Let me try to debug.
,
Dec 4 2017
Thanks, I see the problem.
This may have regressed when we added the SiteInstance stuff for service worker.
When we try to find a renderer process to start the service worker in, we ask SiteInstance for one, arriving at RenderProcessHostImpl::GetProcessHostForSiteInstance(). This function tries lots of things to reuse an existing process, and as a last resort creates a new RenderProcessHostImpl. In this bug, we hit this last resort which means we arrive at RenderProcessHostImpl::CreateOrUseSpareRenderProcessHost(). This function is intentionally passed a null storage partition:
// Pass a null StoragePartition. Tests with TestBrowserContext using a
// RenderProcessHostFactory may not instantiate a StoragePartition, and
// creating one here with GetStoragePartition() can run into cross-thread
// issues as TestBrowserContext initialization is done on the main thread.
So we end up in BrowserContext::GetStoragePartition to find a storage partition for the RPH, which in this bug creates a new storage partition. That's not good because the process must be associated with the same storage partition as the service worker installation.
My proposed fix is to plumb the StoragePartition to SiteInstance when we call set_is_for_service_worker(). Working on a patch.
I'm not too clear on why BrowserTag <webview> hits this easily and we haven't detected the issue on other platforms though.
,
Dec 4 2017
Re your question in c#31, I'm trying to find out if there are any other examples of (real world) cases where PWAs are loaded in OOPIFS ... the timing for WebView can be a bit tricky, as the renderer process may exist before the embedder "attaches" it, in the process giving it the SiteInstance appropriate to the content being loaded into it. It seems Twitter and FlipKart specify x-frame-options: SAMEORIGIN so we can't try them in an OOPIF.
,
Dec 5 2017
Thanks for looking. I do know our UMA has indicated IPC_FAILED before though it's possible that also could be different bugs.
I'd be curious if we can reproduce this outside of <webview> even on a toy PWA: like just a page that registers a service worker that just does console.log('hello').
,
Dec 5 2017
Have a patch here: https://chromium-review.googlesource.com/c/chromium/src/+/807973
,
Dec 15 2017
The following revision refers to this bug: https://chromium.googlesource.com/chromium/src.git/+/24abf78274e01a17c4f0a4c8cc18e55720f3b3b9 commit 24abf78274e01a17c4f0a4c8cc18e55720f3b3b9 Author: Matt Falkenhagen <falken@chromium.org> Date: Fri Dec 15 23:55:11 2017 service worker: Teach StoragePartition the Site URL to use for service workers. The "service worker context" is attached to a StoragePartition. When this context tries to start a service worker, it asks SiteInstance for a process to start the worker in. This process must be in the same StoragePartition as the context. In some cases like the <webview> tag, a non-default StoragePartition is created for guests, but the service worker was trying to start up in a process for the default StoragePartition since it created a SiteInstance using the script URL of the worker (e.g., https://www.example.com) and got a process from that. The solution is to stash the site URL on the StoragePartition when it's for guests (e.g., chrome-guest://someapp/somepath), and have service worker use that site URL when creating a SiteInstance. Bug: 781313 , 752667 Change-Id: I8bf7ee8fd78a42e6c4e23684160c18da4e5189e5 Reviewed-on: https://chromium-review.googlesource.com/807973 Reviewed-by: Kinuko Yasuda <kinuko@chromium.org> Reviewed-by: Scott Violet <sky@chromium.org> Reviewed-by: Tsuyoshi Horo <horo@chromium.org> Reviewed-by: Alex Moshchuk <alexmos@chromium.org> Commit-Queue: Matt Falkenhagen <falken@chromium.org> Cr-Commit-Position: refs/heads/master@{#524528} [modify] https://crrev.com/24abf78274e01a17c4f0a4c8cc18e55720f3b3b9/chrome/browser/chromeos/power/renderer_freezer_unittest.cc [modify] https://crrev.com/24abf78274e01a17c4f0a4c8cc18e55720f3b3b9/chrome/browser/media_galleries/media_file_system_registry_unittest.cc [modify] https://crrev.com/24abf78274e01a17c4f0a4c8cc18e55720f3b3b9/chrome/browser/metrics/chrome_stability_metrics_provider_unittest.cc [modify] https://crrev.com/24abf78274e01a17c4f0a4c8cc18e55720f3b3b9/components/visitedlink/test/visitedlink_unittest.cc [modify] https://crrev.com/24abf78274e01a17c4f0a4c8cc18e55720f3b3b9/content/browser/renderer_host/render_process_host_impl.cc [modify] https://crrev.com/24abf78274e01a17c4f0a4c8cc18e55720f3b3b9/content/browser/renderer_host/render_process_host_unittest.cc [modify] https://crrev.com/24abf78274e01a17c4f0a4c8cc18e55720f3b3b9/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper_unittest.mm [modify] https://crrev.com/24abf78274e01a17c4f0a4c8cc18e55720f3b3b9/content/browser/renderer_host/text_input_client_mac_unittest.mm [modify] https://crrev.com/24abf78274e01a17c4f0a4c8cc18e55720f3b3b9/content/browser/service_worker/service_worker_context_wrapper.cc [modify] https://crrev.com/24abf78274e01a17c4f0a4c8cc18e55720f3b3b9/content/browser/service_worker/service_worker_context_wrapper.h [modify] https://crrev.com/24abf78274e01a17c4f0a4c8cc18e55720f3b3b9/content/browser/service_worker/service_worker_process_manager.cc [modify] https://crrev.com/24abf78274e01a17c4f0a4c8cc18e55720f3b3b9/content/browser/service_worker/service_worker_process_manager.h [modify] https://crrev.com/24abf78274e01a17c4f0a4c8cc18e55720f3b3b9/content/browser/service_worker/service_worker_process_manager_unittest.cc [modify] https://crrev.com/24abf78274e01a17c4f0a4c8cc18e55720f3b3b9/content/browser/storage_partition_impl.h [modify] https://crrev.com/24abf78274e01a17c4f0a4c8cc18e55720f3b3b9/content/public/browser/render_process_host_factory.h [modify] https://crrev.com/24abf78274e01a17c4f0a4c8cc18e55720f3b3b9/content/public/test/mock_render_process_host.cc [modify] https://crrev.com/24abf78274e01a17c4f0a4c8cc18e55720f3b3b9/content/public/test/mock_render_process_host.h
,
Dec 18 2017
This should be fixed in 65.0.3296.0. As per code review comments, I filed a new bug for improving test coverage: issue 795625. Probably we should at least add a browser test for service worker + <webview>. But I likely don't have time to do this before going on holiday break.
,
Dec 18 2017
Since this is a significant regression, we should merge to M64 at least. +dskaram FYI
,
Dec 18 2017
This bug requires manual review: M64 has already been promoted to the beta branch, so this requires manual review Please contact the milestone owner if you have questions. Owners: cmasso@(Android), cmasso@(iOS), kbleicher@(ChromeOS), abdulsyed@(Desktop) For more details visit https://www.chromium.org/issue-tracking/autotriage - Your friendly Sheriffbot
,
Dec 18 2017
,
Dec 18 2017
Hi all, this was referred to as "a significant regression" per #37, but I haven't caught that reading the thread. If this wasn't working in M63 and earlier it's not a M64 regression.
,
Dec 18 2017
Comment 31 said it was a regression. But yeah, not sure when exactly it broke - agreed that if it *didn't* break in M63 then there's an argument for not backmerging.
,
Dec 18 2017
+1 for M64 as well (per #41)
,
Dec 19 2017
The comments above indicate this is broken in 62, and was working in 60. I'm not sure exactly when it started breaking, we had added SiteInstance + service worker code between 60-63. It'd also be good to verify end-to-end this is working on a Chromebook running Canary/Dev CrOS past 65.0.3296.0. I fixed the failure of the service worker to startup as reported at c#28, and verified that in a Linux/CrOS build the service worker is now starting up with the provided app via --load-and-launch-app=Downloads/chrome-pwa-app-test-master Looks like current Dev is still 64.
,
Dec 19 2017
I've verified the app loads even when Linux has no network connection. Of course, you must have loaded the app at least one time before to install the service worker, which is loaded from Amazon AWS.
,
Dec 19 2017
How significant is the impact? Doesn't seem major if the initial occurance isn't well defined? Really a P1?
,
Jan 17 2018
Let's wait for M65 since this merge is rather big and problem is not new on M64 Please feel free to re request if any urgency to get this on M64 |
|||||||||||||||||||||||
►
Sign in to add a comment |
|||||||||||||||||||||||
Comment 1 by e...@chromium.org
, Nov 7 2017