summaryrefslogtreecommitdiff
path: root/chromium/extensions/browser/api/socket/app_firewall_hole_manager.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/extensions/browser/api/socket/app_firewall_hole_manager.cc')
-rw-r--r--chromium/extensions/browser/api/socket/app_firewall_hole_manager.cc166
1 files changed, 166 insertions, 0 deletions
diff --git a/chromium/extensions/browser/api/socket/app_firewall_hole_manager.cc b/chromium/extensions/browser/api/socket/app_firewall_hole_manager.cc
new file mode 100644
index 00000000000..f5973734081
--- /dev/null
+++ b/chromium/extensions/browser/api/socket/app_firewall_hole_manager.cc
@@ -0,0 +1,166 @@
+// Copyright 2015 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 "extensions/browser/api/socket/app_firewall_hole_manager.h"
+
+#include <utility>
+
+#include "base/bind.h"
+#include "base/stl_util.h"
+#include "components/keyed_service/content/browser_context_dependency_manager.h"
+#include "content/public/browser/browser_context.h"
+#include "extensions/browser/app_window/app_window.h"
+
+using chromeos::FirewallHole;
+using content::BrowserContext;
+
+namespace extensions {
+
+namespace {
+
+class AppFirewallHoleManagerFactory : public BrowserContextKeyedServiceFactory {
+ public:
+ static AppFirewallHoleManager* GetForBrowserContext(BrowserContext* context,
+ bool create) {
+ return static_cast<AppFirewallHoleManager*>(
+ GetInstance()->GetServiceForBrowserContext(context, create));
+ }
+
+ static AppFirewallHoleManagerFactory* GetInstance() {
+ return base::Singleton<AppFirewallHoleManagerFactory>::get();
+ }
+
+ AppFirewallHoleManagerFactory()
+ : BrowserContextKeyedServiceFactory(
+ "AppFirewallHoleManager",
+ BrowserContextDependencyManager::GetInstance()) {
+ DependsOn(AppWindowRegistry::Factory::GetInstance());
+ }
+
+ ~AppFirewallHoleManagerFactory() override {}
+
+ private:
+ // BrowserContextKeyedServiceFactory
+ KeyedService* BuildServiceInstanceFor(
+ BrowserContext* context) const override {
+ return new AppFirewallHoleManager(context);
+ }
+
+ BrowserContext* GetBrowserContextToUse(
+ BrowserContext* context) const override {
+ return context;
+ }
+};
+
+bool HasVisibleAppWindows(BrowserContext* context,
+ const std::string& extension_id) {
+ AppWindowRegistry* registry = AppWindowRegistry::Get(context);
+
+ for (const AppWindow* window : registry->GetAppWindowsForApp(extension_id)) {
+ if (!window->is_hidden()) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+} // namespace
+
+AppFirewallHole::~AppFirewallHole() {
+ manager_->Close(this);
+}
+
+AppFirewallHole::AppFirewallHole(AppFirewallHoleManager* manager,
+ PortType type,
+ uint16_t port,
+ const std::string& extension_id)
+ : type_(type),
+ port_(port),
+ extension_id_(extension_id),
+ manager_(manager),
+ weak_factory_(this) {
+}
+
+void AppFirewallHole::SetVisible(bool app_visible) {
+ app_visible_ = app_visible;
+ if (app_visible_) {
+ if (!firewall_hole_) {
+ FirewallHole::Open(type_, port_, "" /* all interfaces */,
+ base::Bind(&AppFirewallHole::OnFirewallHoleOpened,
+ weak_factory_.GetWeakPtr()));
+ }
+ } else {
+ firewall_hole_.reset(nullptr);
+ }
+}
+
+void AppFirewallHole::OnFirewallHoleOpened(
+ scoped_ptr<FirewallHole> firewall_hole) {
+ if (app_visible_) {
+ DCHECK(!firewall_hole_);
+ firewall_hole_ = std::move(firewall_hole);
+ }
+}
+
+AppFirewallHoleManager::AppFirewallHoleManager(BrowserContext* context)
+ : context_(context), observer_(this) {
+ observer_.Add(AppWindowRegistry::Get(context));
+}
+
+AppFirewallHoleManager::~AppFirewallHoleManager() {
+ STLDeleteValues(&tracked_holes_);
+}
+
+AppFirewallHoleManager* AppFirewallHoleManager::Get(BrowserContext* context) {
+ return AppFirewallHoleManagerFactory::GetForBrowserContext(context, true);
+}
+
+scoped_ptr<AppFirewallHole> AppFirewallHoleManager::Open(
+ AppFirewallHole::PortType type,
+ uint16_t port,
+ const std::string& extension_id) {
+ scoped_ptr<AppFirewallHole> hole(
+ new AppFirewallHole(this, type, port, extension_id));
+ tracked_holes_.insert(std::make_pair(extension_id, hole.get()));
+ if (HasVisibleAppWindows(context_, extension_id)) {
+ hole->SetVisible(true);
+ }
+ return hole;
+}
+
+void AppFirewallHoleManager::Close(AppFirewallHole* hole) {
+ auto range = tracked_holes_.equal_range(hole->extension_id());
+ for (auto iter = range.first; iter != range.second; ++iter) {
+ if (iter->second == hole) {
+ tracked_holes_.erase(iter);
+ return;
+ }
+ }
+ NOTREACHED();
+}
+
+void AppFirewallHoleManager::OnAppWindowRemoved(AppWindow* app_window) {
+ OnAppWindowHidden(app_window);
+}
+
+void AppFirewallHoleManager::OnAppWindowHidden(AppWindow* app_window) {
+ DCHECK(context_ == app_window->browser_context());
+ if (!HasVisibleAppWindows(context_, app_window->extension_id())) {
+ const auto& range = tracked_holes_.equal_range(app_window->extension_id());
+ for (auto iter = range.first; iter != range.second; ++iter) {
+ iter->second->SetVisible(false);
+ }
+ }
+}
+
+void AppFirewallHoleManager::OnAppWindowShown(AppWindow* app_window,
+ bool was_hidden) {
+ const auto& range = tracked_holes_.equal_range(app_window->extension_id());
+ for (auto iter = range.first; iter != range.second; ++iter) {
+ iter->second->SetVisible(true);
+ }
+}
+
+} // namespace extensions