Chromium Code Reviews| Index: chrome/browser/extensions/extension_panel_event_router.cc |
| diff --git a/chrome/browser/extensions/extension_panel_event_router.cc b/chrome/browser/extensions/extension_panel_event_router.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..f1cf9a1c75ae5aed975458b16f5dcb05134dfdf1 |
| --- /dev/null |
| +++ b/chrome/browser/extensions/extension_panel_event_router.cc |
| @@ -0,0 +1,142 @@ |
| +// Copyright (c) 2012 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/extension_panel_event_router.h" |
| + |
| +#include "base/command_line.h" |
| +#include "base/json/json_writer.h" |
| +#include "base/values.h" |
| +#include "chrome/browser/extensions/extension_event_names.h" |
| +#include "chrome/browser/extensions/extension_event_router.h" |
| +#include "chrome/browser/extensions/extension_window_controller.h" |
| +#include "chrome/browser/profiles/profile.h" |
| +#include "chrome/browser/ui/panels/panel.h" |
| +#include "chrome/common/chrome_notification_types.h" |
| +#include "chrome/common/chrome_switches.h" |
| +#include "chrome/common/extensions/extension.h" |
| +#include "chrome/common/extensions/extension_constants.h" |
| +#include "content/public/browser/notification_service.h" |
| + |
| +ExtensionPanelEventRouter::ExtensionPanelEventRouter(Profile* profile) |
| + : initialized_(false), |
| + profile_(profile), |
| + focused_profile_(NULL), |
| + focused_window_id_(extension_misc::kUnknownWindowId) { |
| +} |
| + |
| +ExtensionPanelEventRouter::~ExtensionPanelEventRouter() { |
| +} |
| + |
| +void ExtensionPanelEventRouter::Init() { |
| + if (initialized_ || !CommandLine::ForCurrentProcess()->HasSwitch( |
| + switches::kBrowserlessPanels)) |
| + return; |
| + |
| + registrar_.Add(this, chrome::NOTIFICATION_PANEL_OPENED, |
| + content::NotificationService::AllSources()); |
| + registrar_.Add(this, chrome::NOTIFICATION_PANEL_CHANGED_ACTIVE_STATUS, |
| + content::NotificationService::AllSources()); |
| + registrar_.Add(this, chrome::NOTIFICATION_PANEL_CLOSED, |
| + content::NotificationService::AllSources()); |
| + initialized_ = true; |
| +} |
| + |
| +void ExtensionPanelEventRouter::Observe( |
| + int type, |
| + const content::NotificationSource& source, |
| + const content::NotificationDetails& details) { |
| + Panel* panel = content::Source<Panel>(source).ptr(); |
| + switch (type) { |
| + case chrome::NOTIFICATION_PANEL_OPENED: |
| + OnPanelOpened(panel); |
| + break; |
| + case chrome::NOTIFICATION_PANEL_CHANGED_ACTIVE_STATUS: { |
| + bool* is_active_now = content::Details<bool>(details).ptr(); |
| + OnPanelActiveStatusChanged(panel, *is_active_now); |
| + break; |
| + } |
| + case chrome::NOTIFICATION_PANEL_CLOSED: |
| + OnPanelClosed(panel); |
| + break; |
| + default: |
| + NOTREACHED(); |
| + break; |
| + } |
| +} |
| + |
| +void ExtensionPanelEventRouter::OnPanelOpened(Panel* panel) { |
| + if (!profile_->GetExtensionEventRouter()) |
| + return; |
| + |
| + ListValue args; |
| + DCHECK(panel->extension_window_controller()); |
| + DictionaryValue* window_dictionary = |
| + panel->extension_window_controller()->CreateWindowValue(); |
| + args.Append(window_dictionary); |
| + |
| + std::string json_args; |
| + base::JSONWriter::Write(&args, &json_args); |
| + profile_->GetExtensionEventRouter()->DispatchEventToRenderers( |
| + extension_event_names::kOnWindowCreated, json_args, profile_, GURL()); |
|
jianli
2012/07/13 17:46:41
Can you share the above code with the similar one
jennb
2012/07/13 22:12:14
Done.
|
| +} |
| + |
| +void ExtensionPanelEventRouter::OnPanelActiveStatusChanged( |
| + Panel* panel, bool is_active_now) { |
| + Profile* window_profile = NULL; |
| + int window_id = extension_misc::kUnknownWindowId; |
| + if (is_active_now) { |
| + window_profile = panel->profile(); |
| + window_id = panel->extension_window_controller()->GetWindowId(); |
| + } |
| + |
| + if (focused_window_id_ == window_id) |
| + return; |
| + |
| + // window_profile is either this profile's default profile, its |
| + // incognito profile, or NULL iff this profile is losing focus. |
| + Profile* previous_focused_profile = focused_profile_; |
| + focused_profile_ = window_profile; |
| + focused_window_id_ = window_id; |
| + |
| + ListValue real_args; |
| + real_args.Append(Value::CreateIntegerValue(window_id)); |
| + std::string real_json_args; |
| + base::JSONWriter::Write(&real_args, &real_json_args); |
| + |
| + // When switching between windows in the default and incognito profiles, |
| + // dispatch WINDOW_ID_NONE to extensions whose profile lost focus that |
| + // can't see the new focused window across the incognito boundary. |
| + // See crbug.com/46610. |
| + std::string none_json_args; |
| + if (focused_profile_ != NULL && previous_focused_profile != NULL && |
| + focused_profile_ != previous_focused_profile) { |
| + ListValue none_args; |
| + none_args.Append( |
| + Value::CreateIntegerValue(extension_misc::kUnknownWindowId)); |
| + base::JSONWriter::Write(&none_args, &none_json_args); |
| + } |
| + |
| + if (!window_profile) |
| + window_profile = previous_focused_profile; |
| + if (!window_profile->GetExtensionEventRouter()) |
| + return; |
| + window_profile->GetExtensionEventRouter()-> |
| + DispatchEventsToRenderersAcrossIncognito( |
| + extension_event_names::kOnWindowFocusedChanged, real_json_args, |
| + window_profile, none_json_args, GURL()); |
| +} |
| + |
| +void ExtensionPanelEventRouter::OnPanelClosed(Panel* panel) { |
| + if (!profile_->GetExtensionEventRouter()) |
| + return; |
| + |
| + int window_id = panel->extension_window_controller()->GetWindowId(); |
| + ListValue args; |
| + args.Append(Value::CreateIntegerValue(window_id)); |
| + |
| + std::string json_args; |
| + base::JSONWriter::Write(&args, &json_args); |
| + profile_->GetExtensionEventRouter()->DispatchEventToRenderers( |
| + extension_event_names::kOnWindowRemoved, json_args, profile_, GURL()); |
| +} |