OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "chrome/browser/ui/webui/options/content_settings_handler.h" | 5 #include "chrome/browser/ui/webui/options/content_settings_handler.h" |
6 | 6 |
| 7 #include <map> |
7 #include <string> | 8 #include <string> |
8 #include <vector> | 9 #include <vector> |
9 | 10 |
10 #include "base/callback.h" | 11 #include "base/callback.h" |
11 #include "base/command_line.h" | 12 #include "base/command_line.h" |
12 #include "base/utf_string_conversions.h" | 13 #include "base/utf_string_conversions.h" |
13 #include "base/values.h" | 14 #include "base/values.h" |
14 #include "chrome/browser/browser_process.h" | 15 #include "chrome/browser/browser_process.h" |
15 #include "chrome/browser/content_settings/content_settings_details.h" | 16 #include "chrome/browser/content_settings/content_settings_details.h" |
| 17 #include "chrome/browser/content_settings/content_settings_pattern.h" |
16 #include "chrome/browser/content_settings/content_settings_utils.h" | 18 #include "chrome/browser/content_settings/content_settings_utils.h" |
17 #include "chrome/browser/content_settings/host_content_settings_map.h" | 19 #include "chrome/browser/content_settings/host_content_settings_map.h" |
18 #include "chrome/browser/custom_handlers/protocol_handler_registry.h" | 20 #include "chrome/browser/custom_handlers/protocol_handler_registry.h" |
19 #include "chrome/browser/geolocation/geolocation_content_settings_map.h" | |
20 #include "chrome/browser/notifications/desktop_notification_service.h" | 21 #include "chrome/browser/notifications/desktop_notification_service.h" |
21 #include "chrome/browser/notifications/desktop_notification_service_factory.h" | 22 #include "chrome/browser/notifications/desktop_notification_service_factory.h" |
22 #include "chrome/browser/profiles/profile.h" | 23 #include "chrome/browser/profiles/profile.h" |
23 #include "chrome/browser/ui/browser_list.h" | 24 #include "chrome/browser/ui/browser_list.h" |
24 #include "chrome/common/chrome_notification_types.h" | 25 #include "chrome/common/chrome_notification_types.h" |
25 #include "chrome/common/chrome_switches.h" | 26 #include "chrome/common/chrome_switches.h" |
26 #include "chrome/common/content_settings_helper.h" | 27 #include "chrome/common/content_settings_helper.h" |
27 #include "chrome/common/pref_names.h" | 28 #include "chrome/common/pref_names.h" |
28 #include "chrome/common/url_constants.h" | 29 #include "chrome/common/url_constants.h" |
29 #include "content/browser/tab_contents/tab_contents.h" | 30 #include "content/browser/tab_contents/tab_contents.h" |
30 #include "content/common/content_notification_types.h" | 31 #include "content/common/content_notification_types.h" |
31 #include "content/common/notification_service.h" | 32 #include "content/common/notification_service.h" |
32 #include "content/common/notification_source.h" | 33 #include "content/common/notification_source.h" |
33 #include "grit/generated_resources.h" | 34 #include "grit/generated_resources.h" |
34 #include "grit/locale_settings.h" | 35 #include "grit/locale_settings.h" |
35 #include "ui/base/l10n/l10n_util.h" | 36 #include "ui/base/l10n/l10n_util.h" |
36 | 37 |
37 namespace { | 38 namespace { |
38 | 39 |
39 struct ContentSettingsTypeNameEntry { | 40 struct ContentSettingsTypeNameEntry { |
40 ContentSettingsType type; | 41 ContentSettingsType type; |
41 const char* name; | 42 const char* name; |
42 }; | 43 }; |
43 | 44 |
| 45 typedef std::map<ContentSettingsPattern, ContentSetting> OnePatternSettings; |
| 46 typedef std::map<ContentSettingsPattern, OnePatternSettings> |
| 47 AllPatternsSettings; |
| 48 |
44 const char* kDisplayPattern = "displayPattern"; | 49 const char* kDisplayPattern = "displayPattern"; |
45 const char* kSetting = "setting"; | 50 const char* kSetting = "setting"; |
46 const char* kOrigin = "origin"; | 51 const char* kOrigin = "origin"; |
47 const char* kSource = "source"; | 52 const char* kSource = "source"; |
48 const char* kEmbeddingOrigin = "embeddingOrigin"; | 53 const char* kEmbeddingOrigin = "embeddingOrigin"; |
49 | 54 |
50 const ContentSettingsTypeNameEntry kContentSettingsTypeGroupNames[] = { | 55 const ContentSettingsTypeNameEntry kContentSettingsTypeGroupNames[] = { |
51 {CONTENT_SETTINGS_TYPE_COOKIES, "cookies"}, | 56 {CONTENT_SETTINGS_TYPE_COOKIES, "cookies"}, |
52 {CONTENT_SETTINGS_TYPE_IMAGES, "images"}, | 57 {CONTENT_SETTINGS_TYPE_IMAGES, "images"}, |
53 {CONTENT_SETTINGS_TYPE_JAVASCRIPT, "javascript"}, | 58 {CONTENT_SETTINGS_TYPE_JAVASCRIPT, "javascript"}, |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
93 return CONTENT_SETTING_ASK; | 98 return CONTENT_SETTING_ASK; |
94 if (name == "block") | 99 if (name == "block") |
95 return CONTENT_SETTING_BLOCK; | 100 return CONTENT_SETTING_BLOCK; |
96 if (name == "session") | 101 if (name == "session") |
97 return CONTENT_SETTING_SESSION_ONLY; | 102 return CONTENT_SETTING_SESSION_ONLY; |
98 | 103 |
99 NOTREACHED() << name << " is not a recognized content setting."; | 104 NOTREACHED() << name << " is not a recognized content setting."; |
100 return CONTENT_SETTING_DEFAULT; | 105 return CONTENT_SETTING_DEFAULT; |
101 } | 106 } |
102 | 107 |
103 std::string GeolocationExceptionToString(const GURL& origin, | 108 std::string GeolocationExceptionToString( |
104 const GURL& embedding_origin) { | 109 const ContentSettingsPattern& origin, |
| 110 const ContentSettingsPattern& embedding_origin) { |
105 if (origin == embedding_origin) | 111 if (origin == embedding_origin) |
106 return content_settings_helper::OriginToString(origin); | 112 return origin.ToString(); |
107 | 113 |
108 // TODO(estade): the page needs to use CSS to indent the string. | 114 // TODO(estade): the page needs to use CSS to indent the string. |
109 std::string indent(" "); | 115 std::string indent(" "); |
110 if (embedding_origin.is_empty()) { | 116 |
| 117 if (embedding_origin == ContentSettingsPattern::Wildcard()) { |
111 // NOTE: As long as the user cannot add/edit entries from the exceptions | 118 // NOTE: As long as the user cannot add/edit entries from the exceptions |
112 // dialog, it's impossible to actually have a non-default setting for some | 119 // dialog, it's impossible to actually have a non-default setting for some |
113 // origin "embedded on any other site", so this row will never appear. If | 120 // origin "embedded on any other site", so this row will never appear. If |
114 // we add the ability to add/edit exceptions, we'll need to decide when to | 121 // we add the ability to add/edit exceptions, we'll need to decide when to |
115 // display this and how "removing" it will function. | 122 // display this and how "removing" it will function. |
116 return indent + | 123 return indent + |
117 l10n_util::GetStringUTF8(IDS_EXCEPTIONS_GEOLOCATION_EMBEDDED_ANY_OTHER); | 124 l10n_util::GetStringUTF8(IDS_EXCEPTIONS_GEOLOCATION_EMBEDDED_ANY_OTHER); |
118 } | 125 } |
119 | 126 |
120 return indent + l10n_util::GetStringFUTF8( | 127 return indent + l10n_util::GetStringFUTF8( |
121 IDS_EXCEPTIONS_GEOLOCATION_EMBEDDED_ON_HOST, | 128 IDS_EXCEPTIONS_GEOLOCATION_EMBEDDED_ON_HOST, |
122 UTF8ToUTF16(content_settings_helper::OriginToString(embedding_origin))); | 129 UTF8ToUTF16(embedding_origin.ToString())); |
123 } | 130 } |
124 | 131 |
125 // Create a DictionaryValue* that will act as a data source for a single row | 132 // Create a DictionaryValue* that will act as a data source for a single row |
126 // in a HostContentSettingsMap-controlled exceptions table (e.g., cookies). | 133 // in a HostContentSettingsMap-controlled exceptions table (e.g., cookies). |
127 // Ownership of the pointer is passed to the caller. | 134 // Ownership of the pointer is passed to the caller. |
128 DictionaryValue* GetExceptionForPage( | 135 DictionaryValue* GetExceptionForPage( |
129 const ContentSettingsPattern& pattern, | 136 const ContentSettingsPattern& pattern, |
130 ContentSetting setting, | 137 ContentSetting setting, |
131 std::string provider_name) { | 138 std::string provider_name) { |
132 DictionaryValue* exception = new DictionaryValue(); | 139 DictionaryValue* exception = new DictionaryValue(); |
133 exception->Set( | 140 exception->SetString(kDisplayPattern, pattern.ToString()); |
134 kDisplayPattern, | 141 exception->SetString(kSetting, ContentSettingToString(setting)); |
135 new StringValue(pattern.ToString())); | 142 exception->SetString(kSource, provider_name); |
136 exception->Set( | |
137 kSetting, | |
138 new StringValue(ContentSettingToString(setting))); | |
139 exception->Set( | |
140 kSource, | |
141 new StringValue(provider_name)); | |
142 return exception; | 143 return exception; |
143 } | 144 } |
144 | 145 |
145 // Create a DictionaryValue* that will act as a data source for a single row | 146 // Create a DictionaryValue* that will act as a data source for a single row |
146 // in the Geolocation exceptions table. Ownership of the pointer is passed to | 147 // in the Geolocation exceptions table. Ownership of the pointer is passed to |
147 // the caller. | 148 // the caller. |
148 DictionaryValue* GetGeolocationExceptionForPage(const GURL& origin, | 149 DictionaryValue* GetGeolocationExceptionForPage( |
149 const GURL& embedding_origin, | 150 const ContentSettingsPattern& origin, |
150 ContentSetting setting) { | 151 const ContentSettingsPattern& embedding_origin, |
| 152 ContentSetting setting) { |
151 DictionaryValue* exception = new DictionaryValue(); | 153 DictionaryValue* exception = new DictionaryValue(); |
152 exception->Set( | 154 exception->SetString(kDisplayPattern, |
153 kDisplayPattern, | 155 GeolocationExceptionToString(origin, embedding_origin)); |
154 new StringValue(GeolocationExceptionToString(origin, embedding_origin))); | 156 exception->SetString(kSetting, ContentSettingToString(setting)); |
155 exception->Set( | 157 exception->SetString(kOrigin, origin.ToString()); |
156 kSetting, | 158 exception->SetString(kEmbeddingOrigin, embedding_origin.ToString()); |
157 new StringValue(ContentSettingToString(setting))); | |
158 exception->Set( | |
159 kOrigin, | |
160 new StringValue(origin.spec())); | |
161 exception->Set( | |
162 kEmbeddingOrigin, | |
163 new StringValue(embedding_origin.spec())); | |
164 return exception; | 159 return exception; |
165 } | 160 } |
166 | 161 |
167 // Create a DictionaryValue* that will act as a data source for a single row | 162 // Create a DictionaryValue* that will act as a data source for a single row |
168 // in the desktop notifications exceptions table. Ownership of the pointer is | 163 // in the desktop notifications exceptions table. Ownership of the pointer is |
169 // passed to the caller. | 164 // passed to the caller. |
170 DictionaryValue* GetNotificationExceptionForPage( | 165 DictionaryValue* GetNotificationExceptionForPage( |
171 const GURL& url, | 166 const GURL& url, |
172 ContentSetting setting) { | 167 ContentSetting setting) { |
173 DictionaryValue* exception = new DictionaryValue(); | 168 DictionaryValue* exception = new DictionaryValue(); |
174 exception->Set( | 169 exception->SetString(kDisplayPattern, |
175 kDisplayPattern, | 170 content_settings_helper::OriginToString(url)); |
176 new StringValue(content_settings_helper::OriginToString(url))); | 171 exception->SetString(kSetting, ContentSettingToString(setting)); |
177 exception->Set( | 172 exception->SetString(kOrigin, url.spec()); |
178 kSetting, | |
179 new StringValue(ContentSettingToString(setting))); | |
180 exception->Set( | |
181 kOrigin, | |
182 new StringValue(url.spec())); | |
183 return exception; | 173 return exception; |
184 } | 174 } |
185 | 175 |
186 } // namespace | 176 } // namespace |
187 | 177 |
188 ContentSettingsHandler::ContentSettingsHandler() { | 178 ContentSettingsHandler::ContentSettingsHandler() { |
189 } | 179 } |
190 | 180 |
191 ContentSettingsHandler::~ContentSettingsHandler() { | 181 ContentSettingsHandler::~ContentSettingsHandler() { |
192 } | 182 } |
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
431 case CONTENT_SETTINGS_TYPE_GEOLOCATION: | 421 case CONTENT_SETTINGS_TYPE_GEOLOCATION: |
432 case CONTENT_SETTINGS_TYPE_NOTIFICATIONS: | 422 case CONTENT_SETTINGS_TYPE_NOTIFICATIONS: |
433 break; | 423 break; |
434 default: | 424 default: |
435 UpdateExceptionsViewFromOTRHostContentSettingsMap(type); | 425 UpdateExceptionsViewFromOTRHostContentSettingsMap(type); |
436 break; | 426 break; |
437 } | 427 } |
438 } | 428 } |
439 | 429 |
440 void ContentSettingsHandler::UpdateGeolocationExceptionsView() { | 430 void ContentSettingsHandler::UpdateGeolocationExceptionsView() { |
441 GeolocationContentSettingsMap* map = web_ui_->tab_contents()-> | 431 Profile* profile = Profile::FromWebUI(web_ui_); |
442 browser_context()->GetGeolocationContentSettingsMap(); | 432 HostContentSettingsMap* map = profile->GetHostContentSettingsMap(); |
443 GeolocationContentSettingsMap::AllOriginsSettings all_settings = | 433 |
444 map->GetAllOriginsSettings(); | 434 HostContentSettingsMap::SettingsForOneType all_settings; |
445 GeolocationContentSettingsMap::AllOriginsSettings::const_iterator i; | 435 map->GetSettingsForOneType( |
| 436 CONTENT_SETTINGS_TYPE_GEOLOCATION, |
| 437 std::string(), |
| 438 &all_settings); |
| 439 |
| 440 // Group geolocation settings by primary_pattern. |
| 441 AllPatternsSettings all_patterns_settings; |
| 442 for (HostContentSettingsMap::SettingsForOneType::iterator i = |
| 443 all_settings.begin(); |
| 444 i != all_settings.end(); |
| 445 ++i) { |
| 446 all_patterns_settings[i->a][i->b] = i->c; |
| 447 } |
446 | 448 |
447 ListValue exceptions; | 449 ListValue exceptions; |
448 for (i = all_settings.begin(); i != all_settings.end(); ++i) { | 450 for (AllPatternsSettings::iterator i = all_patterns_settings.begin(); |
449 const GURL& origin = i->first; | 451 i != all_patterns_settings.end(); |
450 const GeolocationContentSettingsMap::OneOriginSettings& one_settings = | 452 ++i) { |
451 i->second; | 453 const ContentSettingsPattern& primary_pattern = i->first; |
| 454 const OnePatternSettings& one_settings = i->second; |
452 | 455 |
453 GeolocationContentSettingsMap::OneOriginSettings::const_iterator parent = | 456 OnePatternSettings::const_iterator parent = |
454 one_settings.find(origin); | 457 one_settings.find(primary_pattern); |
455 | 458 |
456 // Add the "parent" entry for the non-embedded setting. | 459 // Add the "parent" entry for the non-embedded setting. |
457 ContentSetting parent_setting = | 460 ContentSetting parent_setting = |
458 parent == one_settings.end() ? CONTENT_SETTING_DEFAULT : parent->second; | 461 parent == one_settings.end() ? CONTENT_SETTING_DEFAULT : parent->second; |
459 exceptions.Append( | 462 exceptions.Append(GetGeolocationExceptionForPage(primary_pattern, |
460 GetGeolocationExceptionForPage(origin, origin, parent_setting)); | 463 primary_pattern, |
| 464 parent_setting)); |
461 | 465 |
462 // Add the "children" for any embedded settings. | 466 // Add the "children" for any embedded settings. |
463 GeolocationContentSettingsMap::OneOriginSettings::const_iterator j; | 467 for (OnePatternSettings::const_iterator j = one_settings.begin(); |
464 for (j = one_settings.begin(); j != one_settings.end(); ++j) { | 468 j != one_settings.end(); |
| 469 ++j) { |
465 // Skip the non-embedded setting which we already added above. | 470 // Skip the non-embedded setting which we already added above. |
466 if (j == parent) | 471 if (j == parent) |
467 continue; | 472 continue; |
468 | 473 |
469 exceptions.Append( | 474 exceptions.Append( |
470 GetGeolocationExceptionForPage(origin, j->first, j->second)); | 475 GetGeolocationExceptionForPage(primary_pattern, j->first, j->second)); |
471 } | 476 } |
472 } | 477 } |
473 | 478 |
474 StringValue type_string( | 479 StringValue type_string( |
475 ContentSettingsTypeToGroupName(CONTENT_SETTINGS_TYPE_GEOLOCATION)); | 480 ContentSettingsTypeToGroupName(CONTENT_SETTINGS_TYPE_GEOLOCATION)); |
476 web_ui_->CallJavascriptFunction("ContentSettings.setExceptions", | 481 web_ui_->CallJavascriptFunction("ContentSettings.setExceptions", |
477 type_string, exceptions); | 482 type_string, exceptions); |
478 | 483 |
479 // This is mainly here to keep this function ideologically parallel to | 484 // This is mainly here to keep this function ideologically parallel to |
480 // UpdateExceptionsViewFromHostContentSettingsMap(). | 485 // UpdateExceptionsViewFromHostContentSettingsMap(). |
(...skipping 28 matching lines...) Expand all Loading... |
509 UpdateSettingDefaultFromModel(CONTENT_SETTINGS_TYPE_NOTIFICATIONS); | 514 UpdateSettingDefaultFromModel(CONTENT_SETTINGS_TYPE_NOTIFICATIONS); |
510 } | 515 } |
511 | 516 |
512 void ContentSettingsHandler::UpdateExceptionsViewFromHostContentSettingsMap( | 517 void ContentSettingsHandler::UpdateExceptionsViewFromHostContentSettingsMap( |
513 ContentSettingsType type) { | 518 ContentSettingsType type) { |
514 HostContentSettingsMap::SettingsForOneType entries; | 519 HostContentSettingsMap::SettingsForOneType entries; |
515 GetContentSettingsMap()->GetSettingsForOneType(type, "", &entries); | 520 GetContentSettingsMap()->GetSettingsForOneType(type, "", &entries); |
516 | 521 |
517 ListValue exceptions; | 522 ListValue exceptions; |
518 for (size_t i = 0; i < entries.size(); ++i) { | 523 for (size_t i = 0; i < entries.size(); ++i) { |
519 exceptions.Append( | 524 // The content settings UI does not support secondary content settings |
520 GetExceptionForPage(entries[i].a, entries[i].c, entries[i].d)); | 525 // pattern yet. For content settings set through the content settings UI the |
| 526 // secondary pattern is by default a wildcard pattern. Hence users are not |
| 527 // able to modify content settings with a secondary pattern other than the |
| 528 // wildcard pattern. So only show settings that the user is able to modify. |
| 529 if (entries[i].b == ContentSettingsPattern::Wildcard()) { |
| 530 exceptions.Append( |
| 531 GetExceptionForPage(entries[i].a, entries[i].c, entries[i].d)); |
| 532 } else { |
| 533 LOG(DFATAL) << "Secondary content settings patterns are not" |
| 534 << "supported by the content settings UI"; |
| 535 } |
521 } | 536 } |
522 | 537 |
523 StringValue type_string(ContentSettingsTypeToGroupName(type)); | 538 StringValue type_string(ContentSettingsTypeToGroupName(type)); |
524 web_ui_->CallJavascriptFunction("ContentSettings.setExceptions", type_string, | 539 web_ui_->CallJavascriptFunction("ContentSettings.setExceptions", type_string, |
525 exceptions); | 540 exceptions); |
526 | 541 |
527 UpdateExceptionsViewFromOTRHostContentSettingsMap(type); | 542 UpdateExceptionsViewFromOTRHostContentSettingsMap(type); |
528 | 543 |
529 // The default may also have changed (we won't get a separate notification). | 544 // The default may also have changed (we won't get a separate notification). |
530 // If it hasn't changed, this call will be harmless. | 545 // If it hasn't changed, this call will be harmless. |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
596 Profile* profile = Profile::FromWebUI(web_ui_); | 611 Profile* profile = Profile::FromWebUI(web_ui_); |
597 ContentSettingsType type = ContentSettingsTypeFromGroupName(type_string); | 612 ContentSettingsType type = ContentSettingsTypeFromGroupName(type_string); |
598 if (type == CONTENT_SETTINGS_TYPE_GEOLOCATION) { | 613 if (type == CONTENT_SETTINGS_TYPE_GEOLOCATION) { |
599 std::string origin; | 614 std::string origin; |
600 std::string embedding_origin; | 615 std::string embedding_origin; |
601 bool rv = args->GetString(arg_i++, &origin); | 616 bool rv = args->GetString(arg_i++, &origin); |
602 DCHECK(rv); | 617 DCHECK(rv); |
603 rv = args->GetString(arg_i++, &embedding_origin); | 618 rv = args->GetString(arg_i++, &embedding_origin); |
604 DCHECK(rv); | 619 DCHECK(rv); |
605 | 620 |
606 profile->GetGeolocationContentSettingsMap()-> | 621 profile->GetHostContentSettingsMap()-> |
607 SetContentSetting(GURL(origin), | 622 SetContentSetting(ContentSettingsPattern::FromString(origin), |
608 GURL(embedding_origin), | 623 ContentSettingsPattern::FromString(embedding_origin), |
| 624 CONTENT_SETTINGS_TYPE_GEOLOCATION, |
| 625 std::string(), |
609 CONTENT_SETTING_DEFAULT); | 626 CONTENT_SETTING_DEFAULT); |
610 } else if (type == CONTENT_SETTINGS_TYPE_NOTIFICATIONS) { | 627 } else if (type == CONTENT_SETTINGS_TYPE_NOTIFICATIONS) { |
611 std::string origin; | 628 std::string origin; |
612 std::string setting; | 629 std::string setting; |
613 bool rv = args->GetString(arg_i++, &origin); | 630 bool rv = args->GetString(arg_i++, &origin); |
614 DCHECK(rv); | 631 DCHECK(rv); |
615 rv = args->GetString(arg_i++, &setting); | 632 rv = args->GetString(arg_i++, &setting); |
616 DCHECK(rv); | 633 DCHECK(rv); |
617 ContentSetting content_setting = ContentSettingFromString(setting); | 634 ContentSetting content_setting = ContentSettingFromString(setting); |
618 if (content_setting == CONTENT_SETTING_ALLOW) { | 635 if (content_setting == CONTENT_SETTING_ALLOW) { |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
726 return Profile::FromWebUI(web_ui_)->GetProtocolHandlerRegistry(); | 743 return Profile::FromWebUI(web_ui_)->GetProtocolHandlerRegistry(); |
727 } | 744 } |
728 | 745 |
729 HostContentSettingsMap* | 746 HostContentSettingsMap* |
730 ContentSettingsHandler::GetOTRContentSettingsMap() { | 747 ContentSettingsHandler::GetOTRContentSettingsMap() { |
731 Profile* profile = Profile::FromWebUI(web_ui_); | 748 Profile* profile = Profile::FromWebUI(web_ui_); |
732 if (profile->HasOffTheRecordProfile()) | 749 if (profile->HasOffTheRecordProfile()) |
733 return profile->GetOffTheRecordProfile()->GetHostContentSettingsMap(); | 750 return profile->GetOffTheRecordProfile()->GetHostContentSettingsMap(); |
734 return NULL; | 751 return NULL; |
735 } | 752 } |
OLD | NEW |