Revert "Fix broken channel icon in chrome://help on CrOS" and try again
[chromium-blink-merge.git] / extensions / browser / api / socket / app_firewall_hole_manager.cc
blobbfb2b1ac145f132bbdf55d9b7a974953c05e7a2e
1 // Copyright 2015 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.
5 #include "extensions/browser/api/socket/app_firewall_hole_manager.h"
7 #include <utility>
9 #include "base/bind.h"
10 #include "base/stl_util.h"
11 #include "components/keyed_service/content/browser_context_dependency_manager.h"
12 #include "content/public/browser/browser_context.h"
13 #include "extensions/browser/app_window/app_window.h"
15 using chromeos::FirewallHole;
16 using content::BrowserContext;
18 namespace extensions {
20 namespace {
22 class AppFirewallHoleManagerFactory : public BrowserContextKeyedServiceFactory {
23 public:
24 static AppFirewallHoleManager* GetForBrowserContext(BrowserContext* context,
25 bool create) {
26 return static_cast<AppFirewallHoleManager*>(
27 GetInstance()->GetServiceForBrowserContext(context, create));
30 static AppFirewallHoleManagerFactory* GetInstance() {
31 return Singleton<AppFirewallHoleManagerFactory>::get();
34 AppFirewallHoleManagerFactory()
35 : BrowserContextKeyedServiceFactory(
36 "AppFirewallHoleManager",
37 BrowserContextDependencyManager::GetInstance()) {
38 DependsOn(AppWindowRegistry::Factory::GetInstance());
41 ~AppFirewallHoleManagerFactory() override {}
43 private:
44 // BrowserContextKeyedServiceFactory
45 KeyedService* BuildServiceInstanceFor(
46 BrowserContext* context) const override {
47 return new AppFirewallHoleManager(context);
50 BrowserContext* GetBrowserContextToUse(
51 BrowserContext* context) const override {
52 return context;
56 bool HasVisibleAppWindows(BrowserContext* context,
57 const std::string& extension_id) {
58 AppWindowRegistry* registry = AppWindowRegistry::Get(context);
60 for (const AppWindow* window : registry->GetAppWindowsForApp(extension_id)) {
61 if (!window->is_hidden()) {
62 return true;
66 return false;
69 } // namespace
71 AppFirewallHole::~AppFirewallHole() {
72 manager_->Close(this);
75 AppFirewallHole::AppFirewallHole(AppFirewallHoleManager* manager,
76 PortType type,
77 uint16_t port,
78 const std::string& extension_id)
79 : type_(type),
80 port_(port),
81 extension_id_(extension_id),
82 manager_(manager),
83 weak_factory_(this) {
86 void AppFirewallHole::SetVisible(bool app_visible) {
87 app_visible_ = app_visible;
88 if (app_visible_) {
89 if (!firewall_hole_) {
90 FirewallHole::Open(type_, port_, "" /* all interfaces */,
91 base::Bind(&AppFirewallHole::OnFirewallHoleOpened,
92 weak_factory_.GetWeakPtr()));
94 } else {
95 firewall_hole_.reset(nullptr);
99 void AppFirewallHole::OnFirewallHoleOpened(
100 scoped_ptr<FirewallHole> firewall_hole) {
101 if (app_visible_) {
102 DCHECK(!firewall_hole_);
103 firewall_hole_ = firewall_hole.Pass();
107 AppFirewallHoleManager::AppFirewallHoleManager(BrowserContext* context)
108 : context_(context), observer_(this) {
109 observer_.Add(AppWindowRegistry::Get(context));
112 AppFirewallHoleManager::~AppFirewallHoleManager() {
113 STLDeleteValues(&tracked_holes_);
116 AppFirewallHoleManager* AppFirewallHoleManager::Get(BrowserContext* context) {
117 return AppFirewallHoleManagerFactory::GetForBrowserContext(context, true);
120 scoped_ptr<AppFirewallHole> AppFirewallHoleManager::Open(
121 AppFirewallHole::PortType type,
122 uint16_t port,
123 const std::string& extension_id) {
124 scoped_ptr<AppFirewallHole> hole(
125 new AppFirewallHole(this, type, port, extension_id));
126 tracked_holes_.insert(std::make_pair(extension_id, hole.get()));
127 if (HasVisibleAppWindows(context_, extension_id)) {
128 hole->SetVisible(true);
130 return hole.Pass();
133 void AppFirewallHoleManager::Close(AppFirewallHole* hole) {
134 auto range = tracked_holes_.equal_range(hole->extension_id());
135 for (auto iter = range.first; iter != range.second; ++iter) {
136 if (iter->second == hole) {
137 tracked_holes_.erase(iter);
138 return;
141 NOTREACHED();
144 void AppFirewallHoleManager::OnAppWindowRemoved(AppWindow* app_window) {
145 OnAppWindowHidden(app_window);
148 void AppFirewallHoleManager::OnAppWindowHidden(AppWindow* app_window) {
149 DCHECK(context_ == app_window->browser_context());
150 if (!HasVisibleAppWindows(context_, app_window->extension_id())) {
151 const auto& range = tracked_holes_.equal_range(app_window->extension_id());
152 for (auto iter = range.first; iter != range.second; ++iter) {
153 iter->second->SetVisible(false);
158 void AppFirewallHoleManager::OnAppWindowShown(AppWindow* app_window,
159 bool was_hidden) {
160 const auto& range = tracked_holes_.equal_range(app_window->extension_id());
161 for (auto iter = range.first; iter != range.second; ++iter) {
162 iter->second->SetVisible(true);
166 } // namespace extensions