diff options
author | derat@chromium.org <derat@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-03-21 00:05:41 +0000 |
---|---|---|
committer | derat@chromium.org <derat@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-03-21 00:05:41 +0000 |
commit | 1410fb00866fd282414a32e04b300230a51bbe1c (patch) | |
tree | 8a737a4414af262de364b3e56af898e990d9dc23 | |
parent | 9fe2d0edd3d21c60886ebeb449fc057ace9ebe76 (diff) | |
download | chromium_src-1410fb00866fd282414a32e04b300230a51bbe1c.zip chromium_src-1410fb00866fd282414a32e04b300230a51bbe1c.tar.gz chromium_src-1410fb00866fd282414a32e04b300230a51bbe1c.tar.bz2 |
ash/chromeos: Defer creating launcher until after login.
This fixes several issues (blank titles in context menu,
missing icons, pinned apps not getting restored) caused by
launcher-related code that was initialized at startup and
cached the pre-login profile. This change makes us defer
initialization of the launcher until after the user has
logged in when running on Chrome OS devices.
To test:
- Logged in on a Chrome OS device and checked that
previously-pinned apps appear in the launcher and that
non-component extensions have icons and titles in their
context menus.
- Killed the Chrome process and checked that the launcher is
visible when it restarts.
- Ran Chrome and ash_shell on a Linux workstation and
checked that the launcher is present.
BUG=118129,118945
TEST=manual: see above
Review URL: https://chromiumcodereview.appspot.com/9733024
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@127841 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | ash/focus_cycler_unittest.cc | 4 | ||||
-rw-r--r-- | ash/launcher/launcher.cc | 3 | ||||
-rw-r--r-- | ash/launcher/launcher.h | 4 | ||||
-rw-r--r-- | ash/shell.cc | 28 | ||||
-rw-r--r-- | ash/shell.h | 9 | ||||
-rw-r--r-- | ash/shell/shell_main.cc | 10 | ||||
-rw-r--r-- | ash/shell_delegate.h | 4 | ||||
-rw-r--r-- | ash/test/test_shell_delegate.cc | 4 | ||||
-rw-r--r-- | ash/test/test_shell_delegate.h | 1 | ||||
-rw-r--r-- | ash/wm/shelf_layout_manager.cc | 62 | ||||
-rw-r--r-- | ash/wm/shelf_layout_manager.h | 5 | ||||
-rw-r--r-- | chrome/browser/ui/views/ash/chrome_shell_delegate.cc | 40 | ||||
-rw-r--r-- | chrome/browser/ui/views/ash/chrome_shell_delegate.h | 13 |
13 files changed, 139 insertions, 48 deletions
diff --git a/ash/focus_cycler_unittest.cc b/ash/focus_cycler_unittest.cc index 7380463..9bc23b9 100644 --- a/ash/focus_cycler_unittest.cc +++ b/ash/focus_cycler_unittest.cc @@ -60,7 +60,6 @@ TEST_F(FocusCyclerTest, CycleFocusForward) { ASSERT_TRUE(launcher); views::Widget* launcher_widget = launcher->widget(); ASSERT_TRUE(launcher_widget); - focus_cycler->AddWidget(launcher_widget); launcher->SetFocusCycler(focus_cycler.get()); // Create a single test window. @@ -103,7 +102,6 @@ TEST_F(FocusCyclerTest, CycleFocusBackward) { ASSERT_TRUE(launcher); views::Widget* launcher_widget = launcher->widget(); ASSERT_TRUE(launcher_widget); - focus_cycler->AddWidget(launcher_widget); launcher->SetFocusCycler(focus_cycler.get()); // Create a single test window. @@ -177,7 +175,6 @@ TEST_F(FocusCyclerLauncherTest, CycleFocusForwardInvisible) { ASSERT_TRUE(launcher); views::Widget* launcher_widget = launcher->widget(); ASSERT_TRUE(launcher_widget); - focus_cycler->AddWidget(launcher_widget); launcher->SetFocusCycler(focus_cycler.get()); // Create a single test window. @@ -216,7 +213,6 @@ TEST_F(FocusCyclerLauncherTest, CycleFocusBackwardInvisible) { ASSERT_TRUE(launcher); views::Widget* launcher_widget = launcher->widget(); ASSERT_TRUE(launcher_widget); - focus_cycler->AddWidget(launcher_widget); launcher->SetFocusCycler(focus_cycler.get()); // Create a single test window. diff --git a/ash/launcher/launcher.cc b/ash/launcher/launcher.cc index 3c1543f..9f4ba4b 100644 --- a/ash/launcher/launcher.cc +++ b/ash/launcher/launcher.cc @@ -71,8 +71,9 @@ Launcher::DelegateView::DelegateView() Launcher::DelegateView::~DelegateView() { } -void Launcher::SetFocusCycler(const internal::FocusCycler* focus_cycler) { +void Launcher::SetFocusCycler(internal::FocusCycler* focus_cycler) { delegate_view_->set_focus_cycler(focus_cycler); + focus_cycler->AddWidget(widget_.get()); } void Launcher::DelegateView::SetStatusWidth(int width) { diff --git a/ash/launcher/launcher.h b/ash/launcher/launcher.h index 6825771..368d943 100644 --- a/ash/launcher/launcher.h +++ b/ash/launcher/launcher.h @@ -37,8 +37,8 @@ class ASH_EXPORT Launcher { explicit Launcher(aura::Window* window_container); ~Launcher(); - // Sets the focus cycler. - void SetFocusCycler(const internal::FocusCycler* focus_cycler); + // Sets the focus cycler. Also adds the launcher to the cycle. + void SetFocusCycler(internal::FocusCycler* focus_cycler); // Sets the width of the status area. void SetStatusWidth(int width); diff --git a/ash/shell.cc b/ash/shell.cc index dea9786..fdc7b57 100644 --- a/ash/shell.cc +++ b/ash/shell.cc @@ -600,10 +600,6 @@ void Shell::Init() { if (!status_widget_) status_widget_ = internal::CreateStatusArea(tray_.get()); - aura::Window* default_container = - GetContainer(internal::kShellWindowId_DefaultContainer); - launcher_.reset(new Launcher(default_container)); - // This controller needs to be set before SetupManagedWindowMode. desktop_background_controller_.reset(new DesktopBackgroundController); @@ -616,8 +612,9 @@ void Shell::Init() { focus_cycler_.reset(new internal::FocusCycler()); focus_cycler_->AddWidget(status_widget_); - focus_cycler_->AddWidget(launcher_->widget()); - launcher_->SetFocusCycler(focus_cycler_.get()); + + if (!delegate_.get() || delegate_->CanCreateLauncher()) + CreateLauncher(); // Force a layout. root_window->layout_manager()->OnWindowResized(); @@ -713,6 +710,20 @@ void Shell::SetMonitorWorkAreaInsets(Window* contains, OnMonitorWorkAreaInsetsChanged()); } +void Shell::CreateLauncher() { + if (launcher_.get()) + return; + + aura::Window* default_container = + GetContainer(internal::kShellWindowId_DefaultContainer); + launcher_.reset(new Launcher(default_container)); + + launcher_->SetFocusCycler(focus_cycler_.get()); + shelf_->SetLauncherWidget(launcher_->widget()); + + launcher_->widget()->Show(); +} + void Shell::AddShellObserver(ShellObserver* observer) { observers_.AddObserver(observer); } @@ -741,7 +752,7 @@ void Shell::InitLayoutManagers() { DCHECK(status_widget_); internal::ShelfLayoutManager* shelf_layout_manager = - new internal::ShelfLayoutManager(launcher_->widget(), status_widget_); + new internal::ShelfLayoutManager(status_widget_); GetContainer(internal::kShellWindowId_LauncherContainer)-> SetLayoutManager(shelf_layout_manager); shelf_ = shelf_layout_manager; @@ -758,9 +769,6 @@ void Shell::InitLayoutManagers() { new internal::WorkspaceController(default_container)); workspace_controller_->workspace_manager()->set_shelf(shelf_layout_manager); - // Ensure launcher is visible. - launcher_->widget()->Show(); - // Create the desktop background image. desktop_background_controller_->SetDefaultDesktopBackgroundImage(); } diff --git a/ash/shell.h b/ash/shell.h index b5fc9cf..06a41d6 100644 --- a/ash/shell.h +++ b/ash/shell.h @@ -113,7 +113,7 @@ class ASH_EXPORT Shell : public aura::MonitorObserver { static void DeleteInstance(); - // Get the singleton RootWindow used by the Shell. + // Gets the singleton RootWindow used by the Shell. static aura::RootWindow* GetRootWindow(); internal::RootWindowLayoutManager* root_window_layout() const { @@ -145,7 +145,7 @@ class ASH_EXPORT Shell : public aura::MonitorObserver { views::NonClientFrameView* CreateDefaultNonClientFrameView( views::Widget* widget); - // Rotate focus through containers that can receive focus. + // Rotates focus through containers that can receive focus. void RotateFocus(Direction direction); // Sets the work area insets of the monitor that contains |window|, @@ -153,7 +153,10 @@ class ASH_EXPORT Shell : public aura::MonitorObserver { void SetMonitorWorkAreaInsets(aura::Window* window, const gfx::Insets& insets); - // Add/remove observer. + // Initializes |launcher_|. Does nothing if it's already initialized. + void CreateLauncher(); + + // Adds/removes observer. void AddShellObserver(ShellObserver* observer); void RemoveShellObserver(ShellObserver* observer); diff --git a/ash/shell/shell_main.cc b/ash/shell/shell_main.cc index 3ba1285..47d32e7 100644 --- a/ash/shell/shell_main.cc +++ b/ash/shell/shell_main.cc @@ -190,10 +190,14 @@ class ShellDelegateImpl : public ash::ShellDelegate { return NULL; } + virtual bool CanCreateLauncher() OVERRIDE { + return true; + } + #if defined(OS_CHROMEOS) - virtual void LockScreen() OVERRIDE { - ash::shell::CreateLockScreen(); - } + virtual void LockScreen() OVERRIDE { + ash::shell::CreateLockScreen(); + } #endif virtual void Exit() OVERRIDE { diff --git a/ash/shell_delegate.h b/ash/shell_delegate.h index 8e9076e..9744190 100644 --- a/ash/shell_delegate.h +++ b/ash/shell_delegate.h @@ -49,6 +49,10 @@ class ASH_EXPORT ShellDelegate { // Invoked to create a new status area. Can return NULL. virtual views::Widget* CreateStatusArea() = 0; + // Can we create the launcher yet? In some cases, we may need to defer it + // until e.g. a user has logged in and their profile has been loaded. + virtual bool CanCreateLauncher() = 0; + #if defined(OS_CHROMEOS) // Invoked when a user uses Ctrl-Shift-L to lock the screen. virtual void LockScreen() = 0; diff --git a/ash/test/test_shell_delegate.cc b/ash/test/test_shell_delegate.cc index 16caee5..bf446ca 100644 --- a/ash/test/test_shell_delegate.cc +++ b/ash/test/test_shell_delegate.cc @@ -25,6 +25,10 @@ views::Widget* TestShellDelegate::CreateStatusArea() { return NULL; } +bool TestShellDelegate::CanCreateLauncher() { + return true; +} + #if defined(OS_CHROMEOS) void TestShellDelegate::LockScreen() { } diff --git a/ash/test/test_shell_delegate.h b/ash/test/test_shell_delegate.h index 888b732..90fcbb6 100644 --- a/ash/test/test_shell_delegate.h +++ b/ash/test/test_shell_delegate.h @@ -19,6 +19,7 @@ class TestShellDelegate : public ShellDelegate { // Overridden from ShellDelegate: virtual views::Widget* CreateStatusArea() OVERRIDE; + virtual bool CanCreateLauncher() OVERRIDE; #if defined(OS_CHROMEOS) virtual void LockScreen() OVERRIDE; #endif diff --git a/ash/wm/shelf_layout_manager.cc b/ash/wm/shelf_layout_manager.cc index db32647..db1fe84 100644 --- a/ash/wm/shelf_layout_manager.cc +++ b/ash/wm/shelf_layout_manager.cc @@ -32,47 +32,60 @@ const int ShelfLayoutManager::kWorkspaceAreaBottomInset = 2; //////////////////////////////////////////////////////////////////////////////// // ShelfLayoutManager, public: -ShelfLayoutManager::ShelfLayoutManager(views::Widget* launcher, - views::Widget* status) +ShelfLayoutManager::ShelfLayoutManager(views::Widget* status) : in_layout_(false), visible_(true), - max_height_(-1), - launcher_(launcher), + max_height_(status->GetWindowScreenBounds().height()), + launcher_(NULL), status_(status) { - gfx::Rect launcher_bounds = launcher->GetWindowScreenBounds(); - gfx::Rect status_bounds = status->GetWindowScreenBounds(); - max_height_ = std::max(launcher_bounds.height(), status_bounds.height()); - root_window_ = launcher->GetNativeView()->GetRootWindow(); + root_window_ = status->GetNativeView()->GetRootWindow(); } ShelfLayoutManager::~ShelfLayoutManager() { } +void ShelfLayoutManager::SetLauncherWidget(views::Widget* launcher) { + if (launcher == launcher_) + return; + + launcher_ = launcher; + max_height_ = + std::max(max_height_, launcher->GetWindowScreenBounds().height()); + LayoutShelf(); + SetVisible(visible()); +} + void ShelfLayoutManager::LayoutShelf() { AutoReset<bool> auto_reset_in_layout(&in_layout_, true); StopAnimating(); TargetBounds target_bounds; float target_opacity = visible_ ? 1.0f : 0.0f; CalculateTargetBounds(visible_, &target_bounds); - GetLayer(launcher_)->SetOpacity(target_opacity); GetLayer(status_)->SetOpacity(target_opacity); - launcher_->SetBounds(target_bounds.launcher_bounds); status_->SetBounds(target_bounds.status_bounds); - Shell::GetInstance()->launcher()->SetStatusWidth( - target_bounds.status_bounds.width()); + + if (launcher_) { + GetLayer(launcher_)->SetOpacity(target_opacity); + launcher_->SetBounds(target_bounds.launcher_bounds); + ash::Shell::GetInstance()->launcher()->SetStatusWidth( + target_bounds.status_bounds.width()); + } + Shell::GetInstance()->SetMonitorWorkAreaInsets( Shell::GetRootWindow(), target_bounds.work_area_insets); } void ShelfLayoutManager::SetVisible(bool visible) { - ui::Layer* launcher_layer = GetLayer(launcher_); + ui::Layer* launcher_layer = launcher_ ? GetLayer(launcher_) : NULL; ui::Layer* status_layer = GetLayer(status_); // TODO(vollick): once visibility is animatable, use GetTargetVisibility. bool current_visibility = visible_ && - launcher_layer->GetTargetOpacity() > 0.0f && status_layer->GetTargetOpacity() > 0.0f; + if (launcher_layer) + current_visibility = + current_visibility && launcher_layer->GetTargetOpacity() > 0.0f; if (visible == current_visibility) return; // Nothing changed. @@ -84,18 +97,19 @@ void ShelfLayoutManager::SetVisible(bool visible) { float target_opacity = visible ? 1.0f : 0.0f; CalculateTargetBounds(visible, &target_bounds); - ui::ScopedLayerAnimationSettings launcher_animation_setter( - launcher_layer->GetAnimator()); ui::ScopedLayerAnimationSettings status_animation_setter( status_layer->GetAnimator()); - - launcher_animation_setter.AddObserver(this); status_animation_setter.AddObserver(this); - - launcher_layer->SetBounds(target_bounds.launcher_bounds); - launcher_layer->SetOpacity(target_opacity); status_layer->SetBounds(target_bounds.status_bounds); status_layer->SetOpacity(target_opacity); + + if (launcher_layer) { + ui::ScopedLayerAnimationSettings launcher_animation_setter( + launcher_layer->GetAnimator()); + launcher_animation_setter.AddObserver(this); + launcher_layer->SetBounds(target_bounds.launcher_bounds); + launcher_layer->SetOpacity(target_opacity); + } } //////////////////////////////////////////////////////////////////////////////// @@ -127,7 +141,8 @@ void ShelfLayoutManager::SetChildBounds(aura::Window* child, void ShelfLayoutManager::StopAnimating() { StopObservingImplicitAnimations(); - GetLayer(launcher_)->GetAnimator()->StopAnimating(); + if (launcher_) + GetLayer(launcher_)->GetAnimator()->StopAnimating(); GetLayer(status_)->GetAnimator()->StopAnimating(); } @@ -141,7 +156,8 @@ void ShelfLayoutManager::CalculateTargetBounds(bool visible, available_bounds.right() - status_bounds.width(), y + max_height_ - status_bounds.height(), status_bounds.width(), status_bounds.height()); - gfx::Rect launcher_bounds(launcher_->GetWindowScreenBounds()); + gfx::Rect launcher_bounds = + launcher_ ? launcher_->GetWindowScreenBounds() : gfx::Rect(); target_bounds->launcher_bounds = gfx::Rect( available_bounds.x(), y + (max_height_ - launcher_bounds.height()) / 2, available_bounds.width(), diff --git a/ash/wm/shelf_layout_manager.h b/ash/wm/shelf_layout_manager.h index b0a9b3c..e70d323 100644 --- a/ash/wm/shelf_layout_manager.h +++ b/ash/wm/shelf_layout_manager.h @@ -42,11 +42,14 @@ class ASH_EXPORT ShelfLayoutManager : public aura::LayoutManager, // the invisible parts of the launcher. static const int kWorkspaceAreaBottomInset; - ShelfLayoutManager(views::Widget* launcher, views::Widget* status); + explicit ShelfLayoutManager(views::Widget* status); virtual ~ShelfLayoutManager(); bool in_layout() const { return in_layout_; } + // The launcher is typically created after the layout manager. + void SetLauncherWidget(views::Widget* launcher); + // Stops any animations and sets the bounds of the launcher and status // widgets. void LayoutShelf(); diff --git a/chrome/browser/ui/views/ash/chrome_shell_delegate.cc b/chrome/browser/ui/views/ash/chrome_shell_delegate.cc index 7982438..bbf82ae 100644 --- a/chrome/browser/ui/views/ash/chrome_shell_delegate.cc +++ b/chrome/browser/ui/views/ash/chrome_shell_delegate.cc @@ -15,12 +15,16 @@ #include "chrome/browser/ui/views/ash/launcher/chrome_launcher_delegate.h" #include "chrome/browser/ui/views/ash/status_area_host_aura.h" #include "chrome/browser/ui/views/frame/browser_view.h" +#include "chrome/common/chrome_notification_types.h" #include "chrome/common/chrome_switches.h" +#include "content/public/browser/notification_service.h" #include "ui/aura/window.h" #if defined(OS_CHROMEOS) +#include "base/chromeos/chromeos_version.h" #include "chrome/browser/chromeos/dbus/dbus_thread_manager.h" #include "chrome/browser/chromeos/dbus/power_manager_client.h" +#include "chrome/browser/chromeos/login/user_manager.h" #include "chrome/browser/chromeos/system/ash_system_tray_delegate.h" #endif namespace { @@ -45,6 +49,12 @@ ChromeShellDelegate* ChromeShellDelegate::instance_ = NULL; ChromeShellDelegate::ChromeShellDelegate() { instance_ = this; +#if defined(OS_CHROMEOS) + registrar_.Add( + this, + chrome::NOTIFICATION_SESSION_STARTED, + content::NotificationService::AllSources()); +#endif } ChromeShellDelegate::~ChromeShellDelegate() { @@ -63,6 +73,19 @@ views::Widget* ChromeShellDelegate::CreateStatusArea() { return status_area_widget; } +bool ChromeShellDelegate::CanCreateLauncher() { +#if defined(OS_CHROMEOS) + // When running a Chrome OS build outside of a device (i.e. on a developer's + // workstation), pretend like we're always logged in. + if (!base::chromeos::IsRunningOnChromeOS()) + return true; + + return chromeos::UserManager::Get()->IsUserLoggedIn(); +#else + return true; +#endif +} + #if defined(OS_CHROMEOS) void ChromeShellDelegate::LockScreen() { if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kGuestSession)) { @@ -109,3 +132,20 @@ ash::SystemTrayDelegate* ChromeShellDelegate::CreateSystemTrayDelegate( return NULL; #endif } + +void ChromeShellDelegate::Observe(int type, + const content::NotificationSource& source, + const content::NotificationDetails& details) { +#if defined(OS_CHROMEOS) + switch (type) { + case chrome::NOTIFICATION_SESSION_STARTED: + ash::Shell::GetInstance()->CreateLauncher(); + break; + default: + NOTREACHED() << "Unexpected notification " << type; + } +#else + // MSVC++ warns about switch statements without any cases. + NOTREACHED() << "Unexpected notification " << type; +#endif +} diff --git a/chrome/browser/ui/views/ash/chrome_shell_delegate.h b/chrome/browser/ui/views/ash/chrome_shell_delegate.h index 125b575..5c30d88 100644 --- a/chrome/browser/ui/views/ash/chrome_shell_delegate.h +++ b/chrome/browser/ui/views/ash/chrome_shell_delegate.h @@ -11,6 +11,8 @@ #include "base/basictypes.h" #include "base/compiler_specific.h" #include "base/memory/scoped_ptr.h" +#include "content/public/browser/notification_observer.h" +#include "content/public/browser/notification_registrar.h" class StatusAreaHostAura; class StatusAreaView; @@ -19,7 +21,8 @@ namespace views { class View; } -class ChromeShellDelegate : public ash::ShellDelegate { +class ChromeShellDelegate : public ash::ShellDelegate, + public content::NotificationObserver { public: ChromeShellDelegate(); virtual ~ChromeShellDelegate(); @@ -34,6 +37,7 @@ class ChromeShellDelegate : public ash::ShellDelegate { // ash::ShellDelegate overrides; virtual views::Widget* CreateStatusArea() OVERRIDE; + virtual bool CanCreateLauncher() OVERRIDE; #if defined(OS_CHROMEOS) virtual void LockScreen() OVERRIDE; #endif @@ -48,9 +52,16 @@ class ChromeShellDelegate : public ash::ShellDelegate { virtual ash::SystemTrayDelegate* CreateSystemTrayDelegate( ash::SystemTray* tray) OVERRIDE; + // content::NotificationObserver override: + virtual void Observe(int type, + const content::NotificationSource& source, + const content::NotificationDetails& details) OVERRIDE; + private: static ChromeShellDelegate* instance_; + content::NotificationRegistrar registrar_; + scoped_ptr<StatusAreaHostAura> status_area_host_; DISALLOW_COPY_AND_ASSIGN(ChromeShellDelegate); |