Disabling then re-enabling SiteNotificationChannels can trigger a crash |
|||
Issue descriptionChrome Version: (copy from chrome://version) OS: (e.g. Win7, OSX 10.9.5, etc...) What steps will reproduce the problem? (0) Cherry-pick the Unmigration CL changes here: https://chromium-review.googlesource.com/c/chromium/src/+/628680 (should soon ship) (1) Ensure the flag is enabled: build/android/adb_chrome_public_command_line --enable-features=SiteNotificationChannels (2) Grant notification permission to tests.peter.sh (3) Disable the flag: build/android/adb_chrome_public_command_line "" (4) Kill & restart the app (5) Block notification permission for tests.peter.sh via site settings (6) Enable the flag as in (1) (7) Kill & restart the app What is the expected result? No crash and the block setting is migrated so a new channel is created as blocked What happens instead? Crash: '[FATAL:notification_channels_provider_android.cc(385)] Check failed: old_chan nel_status == new_channel_status (1 vs. 0) It seems we crash because the pref provider returns a rule iterator with two rules in for the origin - both BLOCK, and ALLOW. We dcheck when trying to create a channel for the second one. I don't know why the pref provider returns two rules for the same origin - we only call SetWebsiteSetting on it once during the unmigration process. Some local logs that might help: 08-24 16:58:47.470 W/chromium(17501): [WARNING:notification_channels_provider_android.cc(186)] ANITA: MigrateToChannelsIfNecessary 08-24 16:58:47.470 W/chromium(17501): [WARNING:notification_channels_provider_android.cc(421)] ANITA: InitCachedChannels 08-24 16:58:47.476 W/chromium(17501): [WARNING:notification_channels_provider_android.cc(188)] ANITA: MigrateToChannelsIfNecessary Initialized cache. 08-24 16:58:47.476 W/chromium(17501): [WARNING:notification_channels_provider_android.cc(399)] ANITA: CreateChannelForRule origin=https://tests.peter.sh, setting=2 08-24 16:58:47.476 W/chromium(17501): [WARNING:notification_channels_provider_android.cc(365)] ANITA: CreateChannelIfRequired origin=https://tests.peter.sh, status=1 08-24 16:58:47.476 W/chromium(17501): [WARNING:notification_channels_provider_android.cc(371)] ANITA: CreateChannelIfRequired cache miss 08-24 16:58:47.483 W/chromium(17501): [WARNING:notification_channels_provider_android.cc(399)] ANITA: CreateChannelForRule origin=https://tests.peter.sh, setting=1 08-24 16:58:47.483 W/chromium(17501): [WARNING:notification_channels_provider_android.cc(365)] ANITA: CreateChannelIfRequired origin=https://tests.peter.sh, status=0 08-24 16:58:47.483 W/chromium(17501): [WARNING:notification_channels_provider_android.cc(382)] ANITA: CreateChannelIfRequired cache hit
,
Aug 24 2017
I've done some poking and my suspicion is because of the inconsistent treatment of the port between url::Origin::Serialize -> ContentSettingsPattern::FromString and GURL -> ContentSettingsPattern::FromURLNoWildcard. url::Origin::Serialize() strips the port if it's the default port for the scheme (https://cs.chromium.org/chromium/src/url/scheme_host_port.cc?type=cs&sq=package:chromium&l=217). Then using ContentSettingsPattern::FromString sets the port to a wildcard (https://cs.chromium.org/chromium/src/components/content_settings/core/common/content_settings_pattern_parser.cc?gsn=Parse&l=167). However, ContentSettingsPattern::FromURLNoWildcard (which is used by SetWebsiteSetting) explicitly keeps the port, and if the port isn't there, it adds the default port, not a wildcard (https://cs.chromium.org/chromium/src/components/content_settings/core/common/content_settings_pattern.cc?type=cs&q=components/content_settings/core/common/content_settings_pattern.cc&sq=package:chromium&l=387). So you have this behaviour: 1. Allow permission (port = 443) 2. Migrate (creates channels with the port stripped out) 3. Unmigrate (uses ContentSettingsPattern::FromString on url::Origin::Serialize, no port) At this point we have two conflicting rules: one for port 443, and one for *. Can you try keeping to using the same code path as what settings does (i.e. ContentSettingsPattern::FromURLNoWildcard from a GURL)?
,
Aug 25 2017
Agree with your hypothesis - adding a log in content_settings_pref_provider confirmed it: ... unmigrate ... 08-25 10:46:20.477 W/chromium(25834): [WARNING:content_settings_pref_provider.cc(149)] ANITA: SetWebsiteSetting pattern=https://tests.peter.sh ... block site from site settings ... 08-25 10:47:22.513 W/chromium(25834): [WARNING:content_settings_pref_provider.cc(149)] ANITA: SetWebsiteSetting pattern=https://tests.peter.sh:443 , changing ContentSettingsPattern::FromString(..) --> ContentSettingsPattern::FromURLNoWildcard(GURL(...)) where I construct the pattern from the channel origin means they both get the port and only one rule is then returned so the crash goes away - hooray! Thanks so much for your help figuring this out - saved me a bunch of debugging :) Now I just need to figure out how to write a regression test for this!
,
Aug 30 2017
I've done a quick fix in the interests of expediency as per #3 here: https://chromium-review.googlesource.com/c/chromium/src/+/643069 Filed crbug.com/760510 to make it use the same codepath as SetWebsiteSetting in future as suggested in #2. I think that's a really good idea but it'll take a little longer.
,
Aug 30 2017
The following revision refers to this bug: https://chromium.googlesource.com/chromium/src.git/+/42bb1dd7d8e7836997e0207d472e15c65bbc2aad commit 42bb1dd7d8e7836997e0207d472e15c65bbc2aad Author: Anita Woodruff <awdf@chromium.org> Date: Wed Aug 30 14:11:52 2017 [Android notification channels] Quick fix for flag re-enabling crash - Previously the ContentSettingsPrefProvider could end up storing two conflicting notification settings for the same origin after unmigrating channel settings, due to recreating the ContentSettingsPattern from the channel origin inconsistently with how it is created when setting a website pattern in the normal way. This meant we would sometimes fail a DCHECK in the channels provider when re-migrating to channel settings. - This change makes the construction of a ContentSettingsPattern from a channel origin string consistent with how ContentSettingPatterns are constructed via HostContentSettingsMap.SetWebsiteSetting - first convert to a GURL, then use ContentSettingsPattern::FromURLNoWildCard. - A proper fix would involve going through HCSM.SetWebsiteSetting, to ensure this is always done consistently - filed crbug.com/760510 to do this. Bug: 758635 Change-Id: I468075e62f7dce7f092389fb72f9d02f89925902 Reviewed-on: https://chromium-review.googlesource.com/643069 Commit-Queue: Anita Woodruff <awdf@chromium.org> Reviewed-by: Peter Beverloo <peter@chromium.org> Cr-Commit-Position: refs/heads/master@{#498451} [modify] https://crrev.com/42bb1dd7d8e7836997e0207d472e15c65bbc2aad/chrome/browser/notifications/notification_channels_provider_android.cc [modify] https://crrev.com/42bb1dd7d8e7836997e0207d472e15c65bbc2aad/chrome/browser/notifications/notification_channels_provider_android_unittest.cc
,
Aug 30 2017
|
|||
►
Sign in to add a comment |
|||
Comment 1 by awdf@chromium.org
, Aug 24 2017