blob: 799faab25f88f3e0a7726ff31e4358ddbc1a311a [file] [log] [blame]
// Copyright 2013 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/chrome_launcher_controller.h"
#include "base/memory/ptr_util.h"
#include "chrome/browser/extensions/extension_app_icon_loader.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/ui/app_list/arc/arc_app_icon_loader.h"
#include "chrome/browser/ui/ash/ash_util.h"
#include "chrome/browser/ui/ash/chrome_launcher_prefs.h"
#include "chrome/browser/ui/ash/launcher/launcher_controller_helper.h"
#include "content/public/common/service_manager_connection.h"
#include "content/public/common/service_names.mojom.h"
#include "services/service_manager/public/cpp/connector.h"
#include "ui/display/display.h"
#include "ui/display/screen.h"
// static
ChromeLauncherController* ChromeLauncherController::instance_ = nullptr;
ChromeLauncherController::~ChromeLauncherController() {
if (instance_ == this)
instance_ = nullptr;
}
void ChromeLauncherController::LaunchApp(const std::string& app_id,
ash::LaunchSource source,
int event_flags) {
launcher_controller_helper_->LaunchApp(app_id, source, event_flags);
}
ChromeLauncherController::ChromeLauncherController() : observer_binding_(this) {
DCHECK(!instance_);
instance_ = this;
// Start observing the shelf controller immediately.
if (ConnectToShelfController()) {
ash::mojom::ShelfObserverAssociatedPtrInfo ptr_info;
observer_binding_.Bind(&ptr_info, shelf_controller_.associated_group());
shelf_controller_->AddObserver(std::move(ptr_info));
}
}
bool ChromeLauncherController::ConnectToShelfController() {
if (shelf_controller_.is_bound())
return true;
auto connection = content::ServiceManagerConnection::GetForProcess();
auto connector = connection ? connection->GetConnector() : nullptr;
// Unit tests may not have a connector.
if (!connector)
return false;
// Under mash the ShelfController interface is in the ash process. In classic
// ash we provide it to ourself.
if (chrome::IsRunningInMash()) {
connector->ConnectToInterface("ash", &shelf_controller_);
} else {
connector->ConnectToInterface(content::mojom::kBrowserServiceName,
&shelf_controller_);
}
return true;
}
AppIconLoader* ChromeLauncherController::GetAppIconLoaderForApp(
const std::string& app_id) {
for (const auto& app_icon_loader : app_icon_loaders_) {
if (app_icon_loader->CanLoadImageForApp(app_id))
return app_icon_loader.get();
}
return nullptr;
}
void ChromeLauncherController::SetShelfAutoHideBehaviorFromPrefs() {
if (!ConnectToShelfController())
return;
// The pref helper functions return default values for invalid display ids.
PrefService* prefs = ProfileManager::GetActiveUserProfile()->GetPrefs();
for (const auto& display : display::Screen::GetScreen()->GetAllDisplays()) {
shelf_controller_->SetAutoHideBehavior(
ash::launcher::GetShelfAutoHideBehaviorPref(prefs, display.id()),
display.id());
}
}
void ChromeLauncherController::SetShelfAlignmentFromPrefs() {
if (!ConnectToShelfController())
return;
// The pref helper functions return default values for invalid display ids.
PrefService* prefs = ProfileManager::GetActiveUserProfile()->GetPrefs();
for (const auto& display : display::Screen::GetScreen()->GetAllDisplays()) {
shelf_controller_->SetAlignment(
ash::launcher::GetShelfAlignmentPref(prefs, display.id()),
display.id());
}
}
void ChromeLauncherController::SetShelfBehaviorsFromPrefs() {
SetShelfAutoHideBehaviorFromPrefs();
SetShelfAlignmentFromPrefs();
}
void ChromeLauncherController::SetLauncherControllerHelperForTest(
std::unique_ptr<LauncherControllerHelper> helper) {
launcher_controller_helper_ = std::move(helper);
}
void ChromeLauncherController::SetAppIconLoadersForTest(
std::vector<std::unique_ptr<AppIconLoader>>& loaders) {
app_icon_loaders_.clear();
for (auto& loader : loaders)
app_icon_loaders_.push_back(std::move(loader));
}
void ChromeLauncherController::SetProfileForTest(Profile* profile) {
profile_ = profile;
}
void ChromeLauncherController::AttachProfile(Profile* profile_to_attach) {
profile_ = profile_to_attach;
// Either add the profile to the list of known profiles and make it the active
// one for some functions of LauncherControllerHelper or create a new one.
if (!launcher_controller_helper_.get()) {
launcher_controller_helper_ =
base::MakeUnique<LauncherControllerHelper>(profile_);
} else {
launcher_controller_helper_->set_profile(profile_);
}
// TODO(skuhne): The AppIconLoaderImpl has the same problem. Each loaded
// image is associated with a profile (its loader requires the profile).
// Since icon size changes are possible, the icon could be requested to be
// reloaded. However - having it not multi profile aware would cause problems
// if the icon cache gets deleted upon user switch.
std::unique_ptr<AppIconLoader> extension_app_icon_loader =
base::MakeUnique<extensions::ExtensionAppIconLoader>(
profile_, extension_misc::EXTENSION_ICON_SMALL, this);
app_icon_loaders_.push_back(std::move(extension_app_icon_loader));
if (arc::ArcSessionManager::IsAllowedForProfile(profile_)) {
std::unique_ptr<AppIconLoader> arc_app_icon_loader =
base::MakeUnique<ArcAppIconLoader>(
profile_, extension_misc::EXTENSION_ICON_SMALL, this);
app_icon_loaders_.push_back(std::move(arc_app_icon_loader));
}
}
void ChromeLauncherController::OnShelfCreated(int64_t display_id) {
if (!ConnectToShelfController())
return;
// The pref helper functions return default values for invalid display ids.
PrefService* prefs = profile_->GetPrefs();
shelf_controller_->SetAlignment(
ash::launcher::GetShelfAlignmentPref(prefs, display_id), display_id);
shelf_controller_->SetAutoHideBehavior(
ash::launcher::GetShelfAutoHideBehaviorPref(prefs, display_id),
display_id);
}
void ChromeLauncherController::OnAlignmentChanged(ash::ShelfAlignment alignment,
int64_t display_id) {
// The locked alignment is set temporarily and not saved to preferences.
if (alignment == ash::SHELF_ALIGNMENT_BOTTOM_LOCKED)
return;
// This will uselessly store a preference value for invalid display ids.
// TODO(msw): Avoid handling this pref change and forwarding the value to ash.
ash::launcher::SetShelfAlignmentPref(profile_->GetPrefs(), display_id,
alignment);
}
void ChromeLauncherController::OnAutoHideBehaviorChanged(
ash::ShelfAutoHideBehavior auto_hide,
int64_t display_id) {
// This will uselessly store a preference value for invalid display ids.
// TODO(msw): Avoid handling this pref change and forwarding the value to ash.
ash::launcher::SetShelfAutoHideBehaviorPref(profile_->GetPrefs(), display_id,
auto_hide);
}
void ChromeLauncherController::OnAppImageUpdated(const std::string& app_id,
const gfx::ImageSkia& image) {
// Implemented by subclasses; this should not be called.
NOTREACHED();
}