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
ScreenManager(ScreenFactory * factory,OobeDisplay * oobe_display,ScreenFlow * initial_flow)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
~ScreenManager()30 ScreenManager::~ScreenManager() {
31 }
32
WarmupScreen(const std::string & id,ScreenContext * context)33 void ScreenManager::WarmupScreen(const std::string& id,
34 ScreenContext* context) {
35
36 }
37
ShowScreen(const std::string & id)38 void ScreenManager::ShowScreen(const std::string& id) {
39 ShowScreenImpl(id, new ScreenContext(), false);
40 }
41
ShowScreenWithParameters(const std::string & id,ScreenContext * context)42 void ScreenManager::ShowScreenWithParameters(const std::string& id,
43 ScreenContext* context) {
44 ShowScreenImpl(id, context, false);
45 }
46
PopupScreen(const std::string & id)47 void ScreenManager::PopupScreen(const std::string& id) {
48 ShowScreenImpl(id, new ScreenContext(), true);
49 }
50
PopupScreenWithParameters(const std::string & id,ScreenContext * context)51 void ScreenManager::PopupScreenWithParameters(const std::string& id,
52 ScreenContext* context) {
53 ShowScreenImpl(id, context, true);
54 }
55
HidePopupScreen(const std::string & screen_id)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
GetCurrentScreenId()74 std::string ScreenManager::GetCurrentScreenId() {
75 DCHECK(!screen_stack_.empty());
76 return screen_stack_.top();
77 }
78
SetScreenFlow(ScreenFlow * flow)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
ShowScreenImpl(const std::string & id,ScreenContext * context,bool popup)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
TransitionScreen(const std::string & from_id,const std::string & to_id)115 void ScreenManager::TransitionScreen(const std::string& from_id,
116 const std::string& to_id) {
117 }
118
TearDownTopmostScreen()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
OnDisplayIsReady()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
GetTopmostScreen()144 BaseScreen* ScreenManager::GetTopmostScreen() {
145 DCHECK(!screen_stack_.empty());
146 return FindOrCreateScreen(screen_stack_.top());
147 }
148
FindOrCreateScreen(const std::string & id)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
OnButtonPressed(const std::string & screen_name,const std::string & button_id)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
OnContextChanged(const std::string & screen_name,const base::DictionaryValue * diff)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