Upstream version 11.40.277.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / webui / options / website_settings_handler.cc
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/ui/webui/options/website_settings_handler.h"
6
7 #include "chrome/browser/extensions/extension_service.h"
8 #include "chrome/browser/profiles/profile.h"
9 #include "chrome/browser/ui/browser.h"
10 #include "chrome/browser/ui/browser_iterator.h"
11 #include "chrome/browser/ui/tabs/tab_strip_model.h"
12 #include "chrome/grit/generated_resources.h"
13 #include "components/content_settings/core/browser/content_settings_utils.h"
14 #include "components/content_settings/core/browser/host_content_settings_map.h"
15 #include "components/power/origin_power_map.h"
16 #include "components/power/origin_power_map_factory.h"
17 #include "content/public/browser/dom_storage_context.h"
18 #include "content/public/browser/storage_partition.h"
19 #include "content/public/browser/user_metrics.h"
20 #include "content/public/browser/web_contents.h"
21 #include "content/public/browser/web_ui.h"
22 #include "extensions/browser/app_window/app_window_registry.h"
23 #include "extensions/browser/extension_registry.h"
24 #include "extensions/browser/extension_system.h"
25 #include "extensions/common/constants.h"
26 #include "extensions/common/extension.h"
27 #include "ui/base/l10n/l10n_util.h"
28 #include "ui/base/l10n/time_format.h"
29 #include "ui/base/text/bytes_formatting.h"
30
31 #if defined(OS_CHROMEOS)
32 #include "components/user_manager/user_manager.h"
33 #endif
34
35 using base::UserMetricsAction;
36 using power::OriginPowerMap;
37 using power::OriginPowerMapFactory;
38
39 namespace {
40
41 const char kBattery[] = "battery";
42 const int kHttpPort = 80;
43 const int kHttpsPort = 443;
44 const char kPreferencesSource[] = "preference";
45 const char kStorage[] = "storage";
46 const ContentSettingsType kValidTypes[] = {
47     CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS,
48     CONTENT_SETTINGS_TYPE_COOKIES,
49     CONTENT_SETTINGS_TYPE_GEOLOCATION,
50     CONTENT_SETTINGS_TYPE_IMAGES,
51     CONTENT_SETTINGS_TYPE_JAVASCRIPT,
52     CONTENT_SETTINGS_TYPE_NOTIFICATIONS,
53     CONTENT_SETTINGS_TYPE_MEDIASTREAM,
54     CONTENT_SETTINGS_TYPE_PLUGINS,
55     CONTENT_SETTINGS_TYPE_POPUPS};
56 const size_t kValidTypesLength = arraysize(kValidTypes);
57
58 }  // namespace
59
60 namespace options {
61
62 WebsiteSettingsHandler::WebsiteSettingsHandler()
63     : observer_(this),
64       weak_ptr_factory_(this) {
65 }
66
67 WebsiteSettingsHandler::~WebsiteSettingsHandler() {
68 }
69
70 void WebsiteSettingsHandler::GetLocalizedValues(
71     base::DictionaryValue* localized_strings) {
72   DCHECK(localized_strings);
73
74   static OptionsStringResource resources[] = {
75       {"websitesOptionsPageTabTitle", IDS_WEBSITE_SETTINGS_TITLE},
76       {"websitesSettingsEditPage", IDS_WEBSITE_SETTINGS_EDIT_TITLE},
77       {"websitesManage", IDS_WEBSITE_SETTINGS_MANAGE},
78       {"websitesSearch", IDS_WEBSITE_SETTINGS_SEARCH_ORIGINS},
79       {"websitesLabelLocation", IDS_WEBSITE_SETTINGS_TYPE_LOCATION},
80       {"websitesLabelMediaStream", IDS_WEBSITE_SETTINGS_TYPE_MEDIASTREAM},
81       {"websitesLabelNotifications", IDS_WEBSITE_SETTINGS_TYPE_NOTIFICATIONS},
82       {"websitesLabelOn", IDS_WEBSITE_SETTINGS_CONTENT_SETTING_ENABLED},
83       {"websitesLabelStorage", IDS_WEBSITE_SETTINGS_TYPE_STORAGE},
84       {"websitesLabelBattery", IDS_WEBSITE_SETTINGS_TYPE_BATTERY},
85       {"websitesCookiesDescription", IDS_WEBSITE_SETTINGS_COOKIES_DESCRIPTION},
86       {"websitesLocationDescription",
87        IDS_WEBSITE_SETTINGS_LOCATION_DESCRIPTION},
88       {"websitesMediaStreamDescription",
89        IDS_WEBSITE_SETTINGS_MEDIASTREAM_DESCRIPTION},
90       {"websitesNotificationsDescription",
91        IDS_WEBSITE_SETTINGS_NOTIFICATIONS_DESCRIPTION},
92       {"websitesDownloadsDescription",
93        IDS_WEBSITE_SETTINGS_DOWNLOAD_DESCRIPTION},
94       {"websitesPluginsDescription", IDS_WEBSITE_SETTINGS_PLUGINS_DESCRIPTION},
95       {"websitesPopupsDescription", IDS_WEBSITE_SETTINGS_POPUPS_DESCRIPTION},
96       {"websitesJavascriptDescription",
97        IDS_WEBSITE_SETTINGS_JAVASCRIPT_DESCRIPTION},
98       {"websitesImagesDescription", IDS_WEBSITE_SETTINGS_IMAGES_DESCRIPTION},
99       {"websitesButtonClear", IDS_WEBSITE_SETTINGS_STORAGE_CLEAR_BUTTON},
100       {"websitesButtonStop", IDS_WEBSITE_SETTINGS_BATTERY_STOP_BUTTON},
101       {"websitesAllowedListTitle", IDS_WEBSITE_SETTINGS_ALLOWED_LIST_TITLE},
102       {"websitesBlockedListTitle", IDS_WEBSITE_SETTINGS_BLOCKED_LIST_TITLE},
103       {"storageTabLabel", IDS_WEBSITE_SETTINGS_TYPE_STORAGE},
104       {"batteryTabLabel", IDS_WEBSITE_SETTINGS_TYPE_BATTERY},
105   };
106
107   RegisterStrings(localized_strings, resources, arraysize(resources));
108   RegisterTitle(
109       localized_strings, "websiteSettingsPage", IDS_WEBSITE_SETTINGS_TITLE);
110 }
111
112 void WebsiteSettingsHandler::InitializeHandler() {
113   Profile* profile = GetProfile();
114   HostContentSettingsMap* settings = profile->GetHostContentSettingsMap();
115   observer_.Add(settings);
116
117   power::OriginPowerMap* origin_power_map =
118       power::OriginPowerMapFactory::GetForBrowserContext(profile);
119   // OriginPowerMap may not be available in tests.
120   if (origin_power_map) {
121     subscription_ = origin_power_map->AddPowerConsumptionUpdatedCallback(
122         base::Bind(&WebsiteSettingsHandler::Update, base::Unretained(this)));
123   }
124 }
125
126 void WebsiteSettingsHandler::RegisterMessages() {
127   web_ui()->RegisterMessageCallback(
128       "updateOrigins",
129       base::Bind(&WebsiteSettingsHandler::HandleUpdateOrigins,
130                  base::Unretained(this)));
131
132   web_ui()->RegisterMessageCallback(
133       "updateOriginsSearchResults",
134       base::Bind(&WebsiteSettingsHandler::HandleUpdateSearchResults,
135                  base::Unretained(this)));
136
137   web_ui()->RegisterMessageCallback(
138       "updateLocalStorage",
139       base::Bind(&WebsiteSettingsHandler::HandleUpdateLocalStorage,
140                  base::Unretained(this)));
141
142   web_ui()->RegisterMessageCallback(
143       "updateBatteryUsage",
144       base::Bind(&WebsiteSettingsHandler::HandleUpdateBatteryUsage,
145                  base::Unretained(this)));
146
147   web_ui()->RegisterMessageCallback(
148       "getOriginInfo",
149       base::Bind(&WebsiteSettingsHandler::HandleGetOriginInfo,
150                  base::Unretained(this)));
151
152   web_ui()->RegisterMessageCallback(
153       "setOriginPermission",
154       base::Bind(&WebsiteSettingsHandler::HandleSetOriginPermission,
155                  base::Unretained(this)));
156
157   web_ui()->RegisterMessageCallback(
158       "maybeShowEditPage",
159       base::Bind(&WebsiteSettingsHandler::HandleMaybeShowEditPage,
160                  base::Unretained(this)));
161
162   web_ui()->RegisterMessageCallback(
163       "deleteLocalStorage",
164       base::Bind(&WebsiteSettingsHandler::HandleDeleteLocalStorage,
165                  base::Unretained(this)));
166
167   web_ui()->RegisterMessageCallback(
168       "stopOrigin",
169       base::Bind(&WebsiteSettingsHandler::HandleStopOrigin,
170                  base::Unretained(this)));
171
172   web_ui()->RegisterMessageCallback(
173       "updateDefaultSetting",
174       base::Bind(&WebsiteSettingsHandler::HandleUpdateDefaultSetting,
175                  base::Unretained(this)));
176
177   web_ui()->RegisterMessageCallback(
178       "setDefaultContentSetting",
179       base::Bind(&WebsiteSettingsHandler::HandleSetDefaultSetting,
180                  base::Unretained(this)));
181
182   web_ui()->RegisterMessageCallback(
183       "setGlobalEnabled",
184       base::Bind(&WebsiteSettingsHandler::HandleSetGlobalToggle,
185                  base::Unretained(this)));
186 }
187
188 // content_settings::Observer implementation.
189 void WebsiteSettingsHandler::OnContentSettingChanged(
190     const ContentSettingsPattern& primary_pattern,
191     const ContentSettingsPattern& secondary_pattern,
192     ContentSettingsType content_type,
193     std::string resource_identifier) {
194   Update();
195 }
196
197 void WebsiteSettingsHandler::OnContentSettingUsed(
198     const ContentSettingsPattern& primary_pattern,
199     const ContentSettingsPattern& secondary_pattern,
200     ContentSettingsType content_type) {
201   Update();
202 }
203
204 void WebsiteSettingsHandler::HandleUpdateOrigins(const base::ListValue* args) {
205   std::string content_setting_name;
206   bool rv = args->GetString(0, &content_setting_name);
207   DCHECK(rv);
208
209   ContentSettingsType content_type;
210   rv = content_settings::GetTypeFromName(content_setting_name, &content_type);
211   DCHECK(rv);
212   DCHECK_NE(
213       kValidTypes + kValidTypesLength,
214       std::find(kValidTypes, kValidTypes + kValidTypesLength, content_type));
215
216   last_setting_ = content_setting_name;
217   UpdateOrigins();
218 }
219
220 void WebsiteSettingsHandler::HandleUpdateSearchResults(
221     const base::ListValue* args) {
222   bool rv = args->GetString(0, &last_filter_);
223   DCHECK(rv);
224
225   Update();
226 }
227
228 void WebsiteSettingsHandler::HandleUpdateLocalStorage(
229     const base::ListValue* args) {
230   if (!local_storage_.get()) {
231     Profile* profile = GetProfile();
232     local_storage_ = new BrowsingDataLocalStorageHelper(profile);
233   }
234
235   last_setting_ = kStorage;
236
237   local_storage_->StartFetching(
238       base::Bind(&WebsiteSettingsHandler::OnLocalStorageFetched,
239                  weak_ptr_factory_.GetWeakPtr()));
240 }
241
242 void WebsiteSettingsHandler::HandleMaybeShowEditPage(
243     const base::ListValue* args) {
244   std::string site;
245   bool rv = args->GetString(0, &site);
246   DCHECK(rv);
247
248   GURL last_site(site);
249   if (!last_site.is_valid())
250     return;
251
252   last_site_ = last_site;
253   base::StringValue site_value(site);
254   web_ui()->CallJavascriptFunction("WebsiteSettingsEditor.showEditPage",
255                                    site_value);
256 }
257
258 void WebsiteSettingsHandler::OnLocalStorageFetched(const std::list<
259     BrowsingDataLocalStorageHelper::LocalStorageInfo>& storage) {
260   local_storage_list_ = storage;
261   Update();
262   GetInfoForOrigin(last_site_, false);
263 }
264
265 void WebsiteSettingsHandler::Update() {
266   DCHECK(!last_setting_.empty());
267   if (last_setting_ == kStorage)
268     UpdateLocalStorage();
269   else if (last_setting_ == kBattery)
270     UpdateBatteryUsage();
271   else
272     UpdateOrigins();
273 }
274
275 void WebsiteSettingsHandler::UpdateOrigins() {
276   Profile* profile = GetProfile();
277   HostContentSettingsMap* settings = profile->GetHostContentSettingsMap();
278
279   ContentSettingsForOneType all_settings;
280   ContentSettingsType last_setting;
281   content_settings::GetTypeFromName(last_setting_, &last_setting);
282
283   if (last_setting == CONTENT_SETTINGS_TYPE_MEDIASTREAM)
284     last_setting = CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC;
285
286   settings->GetSettingsForOneType(last_setting, std::string(), &all_settings);
287
288   base::DictionaryValue allowed_origins;
289   base::DictionaryValue blocked_origins;
290   for (ContentSettingsForOneType::const_iterator it = all_settings.begin();
291        it != all_settings.end();
292        ++it) {
293     // Don't add default settings.
294     if (it->primary_pattern == ContentSettingsPattern::Wildcard() &&
295         it->secondary_pattern == ContentSettingsPattern::Wildcard() &&
296         it->source != kPreferencesSource) {
297       continue;
298     }
299
300     GURL origin_url(it->primary_pattern.ToString());
301     std::string origin = origin_url.spec();
302
303     // Hide the port if it is using a standard URL scheme.
304     if ((origin_url.SchemeIs(url::kHttpScheme) &&
305          origin_url.IntPort() == kHttpPort) ||
306         (origin_url.SchemeIs(url::kHttpsScheme) &&
307          origin_url.IntPort() == kHttpsPort)) {
308       url::Replacements<char> replacements;
309       replacements.ClearPort();
310       origin = origin_url.ReplaceComponents(replacements).spec();
311     }
312
313     // Mediastream isn't set unless both mic and camera are set to the same.
314     if (last_setting == CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC) {
315       ContentSetting cam_setting = settings->GetContentSettingWithoutOverride(
316           origin_url,
317           origin_url,
318           CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA,
319           std::string());
320       if (it->setting != cam_setting)
321         continue;
322     }
323
324     if (origin.find(last_filter_) == base::string16::npos)
325       continue;
326
327     base::Time last_usage = settings->GetLastUsageByPattern(
328         it->primary_pattern, it->secondary_pattern, last_setting);
329
330     base::DictionaryValue* origin_entry = new base::DictionaryValue();
331     origin_entry->SetDoubleWithoutPathExpansion("usage",
332                                                 last_usage.ToDoubleT());
333     base::string16 usage_string;
334     if (last_usage.ToDoubleT()) {
335       usage_string = ui::TimeFormat::Simple(ui::TimeFormat::FORMAT_ELAPSED,
336                                             ui::TimeFormat::LENGTH_SHORT,
337                                             base::Time::Now() - last_usage);
338     }
339     origin_entry->SetStringWithoutPathExpansion("usageString", usage_string);
340     origin_entry->SetStringWithoutPathExpansion("readableName",
341                                                 GetReadableName(origin_url));
342
343     if (it->setting == CONTENT_SETTING_BLOCK)
344       blocked_origins.SetWithoutPathExpansion(origin, origin_entry);
345     else
346       allowed_origins.SetWithoutPathExpansion(origin, origin_entry);
347   }
348
349   bool is_globally_allowed = settings->GetContentSettingOverride(last_setting);
350   web_ui()->CallJavascriptFunction("WebsiteSettingsManager.populateOrigins",
351                                    allowed_origins,
352                                    blocked_origins,
353                                    base::FundamentalValue(is_globally_allowed));
354 }
355
356 void WebsiteSettingsHandler::HandleGetOriginInfo(const base::ListValue* args) {
357   std::string url;
358   bool rv = args->GetString(0, &url);
359   DCHECK(rv);
360   GURL origin(url);
361
362   if (!origin.is_valid())
363     return;
364
365   GetInfoForOrigin(origin, true);
366 }
367
368 void WebsiteSettingsHandler::HandleSetOriginPermission(
369     const base::ListValue* args) {
370   std::string setting_name;
371   bool rv = args->GetString(0, &setting_name);
372   DCHECK(rv);
373   ContentSettingsType settings_type;
374   rv = content_settings::GetTypeFromName(setting_name, &settings_type);
375   DCHECK(rv);
376
377   std::string value;
378   rv = args->GetString(1, &value);
379   DCHECK(rv);
380
381   ContentSetting setting = content_settings::ContentSettingFromString(value);
382   Profile* profile = GetProfile();
383   HostContentSettingsMap* map = profile->GetHostContentSettingsMap();
384   ContentSetting default_value =
385       map->GetDefaultContentSetting(settings_type, NULL);
386
387   // Users are not allowed to be the source of the "ask" setting. It is an
388   // ephemeral setting which is removed once the question is asked.
389   if (setting == CONTENT_SETTING_ASK && setting == default_value)
390     setting = CONTENT_SETTING_DEFAULT;
391
392   ContentSettingsPattern primary_pattern;
393   ContentSettingsPattern secondary_pattern;
394   switch (settings_type) {
395     case CONTENT_SETTINGS_TYPE_NOTIFICATIONS:
396       primary_pattern = ContentSettingsPattern::FromURLNoWildcard(last_site_);
397       secondary_pattern = ContentSettingsPattern::Wildcard();
398       break;
399     case CONTENT_SETTINGS_TYPE_MEDIASTREAM:
400       primary_pattern = ContentSettingsPattern::FromURLNoWildcard(last_site_);
401       secondary_pattern = ContentSettingsPattern::Wildcard();
402       map->SetContentSetting(primary_pattern,
403                              secondary_pattern,
404                              CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC,
405                              std::string(),
406                              setting);
407       map->SetContentSetting(primary_pattern,
408                              secondary_pattern,
409                              CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA,
410                              std::string(),
411                              setting);
412       return;
413     case CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS:
414     case CONTENT_SETTINGS_TYPE_COOKIES:
415     case CONTENT_SETTINGS_TYPE_GEOLOCATION:
416     case CONTENT_SETTINGS_TYPE_IMAGES:
417     case CONTENT_SETTINGS_TYPE_JAVASCRIPT:
418     case CONTENT_SETTINGS_TYPE_PLUGINS:
419     case CONTENT_SETTINGS_TYPE_POPUPS:
420       primary_pattern = ContentSettingsPattern::FromURLNoWildcard(last_site_);
421       secondary_pattern = ContentSettingsPattern::FromURLNoWildcard(last_site_);
422       break;
423     default:
424       NOTREACHED() << "Content settings type not yet supported.";
425       return;
426   }
427
428   content_settings::SettingInfo info;
429   scoped_ptr<base::Value> v(map->GetWebsiteSettingWithoutOverride(
430       last_site_, last_site_, settings_type, std::string(), &info));
431   map->SetNarrowestWebsiteSetting(primary_pattern,
432                                   secondary_pattern,
433                                   settings_type,
434                                   std::string(),
435                                   setting,
436                                   info);
437 }
438
439 void WebsiteSettingsHandler::HandleUpdateBatteryUsage(
440     const base::ListValue* args) {
441   last_setting_ = kBattery;
442   UpdateBatteryUsage();
443 }
444
445 void WebsiteSettingsHandler::HandleDeleteLocalStorage(
446     const base::ListValue* args) {
447   DCHECK(!last_site_.is_empty());
448   DeleteLocalStorage(last_site_);
449 }
450
451 void WebsiteSettingsHandler::HandleStopOrigin(const base::ListValue* args) {
452   DCHECK(!last_site_.is_empty());
453   StopOrigin(last_site_);
454 }
455
456 // TODO(dhnishi): Remove default settings duplication from the
457 //                WebsiteSettingsHandler and the ContentSettingsHandler.
458 void WebsiteSettingsHandler::HandleUpdateDefaultSetting(
459     const base::ListValue* args) {
460   ContentSettingsType last_setting;
461   content_settings::GetTypeFromName(last_setting_, &last_setting);
462
463   base::DictionaryValue filter_settings;
464   std::string provider_id;
465   filter_settings.SetString(
466       "value", GetSettingDefaultFromModel(last_setting, &provider_id));
467   filter_settings.SetString("managedBy", provider_id);
468
469   web_ui()->CallJavascriptFunction("WebsiteSettingsManager.updateDefault",
470                                    filter_settings);
471 }
472
473 void WebsiteSettingsHandler::HandleSetDefaultSetting(
474     const base::ListValue* args) {
475   DCHECK_EQ(1U, args->GetSize());
476   std::string setting;
477   if (!args->GetString(0, &setting)) {
478     NOTREACHED();
479     return;
480   }
481   ContentSetting new_default =
482       content_settings::ContentSettingFromString(setting);
483
484   ContentSettingsType last_setting;
485   content_settings::GetTypeFromName(last_setting_, &last_setting);
486   Profile* profile = GetProfile();
487
488   HostContentSettingsMap* map = profile->GetHostContentSettingsMap();
489   map->SetDefaultContentSetting(last_setting, new_default);
490
491   switch (last_setting) {
492     case CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS:
493       content::RecordAction(
494           UserMetricsAction("Options_DefaultMultipleAutomaticDLSettingChange"));
495       break;
496     case CONTENT_SETTINGS_TYPE_COOKIES:
497       content::RecordAction(
498           UserMetricsAction("Options_DefaultCookieSettingChanged"));
499       break;
500     case CONTENT_SETTINGS_TYPE_GEOLOCATION:
501       content::RecordAction(
502           UserMetricsAction("Options_DefaultGeolocationSettingChanged"));
503       break;
504     case CONTENT_SETTINGS_TYPE_IMAGES:
505       content::RecordAction(
506           UserMetricsAction("Options_DefaultImagesSettingChanged"));
507       break;
508     case CONTENT_SETTINGS_TYPE_JAVASCRIPT:
509       content::RecordAction(
510           UserMetricsAction("Options_DefaultJavaScriptSettingChanged"));
511       break;
512     case CONTENT_SETTINGS_TYPE_MEDIASTREAM:
513       content::RecordAction(
514           UserMetricsAction("Options_DefaultMediaStreamMicSettingChanged"));
515       break;
516     case CONTENT_SETTINGS_TYPE_NOTIFICATIONS:
517       content::RecordAction(
518           UserMetricsAction("Options_DefaultNotificationsSettingChanged"));
519       break;
520     case CONTENT_SETTINGS_TYPE_PLUGINS:
521       content::RecordAction(
522           UserMetricsAction("Options_DefaultPluginsSettingChanged"));
523       break;
524     case CONTENT_SETTINGS_TYPE_POPUPS:
525       content::RecordAction(
526           UserMetricsAction("Options_DefaultPopupsSettingChanged"));
527       break;
528     default:
529       NOTREACHED();
530       return;
531   }
532 }
533
534 void WebsiteSettingsHandler::HandleSetGlobalToggle(
535     const base::ListValue* args) {
536   DCHECK_EQ(1U, args->GetSize());
537   bool is_enabled;
538   bool rv = args->GetBoolean(0, &is_enabled);
539   DCHECK(rv);
540
541   ContentSettingsType last_setting;
542   rv = content_settings::GetTypeFromName(last_setting_, &last_setting);
543   DCHECK(rv);
544
545   Profile* profile = GetProfile();
546   HostContentSettingsMap* map = profile->GetHostContentSettingsMap();
547   map->SetContentSettingOverride(last_setting, is_enabled);
548 }
549
550 void WebsiteSettingsHandler::GetInfoForOrigin(const GURL& site_url,
551                                               bool show_page) {
552   Profile* profile = GetProfile();
553   HostContentSettingsMap* map = profile->GetHostContentSettingsMap();
554
555   double storage = 0.0;
556   for (LocalStorageList::const_iterator it = local_storage_list_.begin();
557        it != local_storage_list_.end();
558        it++) {
559     if (it->origin_url == site_url) {
560       storage = static_cast<double>(it->size);
561       break;
562     }
563   }
564
565   int battery = 0;
566   battery = OriginPowerMapFactory::GetForBrowserContext(
567       GetProfile())->GetPowerForOrigin(site_url);
568
569   base::DictionaryValue* permissions = new base::DictionaryValue;
570   for (size_t i = 0; i < arraysize(kValidTypes); ++i) {
571     ContentSettingsType permission_type = kValidTypes[i];
572
573     // Append the possible settings.
574     base::ListValue* options = new base::ListValue;
575     ContentSetting default_value =
576         map->GetDefaultContentSetting(permission_type, NULL);
577     if (default_value != CONTENT_SETTING_ALLOW &&
578         default_value != CONTENT_SETTING_BLOCK) {
579       options->AppendString(
580           content_settings::ContentSettingToString(default_value));
581     }
582     options->AppendString(
583         content_settings::ContentSettingToString(CONTENT_SETTING_ALLOW));
584     options->AppendString(
585         content_settings::ContentSettingToString(CONTENT_SETTING_BLOCK));
586     if (permission_type == CONTENT_SETTINGS_TYPE_COOKIES) {
587       options->AppendString(content_settings::ContentSettingToString(
588           CONTENT_SETTING_SESSION_ONLY));
589     }
590
591     ContentSetting permission;
592     content_settings::SettingInfo info;
593     if (permission_type == CONTENT_SETTINGS_TYPE_MEDIASTREAM) {
594       scoped_ptr<base::Value> mic_value(map->GetWebsiteSettingWithoutOverride(
595           site_url,
596           site_url,
597           CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC,
598           std::string(),
599           &info));
600       ContentSetting mic_setting =
601           content_settings::ValueToContentSetting(mic_value.get());
602       ContentSetting cam_setting = map->GetContentSettingWithoutOverride(
603           site_url,
604           site_url,
605           CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA,
606           std::string());
607
608       if (mic_setting != cam_setting)
609         permission = CONTENT_SETTING_ASK;
610       else
611         permission = mic_setting;
612     } else {
613       scoped_ptr<base::Value> v(map->GetWebsiteSettingWithoutOverride(
614           site_url, site_url, permission_type, std::string(), &info));
615       permission = content_settings::ValueToContentSetting(v.get());
616     }
617
618     base::DictionaryValue* permission_info = new base::DictionaryValue;
619     permission_info->SetStringWithoutPathExpansion(
620         "setting", content_settings::ContentSettingToString(permission));
621     permission_info->SetWithoutPathExpansion("options", options);
622     permission_info->SetBooleanWithoutPathExpansion(
623         "editable", info.source == content_settings::SETTING_SOURCE_USER);
624     permissions->SetWithoutPathExpansion(
625         content_settings::GetTypeName(permission_type), permission_info);
626   }
627
628   base::Value* storage_used = new base::StringValue(l10n_util::GetStringFUTF16(
629       IDS_WEBSITE_SETTINGS_STORAGE_USED, ui::FormatBytes(storage)));
630   base::Value* battery_used =
631       new base::StringValue(l10n_util::GetStringFUTF16Int(
632           IDS_WEBSITE_SETTINGS_BATTERY_USED, battery));
633
634   web_ui()->CallJavascriptFunction("WebsiteSettingsEditor.populateOrigin",
635                                    *storage_used,
636                                    *battery_used,
637                                    *permissions,
638                                    base::FundamentalValue(show_page));
639 }
640
641 void WebsiteSettingsHandler::UpdateLocalStorage() {
642   base::DictionaryValue local_storage_map;
643   for (LocalStorageList::const_iterator it = local_storage_list_.begin();
644        it != local_storage_list_.end();
645        it++) {
646     std::string origin = it->origin_url.spec();
647
648     if (origin.find(last_filter_) == base::string16::npos)
649       continue;
650
651     base::DictionaryValue* origin_entry = new base::DictionaryValue();
652     origin_entry->SetWithoutPathExpansion(
653         "usage", new base::FundamentalValue(static_cast<double>(it->size)));
654     origin_entry->SetWithoutPathExpansion(
655         "usageString", new base::StringValue(ui::FormatBytes(it->size)));
656     origin_entry->SetStringWithoutPathExpansion(
657         "readableName", GetReadableName(it->origin_url));
658     local_storage_map.SetWithoutPathExpansion(origin, origin_entry);
659   }
660   web_ui()->CallJavascriptFunction("WebsiteSettingsManager.populateOrigins",
661                                    local_storage_map);
662 }
663
664 void WebsiteSettingsHandler::UpdateBatteryUsage() {
665   base::DictionaryValue power_map;
666   OriginPowerMap* origins =
667       OriginPowerMapFactory::GetForBrowserContext(GetProfile());
668   OriginPowerMap::PercentOriginMap percent_map = origins->GetPercentOriginMap();
669   for (std::map<GURL, int>::iterator it = percent_map.begin();
670        it != percent_map.end();
671        ++it) {
672     std::string origin = it->first.spec();
673
674     if (origin.find(last_filter_) == base::string16::npos)
675       continue;
676
677     base::DictionaryValue* origin_entry = new base::DictionaryValue();
678     origin_entry->SetInteger("usage", it->second);
679     if (it->second == 0) {
680       origin_entry->SetString(
681           "usageString",
682           l10n_util::GetStringUTF16(IDS_WEBSITE_SETTINGS_BATTERY_ZERO_PERCENT));
683     } else {
684       origin_entry->SetString(
685           "usageString",
686           l10n_util::GetStringFUTF16Int(IDS_WEBSITE_SETTINGS_BATTERY_PERCENT,
687                                         it->second));
688     }
689     origin_entry->SetStringWithoutPathExpansion("readableName",
690                                                 GetReadableName(it->first));
691     power_map.SetWithoutPathExpansion(origin, origin_entry);
692   }
693   web_ui()->CallJavascriptFunction("WebsiteSettingsManager.populateOrigins",
694                                    power_map);
695 }
696
697 std::string WebsiteSettingsHandler::GetSettingDefaultFromModel(
698     ContentSettingsType type,
699     std::string* provider_id) {
700   Profile* profile = GetProfile();
701   ContentSetting default_setting =
702       profile->GetHostContentSettingsMap()->GetDefaultContentSetting(
703           type, provider_id);
704
705   return content_settings::ContentSettingToString(default_setting);
706 }
707
708 void WebsiteSettingsHandler::StopOrigin(const GURL& site_url) {
709   Profile* profile = GetProfile();
710   if (site_url.SchemeIs(extensions::kExtensionScheme)) {
711     const extensions::Extension* extension =
712         extensions::ExtensionRegistry::Get(profile)
713             ->enabled_extensions()
714             .GetHostedAppByURL(site_url);
715     if (extension) {
716       extensions::AppWindowRegistry::Get(profile)
717           ->CloseAllAppWindowsForApp(extension->id());
718     }
719   }
720
721   for (chrome::BrowserIterator it; !it.done(); it.Next()) {
722     Browser* browser = *it;
723     TabStripModel* model = browser->tab_strip_model();
724     for (int idx = 0; idx < model->count(); idx++) {
725       content::WebContents* web_contents = model->GetWebContentsAt(idx);
726       // Can't discard tabs that are already discarded or active.
727       if (model->IsTabDiscarded(idx) || (model->active_index() == idx))
728         continue;
729
730       // Don't discard tabs that belong to other profiles or other origins.
731       if (web_contents->GetLastCommittedURL().GetOrigin() != site_url ||
732           profile !=
733               Profile::FromBrowserContext(web_contents->GetBrowserContext())) {
734         continue;
735       }
736       model->DiscardWebContentsAt(idx);
737     }
738   }
739 }
740
741 void WebsiteSettingsHandler::DeleteLocalStorage(const GURL& site_url) {
742   Profile* profile = GetProfile();
743   content::DOMStorageContext* dom_storage_context_ =
744       content::BrowserContext::GetDefaultStoragePartition(profile)
745           ->GetDOMStorageContext();
746   dom_storage_context_->DeleteLocalStorage(site_url);
747
748   // Load a new BrowsingDataLocalStorageHelper to update.
749   local_storage_ = new BrowsingDataLocalStorageHelper(profile);
750
751   local_storage_->StartFetching(
752       base::Bind(&WebsiteSettingsHandler::OnLocalStorageFetched,
753                  weak_ptr_factory_.GetWeakPtr()));
754 }
755
756 const std::string& WebsiteSettingsHandler::GetReadableName(
757     const GURL& site_url) {
758   if (site_url.SchemeIs(extensions::kExtensionScheme)) {
759     Profile* profile = GetProfile();
760     ExtensionService* extension_service =
761         extensions::ExtensionSystem::Get(profile)->extension_service();
762
763     const extensions::Extension* extension =
764         extension_service->extensions()->GetExtensionOrAppByURL(site_url);
765     // If extension is NULL, it was removed and we cannot look up its name.
766     if (!extension)
767       return site_url.spec();
768
769     return extension->name();
770   }
771   return site_url.spec();
772 }
773
774 Profile* WebsiteSettingsHandler::GetProfile() {
775   Profile* profile = Profile::FromWebUI(web_ui());
776 #if defined(OS_CHROMEOS)
777   // Chrome OS special case: in Guest mode settings are opened in Incognito
778   // mode, so we need original profile to actually modify settings.
779   if (user_manager::UserManager::Get()->IsLoggedInAsGuest())
780     profile = profile->GetOriginalProfile();
781 #endif
782   return profile;
783 }
784
785 }  // namespace options