blob: 04668bb0d82836e2f3e3e88ab19774da3453eaca [file] [log] [blame]
// 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();
}