1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "athena/system/public/system_ui.h" 6 7 #include "athena/screen/public/screen_manager.h" 8 #include "athena/system/background_controller.h" 9 #include "athena/system/orientation_controller.h" 10 #include "athena/system/power_button_controller.h" 11 #include "athena/system/status_icon_container_view.h" 12 #include "athena/system/time_view.h" 13 #include "athena/util/container_priorities.h" 14 #include "athena/util/fill_layout_manager.h" 15 #include "base/logging.h" 16 #include "base/memory/ref_counted.h" 17 #include "base/memory/scoped_ptr.h" 18 #include "ui/aura/window.h" 19 #include "ui/views/view.h" 20 21 namespace athena { 22 namespace { 23 24 SystemUI* instance = NULL; 25 26 // View which positions the TimeView on the left and the StatusIconView on the 27 // right. 28 class SystemInfoView : public views::View { 29 public: 30 SystemInfoView(SystemUI::ColorScheme color_scheme, 31 aura::Window* system_modal_container) 32 : time_view_(new TimeView(color_scheme)), 33 status_icon_view_( 34 new StatusIconContainerView(color_scheme, system_modal_container)) { 35 AddChildView(time_view_); 36 AddChildView(status_icon_view_); 37 } 38 39 virtual ~SystemInfoView() { 40 } 41 42 // views::View: 43 virtual gfx::Size GetPreferredSize() const OVERRIDE { 44 // The view should be as wide as its parent view. 45 return gfx::Size(0, 46 std::max(time_view_->GetPreferredSize().height(), 47 status_icon_view_->GetPreferredSize().height())); 48 } 49 50 virtual void Layout() OVERRIDE { 51 time_view_->SetBoundsRect(gfx::Rect(time_view_->GetPreferredSize())); 52 gfx::Size status_icon_preferred_size = 53 status_icon_view_->GetPreferredSize(); 54 status_icon_view_->SetBoundsRect( 55 gfx::Rect(width() - status_icon_preferred_size.width(), 56 0, 57 status_icon_preferred_size.width(), 58 status_icon_preferred_size.height())); 59 } 60 61 virtual void ChildPreferredSizeChanged(views::View* child) OVERRIDE { 62 // Relayout to take into account changes in |status_icon_view_|'s width. 63 // Assume that |time_view_|'s and |status_icon_view_|'s preferred height 64 // does not change. 65 Layout(); 66 } 67 68 private: 69 views::View* time_view_; 70 views::View* status_icon_view_; 71 72 DISALLOW_COPY_AND_ASSIGN(SystemInfoView); 73 }; 74 75 class SystemUIImpl : public SystemUI { 76 public: 77 SystemUIImpl(scoped_refptr<base::TaskRunner> blocking_task_runner) 78 : orientation_controller_(new OrientationController()), 79 background_container_(NULL), 80 system_modal_container_(NULL) { 81 orientation_controller_->InitWith(blocking_task_runner); 82 } 83 84 virtual ~SystemUIImpl() { 85 // Stops file watching now if exists. Waiting until message loop shutdon 86 // leads to FilePathWatcher crash. 87 orientation_controller_->Shutdown(); 88 } 89 90 void Init() { 91 ScreenManager* screen_manager = ScreenManager::Get(); 92 background_container_ = screen_manager->CreateContainer( 93 ScreenManager::ContainerParams("AthenaBackground", CP_BACKGROUND)); 94 background_container_->SetLayoutManager( 95 new FillLayoutManager(background_container_)); 96 ScreenManager::ContainerParams system_modal_params( 97 "AthenaSystemModalContainer", CP_SYSTEM_MODAL); 98 system_modal_params.can_activate_children = true; 99 system_modal_container_ = 100 screen_manager->CreateContainer(system_modal_params); 101 login_screen_system_modal_container_ = screen_manager->CreateContainer( 102 ScreenManager::ContainerParams("AthenaLoginScreenSystemModalContainer", 103 CP_LOGIN_SCREEN_SYSTEM_MODAL)); 104 105 // Use |login_screen_system_modal_container_| for the power button's dialog 106 // because it needs to show over the login screen. 107 // TODO(pkotwicz): Pick the most appropriate container based on whether the 108 // user has logged in. 109 power_button_controller_.reset( 110 new PowerButtonController(login_screen_system_modal_container_)); 111 background_controller_.reset( 112 new BackgroundController(background_container_)); 113 } 114 115 virtual void SetBackgroundImage(const gfx::ImageSkia& image) OVERRIDE { 116 background_controller_->SetImage(image); 117 } 118 119 virtual views::View* CreateSystemInfoView(ColorScheme color_scheme) OVERRIDE { 120 return new SystemInfoView(color_scheme, system_modal_container_); 121 } 122 123 private: 124 scoped_ptr<OrientationController> orientation_controller_; 125 scoped_ptr<PowerButtonController> power_button_controller_; 126 scoped_ptr<BackgroundController> background_controller_; 127 128 // The parent container for the background. 129 aura::Window* background_container_; 130 131 // The parent container used by system modal dialogs. 132 aura::Window* system_modal_container_; 133 134 // The parent container used by system modal dialogs when the login screen is 135 // visible. 136 aura::Window* login_screen_system_modal_container_; 137 138 DISALLOW_COPY_AND_ASSIGN(SystemUIImpl); 139 }; 140 141 } // namespace 142 143 // static 144 SystemUI* SystemUI::Create( 145 scoped_refptr<base::TaskRunner> blocking_task_runner) { 146 SystemUIImpl* system_ui = new SystemUIImpl(blocking_task_runner); 147 instance = system_ui; 148 system_ui->Init(); 149 return instance; 150 } 151 152 // static 153 SystemUI* SystemUI::Get() { 154 DCHECK(instance); 155 return instance; 156 } 157 158 // static 159 void SystemUI::Shutdown() { 160 CHECK(instance); 161 delete instance; 162 instance = NULL; 163 } 164 165 } // namespace athena 166