| // Copyright 2013 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chrome/browser/extensions/api/messaging/incognito_connectability.h" |
| |
| #include "base/lazy_instance.h" |
| #include "base/logging.h" |
| #include "base/strings/string16.h" |
| #include "base/strings/utf_string_conversions.h" |
| #include "chrome/browser/ui/simple_message_box.h" |
| #include "content/public/browser/web_contents.h" |
| #include "content/public/browser/web_contents_view.h" |
| #include "extensions/common/extension.h" |
| #include "grit/generated_resources.h" |
| #include "ui/base/l10n/l10n_util.h" |
| |
| namespace extensions { |
| |
| namespace { |
| IncognitoConnectability::ScopedAlertTracker::Mode g_alert_mode = |
| IncognitoConnectability::ScopedAlertTracker::INTERACTIVE; |
| int g_alert_count = 0; |
| } |
| |
| IncognitoConnectability::ScopedAlertTracker::ScopedAlertTracker(Mode mode) |
| : last_checked_invocation_count_(g_alert_count) { |
| DCHECK_EQ(INTERACTIVE, g_alert_mode); |
| DCHECK_NE(INTERACTIVE, mode); |
| g_alert_mode = mode; |
| } |
| |
| IncognitoConnectability::ScopedAlertTracker::~ScopedAlertTracker() { |
| DCHECK_NE(INTERACTIVE, g_alert_mode); |
| g_alert_mode = INTERACTIVE; |
| } |
| |
| int IncognitoConnectability::ScopedAlertTracker::GetAndResetAlertCount() { |
| int result = g_alert_count - last_checked_invocation_count_; |
| last_checked_invocation_count_ = g_alert_count; |
| return result; |
| } |
| |
| IncognitoConnectability::IncognitoConnectability(Profile* profile) { |
| CHECK(profile->IsOffTheRecord()); |
| } |
| |
| IncognitoConnectability::~IncognitoConnectability() { |
| } |
| |
| // static |
| IncognitoConnectability* IncognitoConnectability::Get(Profile* profile) { |
| return ProfileKeyedAPIFactory<IncognitoConnectability>::GetForProfile( |
| profile); |
| } |
| |
| bool IncognitoConnectability::Query(const Extension* extension, |
| content::WebContents* web_contents, |
| const GURL& url) { |
| GURL origin = url.GetOrigin(); |
| if (origin.is_empty()) |
| return false; |
| |
| if (IsInMap(extension, origin, allowed_origins_)) |
| return true; |
| if (IsInMap(extension, origin, disallowed_origins_)) |
| return false; |
| |
| // We need to ask the user. |
| ++g_alert_count; |
| chrome::MessageBoxResult result = chrome::MESSAGE_BOX_RESULT_NO; |
| |
| switch (g_alert_mode) { |
| // Production code should always be using INTERACTIVE. |
| case ScopedAlertTracker::INTERACTIVE: { |
| int template_id = extension->is_app() ? |
| IDS_EXTENSION_PROMPT_APP_CONNECT_FROM_INCOGNITO : |
| IDS_EXTENSION_PROMPT_EXTENSION_CONNECT_FROM_INCOGNITO; |
| result = chrome::ShowMessageBox( |
| web_contents ? web_contents->GetView()->GetTopLevelNativeWindow() |
| : NULL, |
| base::string16(), // no title |
| l10n_util::GetStringFUTF16(template_id, |
| UTF8ToUTF16(origin.spec()), |
| UTF8ToUTF16(extension->name())), |
| chrome::MESSAGE_BOX_TYPE_QUESTION); |
| break; |
| } |
| |
| // Testing code can override to always allow or deny. |
| case ScopedAlertTracker::ALWAYS_ALLOW: |
| result = chrome::MESSAGE_BOX_RESULT_YES; |
| break; |
| case ScopedAlertTracker::ALWAYS_DENY: |
| result = chrome::MESSAGE_BOX_RESULT_NO; |
| break; |
| } |
| |
| if (result == chrome::MESSAGE_BOX_RESULT_NO) { |
| disallowed_origins_[extension->id()].insert(origin); |
| return false; |
| } |
| allowed_origins_[extension->id()].insert(origin); |
| return true; |
| } |
| |
| bool IncognitoConnectability::IsInMap(const Extension* extension, |
| const GURL& origin, |
| const ExtensionToOriginsMap& map) { |
| DCHECK_EQ(origin, origin.GetOrigin()); |
| ExtensionToOriginsMap::const_iterator it = map.find(extension->id()); |
| return it != map.end() && it->second.count(origin) > 0; |
| } |
| |
| static base::LazyInstance<ProfileKeyedAPIFactory<IncognitoConnectability> > |
| g_factory = LAZY_INSTANCE_INITIALIZER; |
| |
| // static |
| ProfileKeyedAPIFactory<IncognitoConnectability>* |
| IncognitoConnectability::GetFactoryInstance() { |
| return &g_factory.Get(); |
| } |
| |
| } // namespace extensions |