| // 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/ui/ash/launcher/browser_launcher_item_controller.h" |
| |
| #include "ash/launcher/launcher.h" |
| #include "ash/launcher/launcher_model.h" |
| #include "ash/shell.h" |
| #include "ash/wm/window_util.h" |
| #include "chrome/browser/extensions/extension_service.h" |
| #include "chrome/browser/extensions/tab_helper.h" |
| #include "chrome/browser/favicon/favicon_tab_helper.h" |
| #include "chrome/browser/profiles/profile.h" |
| #include "chrome/browser/ui/ash/launcher/chrome_launcher_app_menu_item.h" |
| #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h" |
| #include "chrome/browser/ui/browser.h" |
| #include "chrome/browser/ui/browser_list.h" |
| #include "chrome/browser/ui/browser_window.h" |
| #include "chrome/browser/ui/tabs/tab_strip_model.h" |
| #include "chrome/browser/web_applications/web_app.h" |
| #include "chrome/common/extensions/manifest_handlers/icons_handler.h" |
| #include "content/public/browser/web_contents.h" |
| #include "grit/ui_resources.h" |
| #include "ui/aura/client/aura_constants.h" |
| #include "ui/aura/window.h" |
| #include "ui/base/resource/resource_bundle.h" |
| #include "ui/views/widget/widget.h" |
| |
| BrowserLauncherItemController::BrowserLauncherItemController( |
| Type type, |
| aura::Window* window, |
| TabStripModel* tab_model, |
| ChromeLauncherController* launcher_controller, |
| const std::string& app_id) |
| : LauncherItemController(type, app_id, launcher_controller), |
| window_(window), |
| tab_model_(tab_model), |
| is_incognito_(tab_model->profile()->GetOriginalProfile() != |
| tab_model->profile() && |
| !tab_model->profile()->IsGuestSession()) { |
| DCHECK(window_); |
| window_->AddObserver(this); |
| } |
| |
| BrowserLauncherItemController::~BrowserLauncherItemController() { |
| tab_model_->RemoveObserver(this); |
| window_->RemoveObserver(this); |
| if (launcher_id() > 0) |
| launcher_controller()->CloseLauncherItem(launcher_id()); |
| if (type() == TYPE_WINDOWED_APP) |
| launcher_controller()->UnlockV1AppWithID(LauncherItemController::app_id()); |
| } |
| |
| const std::string& BrowserLauncherItemController::app_id() const { |
| if (type() == TYPE_WINDOWED_APP) |
| return empty_app_id_; |
| return LauncherItemController::app_id(); |
| } |
| |
| void BrowserLauncherItemController::Init() { |
| tab_model_->AddObserver(this); |
| ash::LauncherItemStatus app_status = |
| ash::wm::IsActiveWindow(window_) ? |
| ash::STATUS_ACTIVE : ash::STATUS_RUNNING; |
| if (type() != TYPE_TABBED && type() != TYPE_WINDOWED_APP) |
| launcher_controller()->CreateAppLauncherItem(this, app_id(), app_status); |
| else if (type() == TYPE_WINDOWED_APP) |
| launcher_controller()->LockV1AppWithID(LauncherItemController::app_id()); |
| |
| // In testing scenarios we can get tab strips with no active contents. |
| if (tab_model_->active_index() != TabStripModel::kNoTab) |
| UpdateLauncher(tab_model_->GetActiveWebContents()); |
| } |
| |
| // static |
| BrowserLauncherItemController* BrowserLauncherItemController::Create( |
| Browser* browser) { |
| // Under testing this can be called before the controller is created. |
| if (!ChromeLauncherController::instance()) |
| return NULL; |
| |
| Type type; |
| std::string app_id; |
| if (browser->is_type_tabbed() || browser->is_type_popup()) { |
| type = TYPE_TABBED; |
| if (!browser->is_type_tabbed() && |
| browser->is_type_popup() && |
| browser->is_app()) { |
| app_id = web_app::GetExtensionIdFromApplicationName( |
| browser->app_name()); |
| // Only allow this for known applications. Some unit tests for example |
| // do not have one. |
| if (!app_id.empty()) |
| type = TYPE_WINDOWED_APP; |
| } |
| } else if (browser->is_app()) { |
| type = TYPE_TABBED; |
| app_id = web_app::GetExtensionIdFromApplicationName(browser->app_name()); |
| } else { |
| return NULL; |
| } |
| BrowserLauncherItemController* controller = |
| new BrowserLauncherItemController(type, |
| browser->window()->GetNativeWindow(), |
| browser->tab_strip_model(), |
| ChromeLauncherController::instance(), |
| app_id); |
| controller->Init(); |
| return controller; |
| } |
| |
| void BrowserLauncherItemController::BrowserActivationStateChanged() { |
| content::WebContents* active_contents = tab_model_->GetActiveWebContents(); |
| if (active_contents) |
| UpdateAppState(active_contents); |
| UpdateItemStatus(); |
| } |
| |
| string16 BrowserLauncherItemController::GetTitle() { |
| if (type() == TYPE_TABBED) { |
| if (tab_model_->active_index() != TabStripModel::kNoTab) { |
| const content::WebContents* contents = tab_model_->GetActiveWebContents(); |
| if (contents) |
| return contents->GetTitle(); |
| } |
| } |
| return GetAppTitle(); |
| } |
| |
| bool BrowserLauncherItemController::IsCurrentlyShownInWindow( |
| aura::Window* window) const { |
| return window_ == window; |
| } |
| |
| bool BrowserLauncherItemController::IsOpen() const { |
| return true; |
| } |
| |
| bool BrowserLauncherItemController::IsVisible() const { |
| return window_->IsVisible(); |
| } |
| |
| void BrowserLauncherItemController::Launch(int event_flags) { |
| DCHECK(!app_id().empty()); |
| launcher_controller()->LaunchApp(app_id(), event_flags); |
| } |
| |
| void BrowserLauncherItemController::Activate() { |
| window_->Show(); |
| ash::wm::ActivateWindow(window_); |
| } |
| |
| void BrowserLauncherItemController::Close() { |
| views::Widget* widget = views::Widget::GetWidgetForNativeView(window_); |
| if (widget) |
| widget->Close(); |
| } |
| |
| void BrowserLauncherItemController::Clicked(const ui::Event& event) { |
| views::Widget* widget = |
| views::Widget::GetWidgetForNativeView(window_); |
| if (widget && widget->IsActive()) { |
| widget->Minimize(); |
| } else { |
| Activate(); |
| } |
| } |
| |
| void BrowserLauncherItemController::OnRemoved() { |
| } |
| |
| void BrowserLauncherItemController::LauncherItemChanged( |
| int index, |
| const ash::LauncherItem& old_item) { |
| } |
| |
| ChromeLauncherAppMenuItems |
| BrowserLauncherItemController::GetApplicationList(int event_flags) { |
| // This will never be called and the entire class will go away. |
| ChromeLauncherAppMenuItems items; |
| return items.Pass(); |
| } |
| |
| void BrowserLauncherItemController::ActiveTabChanged( |
| content::WebContents* old_contents, |
| content::WebContents* new_contents, |
| int index, |
| int reason) { |
| // Update immediately on a tab change. |
| if (old_contents && |
| TabStripModel::kNoTab != |
| tab_model_->GetIndexOfWebContents(old_contents)) |
| UpdateAppState(old_contents); |
| UpdateAppState(new_contents); |
| UpdateLauncher(new_contents); |
| } |
| |
| void BrowserLauncherItemController::TabInsertedAt( |
| content::WebContents* contents, |
| int index, |
| bool foreground) { |
| UpdateAppState(contents); |
| } |
| |
| void BrowserLauncherItemController::TabDetachedAt( |
| content::WebContents* contents, |
| int index) { |
| launcher_controller()->UpdateAppState( |
| contents, ChromeLauncherController::APP_STATE_REMOVED); |
| } |
| |
| void BrowserLauncherItemController::TabChangedAt( |
| content::WebContents* contents, |
| int index, |
| TabStripModelObserver::TabChangeType change_type) { |
| UpdateAppState(contents); |
| if (index != tab_model_->active_index() || |
| !(change_type != TabStripModelObserver::LOADING_ONLY && |
| change_type != TabStripModelObserver::TITLE_NOT_LOADING)) { |
| return; |
| } |
| |
| UpdateLauncher(contents); |
| } |
| |
| void BrowserLauncherItemController::TabReplacedAt( |
| TabStripModel* tab_strip_model, |
| content::WebContents* old_contents, |
| content::WebContents* new_contents, |
| int index) { |
| launcher_controller()->UpdateAppState( |
| old_contents, |
| ChromeLauncherController::APP_STATE_REMOVED); |
| UpdateAppState(new_contents); |
| } |
| |
| void BrowserLauncherItemController::OnWindowPropertyChanged( |
| aura::Window* window, |
| const void* key, |
| intptr_t old) { |
| if (key == aura::client::kDrawAttentionKey) |
| UpdateItemStatus(); |
| } |
| |
| void BrowserLauncherItemController::UpdateItemStatus() { |
| } |
| |
| void BrowserLauncherItemController::UpdateLauncher(content::WebContents* tab) { |
| } |
| |
| void BrowserLauncherItemController::UpdateAppState(content::WebContents* tab) { |
| ChromeLauncherController::AppState app_state; |
| |
| if (tab_model_->GetActiveWebContents() == tab) { |
| if (ash::wm::IsActiveWindow(window_)) |
| app_state = ChromeLauncherController::APP_STATE_WINDOW_ACTIVE; |
| else |
| app_state = ChromeLauncherController::APP_STATE_ACTIVE; |
| } else { |
| app_state = ChromeLauncherController::APP_STATE_INACTIVE; |
| } |
| launcher_controller()->UpdateAppState(tab, app_state); |
| } |
| |
| ash::LauncherModel* BrowserLauncherItemController::launcher_model() { |
| return launcher_controller()->model(); |
| } |