1 // Copyright (c) 2010 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/geolocation/geolocation_settings_state.h" 6 7 #include "base/string_piece.h" 8 #include "base/utf_string_conversions.h" 9 #include "chrome/browser/geolocation/geolocation_content_settings_map.h" 10 #include "chrome/browser/prefs/pref_service.h" 11 #include "chrome/browser/profiles/profile.h" 12 #include "chrome/common/pref_names.h" 13 #include "content/browser/tab_contents/navigation_entry.h" 14 #include "net/base/net_util.h" 15 16 GeolocationSettingsState::GeolocationSettingsState(Profile* profile) 17 : profile_(profile) { 18 } 19 20 GeolocationSettingsState::~GeolocationSettingsState() { 21 } 22 23 void GeolocationSettingsState::OnGeolocationPermissionSet( 24 const GURL& requesting_origin, bool allowed) { 25 state_map_[requesting_origin] = 26 allowed ? CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK; 27 } 28 29 void GeolocationSettingsState::DidNavigate( 30 const NavigationController::LoadCommittedDetails& details) { 31 if (details.entry) 32 embedder_url_ = details.entry->url(); 33 if (state_map_.empty()) 34 return; 35 if (!details.entry || 36 details.previous_url.GetOrigin() != details.entry->url().GetOrigin()) { 37 state_map_.clear(); 38 return; 39 } 40 // We're in the same origin, check if there's any icon to be displayed. 41 unsigned int tab_state_flags = 0; 42 GetDetailedInfo(NULL, &tab_state_flags); 43 if (!(tab_state_flags & TABSTATE_HAS_ANY_ICON)) 44 state_map_.clear(); 45 } 46 47 void GeolocationSettingsState::ClearStateMap() { 48 state_map_.clear(); 49 } 50 51 void GeolocationSettingsState::GetDetailedInfo( 52 FormattedHostsPerState* formatted_hosts_per_state, 53 unsigned int* tab_state_flags) const { 54 DCHECK(tab_state_flags); 55 DCHECK(embedder_url_.is_valid()); 56 const ContentSetting default_setting = 57 profile_->GetGeolocationContentSettingsMap()->GetDefaultContentSetting(); 58 std::set<std::string> formatted_hosts; 59 std::set<std::string> repeated_formatted_hosts; 60 61 // Build a set of repeated formatted hosts 62 for (StateMap::const_iterator i(state_map_.begin()); 63 i != state_map_.end(); ++i) { 64 std::string formatted_host = GURLToFormattedHost(i->first); 65 if (!formatted_hosts.insert(formatted_host).second) { 66 repeated_formatted_hosts.insert(formatted_host); 67 } 68 } 69 70 for (StateMap::const_iterator i(state_map_.begin()); 71 i != state_map_.end(); ++i) { 72 if (i->second == CONTENT_SETTING_ALLOW) 73 *tab_state_flags |= TABSTATE_HAS_ANY_ALLOWED; 74 if (formatted_hosts_per_state) { 75 std::string formatted_host = GURLToFormattedHost(i->first); 76 std::string final_formatted_host = 77 repeated_formatted_hosts.find(formatted_host) == 78 repeated_formatted_hosts.end() ? 79 formatted_host : 80 i->first.spec(); 81 (*formatted_hosts_per_state)[i->second].insert(final_formatted_host); 82 } 83 84 const ContentSetting saved_setting = 85 profile_->GetGeolocationContentSettingsMap()->GetContentSetting( 86 i->first, embedder_url_); 87 if (saved_setting != default_setting) 88 *tab_state_flags |= TABSTATE_HAS_EXCEPTION; 89 if (saved_setting != i->second) 90 *tab_state_flags |= TABSTATE_HAS_CHANGED; 91 if (saved_setting != CONTENT_SETTING_ASK) 92 *tab_state_flags |= TABSTATE_HAS_ANY_ICON; 93 } 94 } 95 96 std::string GeolocationSettingsState::GURLToFormattedHost( 97 const GURL& url) const { 98 std::wstring display_host_wide; 99 net::AppendFormattedHost( 100 url, UTF8ToWide(profile_->GetPrefs()->GetString(prefs::kAcceptLanguages)), 101 &display_host_wide, NULL, NULL); 102 return WideToUTF8(display_host_wide); 103 } 104