1 // Copyright (c) 2011 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 "chrome/browser/chromeos/login/screens/screen_manager.h" 6 7 #include "base/bind.h" 8 #include "base/logging.h" 9 #include "chrome/browser/chromeos/login/oobe_display.h" 10 #include "chrome/browser/chromeos/login/screens/base_screen.h" 11 #include "chrome/browser/chromeos/login/screens/screen_factory.h" 12 #include "chrome/browser/chromeos/login/screens/screen_flow.h" 13 14 namespace chromeos { 15 16 ScreenManager::ScreenManager(ScreenFactory* factory, 17 OobeDisplay* oobe_display, 18 ScreenFlow* initial_flow) 19 : factory_(factory), 20 display_(oobe_display), 21 flow_(initial_flow), 22 weak_factory_(this) { 23 js_is_ready_ = display_->IsJSReady( 24 base::Bind(&ScreenManager::OnDisplayIsReady, weak_factory_.GetWeakPtr())); 25 26 // TODO({antrim|ygorshenin}@): register ScreenManager as delegate in 27 // ScreenManagerHandler instance. 28 } 29 30 ScreenManager::~ScreenManager() { 31 } 32 33 void ScreenManager::WarmupScreen(const std::string& id, 34 ScreenContext* context) { 35 36 } 37 38 void ScreenManager::ShowScreen(const std::string& id) { 39 ShowScreenImpl(id, new ScreenContext(), false); 40 } 41 42 void ScreenManager::ShowScreenWithParameters(const std::string& id, 43 ScreenContext* context) { 44 ShowScreenImpl(id, context, false); 45 } 46 47 void ScreenManager::PopupScreen(const std::string& id) { 48 ShowScreenImpl(id, new ScreenContext(), true); 49 } 50 51 void ScreenManager::PopupScreenWithParameters(const std::string& id, 52 ScreenContext* context) { 53 ShowScreenImpl(id, context, true); 54 } 55 56 void ScreenManager::HidePopupScreen(const std::string& screen_id) { 57 DCHECK(!screen_stack_.empty()); 58 DCHECK_EQ(screen_stack_.top(), screen_id); 59 60 // TODO(antrim): check that id really exist in stack. 61 std::string previous_screen = GetCurrentScreenId(); 62 GetTopmostScreen()->OnHide(); 63 TearDownTopmostScreen(); 64 screen_stack_.pop(); 65 66 std::string screen_below; 67 if (!screen_stack_.empty()) { 68 screen_below = GetCurrentScreenId(); 69 GetTopmostScreen()->OnShow(); 70 } 71 TransitionScreen(previous_screen, screen_below); 72 } 73 74 std::string ScreenManager::GetCurrentScreenId() { 75 DCHECK(!screen_stack_.empty()); 76 return screen_stack_.top(); 77 } 78 79 void ScreenManager::SetScreenFlow(ScreenFlow* flow) { 80 if (flow) 81 flow->set_screen_manager(this); 82 // TODO(antrim): delayed reset. 83 flow_.reset(flow); 84 } 85 86 void ScreenManager::ShowScreenImpl(const std::string& id, 87 ScreenContext* context, 88 bool popup) { 89 if (!js_is_ready_) { 90 DCHECK(!start_screen_params_.get()); 91 start_screen_params_.reset(context); 92 start_screen_popup_ = popup; 93 start_screen_ = id; 94 return; 95 } 96 DCHECK(popup || screen_stack_.size() <= 1); 97 BaseScreen* screen = FindOrCreateScreen(id); 98 screen->SetContext(context); 99 screen->Initialize(context); 100 101 std::string previous_screen; 102 if (!screen_stack_.empty()) { 103 previous_screen = GetCurrentScreenId(); 104 GetTopmostScreen()->OnHide(); 105 if (!popup) 106 TearDownTopmostScreen(); 107 } 108 109 DCHECK(popup || screen_stack_.empty()); 110 screen_stack_.push(id); 111 screen->OnShow(); 112 TransitionScreen(previous_screen, id); 113 } 114 115 void ScreenManager::TransitionScreen(const std::string& from_id, 116 const std::string& to_id) { 117 } 118 119 void ScreenManager::TearDownTopmostScreen() { 120 DCHECK(!screen_stack_.empty()); 121 std::string screen_id = screen_stack_.top(); 122 123 ScreenMap::iterator i = existing_screens_.find(screen_id); 124 125 if (i == existing_screens_.end()) { 126 NOTREACHED(); 127 return; 128 } 129 BaseScreen* screen = i->second.get(); 130 if (!screen->IsPermanent()) { 131 screen->OnClose(); 132 existing_screens_.erase(i); 133 } 134 } 135 136 void ScreenManager::OnDisplayIsReady() { 137 js_is_ready_ = true; 138 ShowScreenImpl( 139 start_screen_, 140 start_screen_params_.release(), 141 start_screen_popup_); 142 } 143 144 BaseScreen* ScreenManager::GetTopmostScreen() { 145 DCHECK(!screen_stack_.empty()); 146 return FindOrCreateScreen(screen_stack_.top()); 147 } 148 149 BaseScreen* ScreenManager::FindOrCreateScreen(const std::string& id) { 150 ScreenMap::iterator i = existing_screens_.find(id); 151 if (i != existing_screens_.end()) 152 return i->second.get(); 153 BaseScreen* result = factory_->CreateScreen(id); 154 existing_screens_[id] = linked_ptr<BaseScreen>(result); 155 return result; 156 } 157 158 void ScreenManager::OnButtonPressed(const std::string& screen_name, 159 const std::string& button_id) { 160 CallOnScreen<const std::string&>(screen_name, 161 &BaseScreen::OnButtonPressed, 162 button_id); 163 } 164 165 void ScreenManager::OnContextChanged(const std::string& screen_name, 166 const base::DictionaryValue* diff) { 167 CallOnScreen<const base::DictionaryValue*>(screen_name, 168 &BaseScreen::OnContextChanged, 169 diff); 170 } 171 172 } // namespace chromeos 173