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