OLD | NEW |
| (Empty) |
1 // Copyright 2010 Google Inc. | |
2 // | |
3 // Licensed under the Apache License, Version 2.0 (the "License"); | |
4 // you may not use this file except in compliance with the License. | |
5 // You may obtain a copy of the License at | |
6 // | |
7 // http://www.apache.org/licenses/LICENSE-2.0 | |
8 // | |
9 // Unless required by applicable law or agreed to in writing, software | |
10 // distributed under the License is distributed on an "AS IS" BASIS, | |
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
12 // See the License for the specific language governing permissions and | |
13 // limitations under the License. | |
14 // ======================================================================== | |
15 | |
16 #include "omaha/ui/splash_screen.h" | |
17 #include "base/basictypes.h" | |
18 #include "omaha/base/app_util.h" | |
19 #include "omaha/base/constants.h" | |
20 #include "omaha/base/const_object_names.h" | |
21 #include "omaha/base/debug.h" | |
22 #include "omaha/base/error.h" | |
23 #include "omaha/base/logging.h" | |
24 #include "omaha/base/smart_handle.h" | |
25 #include "omaha/base/utils.h" | |
26 #include "omaha/base/window_utils.h" | |
27 #include "omaha/client/client_utils.h" | |
28 #include "omaha/client/resource.h" | |
29 #include "omaha/common/lang.h" | |
30 #include "omaha/google_update/resource.h" // For the IDI_APP | |
31 #include "omaha/ui/scoped_gdi.h" | |
32 | |
33 namespace { | |
34 | |
35 const int kClosingTimerID = 1; | |
36 // Frequency that the window changes alpah blending value during fading stage. | |
37 const int kTimerInterval = 100; | |
38 | |
39 // Alpha blending values for the fading effect. | |
40 const int kDefaultAlphaScale = 100; | |
41 const int kAlphaScales[] = { 0, 30, 47, 62, 75, 85, 93, kDefaultAlphaScale }; | |
42 | |
43 uint8 AlphaScaleToAlphaValue(int alpha_scale) { | |
44 ASSERT1(alpha_scale >= 0 && alpha_scale <= 100); | |
45 return static_cast<uint8>(alpha_scale * 255 / 100); | |
46 } | |
47 | |
48 } // namespace | |
49 | |
50 namespace omaha { | |
51 | |
52 SplashScreen::SplashScreen(const CString& bundle_name) | |
53 : IDD(IDD_PROGRESS), | |
54 alpha_index_(0), | |
55 timer_created_(false) { | |
56 CORE_LOG(L3, (_T("[SplashScreen::SplashScreen]"))); | |
57 caption_ = client_utils::GetInstallerDisplayName(bundle_name); | |
58 text_.FormatMessage(IDS_SPLASH_SCREEN_MESSAGE, caption_); | |
59 | |
60 SwitchToState(STATE_CREATED); | |
61 } | |
62 | |
63 SplashScreen::~SplashScreen() { | |
64 CORE_LOG(L3, (_T("[SplashScreen::~SplashScreen]"))); | |
65 | |
66 const int kWaitTimeoutInMillisecond = 60000; | |
67 | |
68 // Before the object goes out of scope, waits the thread to exit to avoid | |
69 // it accessing the object after that. | |
70 if (thread_.Running() && !thread_.WaitTillExit(kWaitTimeoutInMillisecond)) { | |
71 CORE_LOG(LW, (_T("[SplashScreen: thread failed to exit gracefully]"))); | |
72 return; | |
73 } | |
74 | |
75 ASSERT1(state_ == STATE_CREATED || state_ == STATE_CLOSED); | |
76 } | |
77 | |
78 void SplashScreen::Show() { | |
79 AutoSync get_lock(lock_); | |
80 | |
81 if (state_ == STATE_CREATED) { | |
82 thread_.Start(this); | |
83 } else { | |
84 ASSERT1(false); | |
85 } | |
86 } | |
87 | |
88 void SplashScreen::Dismiss() { | |
89 AutoSync get_lock(lock_); | |
90 | |
91 switch (state_) { | |
92 case STATE_CREATED: | |
93 SwitchToState(STATE_CLOSED); | |
94 break; | |
95 | |
96 case STATE_SHOW_NORMAL: | |
97 SwitchToState(STATE_FADING); | |
98 break; | |
99 | |
100 case STATE_CLOSED: | |
101 case STATE_FADING: | |
102 case STATE_INITIALIZED: | |
103 break; | |
104 | |
105 default: | |
106 ASSERT1(false); | |
107 break; | |
108 } | |
109 } | |
110 | |
111 HRESULT SplashScreen::Initialize() { | |
112 CORE_LOG(L3, (_T("[SplashScreen::Initialize]"))); | |
113 | |
114 ASSERT1(!IsWindow()); | |
115 ASSERT1(state_ == STATE_CREATED); | |
116 | |
117 if (!Create(NULL)) { | |
118 return GOOPDATE_E_UI_INTERNAL_ERROR; | |
119 } | |
120 | |
121 VERIFY1(SetWindowText(caption_)); | |
122 | |
123 EnableSystemButtons(false); | |
124 GetDlgItem(IDC_IMAGE).ShowWindow(SW_HIDE); | |
125 | |
126 CWindow text_wnd = GetDlgItem(IDC_INSTALLER_STATE_TEXT); | |
127 text_wnd.ShowWindow(SW_SHOWNORMAL); | |
128 text_wnd.SetWindowText(text_); | |
129 | |
130 InitProgressBar(); | |
131 | |
132 ::SetLayeredWindowAttributes( | |
133 m_hWnd, | |
134 0, | |
135 AlphaScaleToAlphaValue(kDefaultAlphaScale), | |
136 LWA_ALPHA); | |
137 | |
138 VERIFY1(CenterWindow(NULL)); | |
139 HRESULT hr = WindowUtils::SetWindowIcon(m_hWnd, IDI_APP, address(hicon_)); | |
140 if (FAILED(hr)) { | |
141 CORE_LOG(LW, (_T("[SetWindowIcon failed][0x%08x]"), hr)); | |
142 } | |
143 SwitchToState(STATE_INITIALIZED); | |
144 return S_OK; | |
145 } | |
146 | |
147 void SplashScreen::EnableSystemButtons(bool enable) { | |
148 const LONG kSysStyleMask = WS_MINIMIZEBOX | WS_SYSMENU | WS_MAXIMIZEBOX; | |
149 | |
150 if (enable) { | |
151 SetWindowLong(GWL_STYLE, GetWindowLong(GWL_STYLE) | kSysStyleMask); | |
152 } else { | |
153 SetWindowLong(GWL_STYLE, GetWindowLong(GWL_STYLE) & ~kSysStyleMask); | |
154 } | |
155 } | |
156 | |
157 void SplashScreen::InitProgressBar() { | |
158 const LONG kStyle = WS_CHILD | WS_VISIBLE | PBS_MARQUEE | PBS_SMOOTH; | |
159 | |
160 CWindow progress_bar = GetDlgItem(IDC_PROGRESS); | |
161 LONG style = progress_bar.GetWindowLong(GWL_STYLE) | kStyle; | |
162 progress_bar.SetWindowLong(GWL_STYLE, style); | |
163 progress_bar.SendMessage(PBM_SETMARQUEE, TRUE, 60); | |
164 } | |
165 | |
166 LRESULT SplashScreen::OnTimer(UINT message, | |
167 WPARAM wparam, | |
168 LPARAM lparam, | |
169 BOOL& handled) { | |
170 UNREFERENCED_PARAMETER(message); | |
171 UNREFERENCED_PARAMETER(wparam); | |
172 UNREFERENCED_PARAMETER(lparam); | |
173 | |
174 ASSERT1(state_ == STATE_FADING); | |
175 ASSERT1(alpha_index_ > 0); | |
176 if (--alpha_index_) { | |
177 ::SetLayeredWindowAttributes( | |
178 m_hWnd, | |
179 0, | |
180 AlphaScaleToAlphaValue(kAlphaScales[alpha_index_]), | |
181 LWA_ALPHA); | |
182 } else { | |
183 Close(); | |
184 } | |
185 | |
186 handled = TRUE; | |
187 return 0; | |
188 } | |
189 | |
190 LRESULT SplashScreen::OnClose(UINT message, | |
191 WPARAM wparam, | |
192 LPARAM lparam, | |
193 BOOL& handled) { | |
194 UNREFERENCED_PARAMETER(message); | |
195 UNREFERENCED_PARAMETER(wparam); | |
196 UNREFERENCED_PARAMETER(lparam); | |
197 | |
198 DestroyWindow(); | |
199 handled = TRUE; | |
200 return 0; | |
201 } | |
202 | |
203 LRESULT SplashScreen::OnDestroy(UINT message, | |
204 WPARAM wparam, | |
205 LPARAM lparam, | |
206 BOOL& handled) { | |
207 UNREFERENCED_PARAMETER(message); | |
208 UNREFERENCED_PARAMETER(wparam); | |
209 UNREFERENCED_PARAMETER(lparam); | |
210 | |
211 if (timer_created_) { | |
212 ASSERT1(IsWindow()); | |
213 KillTimer(kClosingTimerID); | |
214 } | |
215 | |
216 ::PostQuitMessage(0); | |
217 | |
218 handled = TRUE; | |
219 return 0; | |
220 } | |
221 | |
222 void SplashScreen::SwitchToState(WindowState new_state) { | |
223 AutoSync get_lock(lock_); | |
224 | |
225 state_ = new_state; | |
226 switch (new_state) { | |
227 case STATE_CREATED: | |
228 case STATE_INITIALIZED: | |
229 break; | |
230 case STATE_SHOW_NORMAL: | |
231 alpha_index_ = arraysize(kAlphaScales) - 1; | |
232 break; | |
233 case STATE_FADING: | |
234 ASSERT1(IsWindow()); | |
235 timer_created_ = (SetTimer(kClosingTimerID, kTimerInterval, NULL) != 0); | |
236 if (!timer_created_) { | |
237 CORE_LOG(LW, | |
238 (_T("[SetTimer failed, closing window directly.][0x%08x]"), | |
239 HRESULTFromLastError())); | |
240 Close(); | |
241 } | |
242 break; | |
243 case STATE_CLOSED: | |
244 break; | |
245 default: | |
246 ASSERT1(false); | |
247 break; | |
248 } | |
249 } | |
250 | |
251 void SplashScreen::Run() { | |
252 { | |
253 AutoSync get_lock(lock_); | |
254 | |
255 if (state_ != STATE_CREATED) { | |
256 return; | |
257 } | |
258 | |
259 // Initialize() has to be called in this thread so that it is the owner of | |
260 // the window and window messages can be correctly routed by the message | |
261 // loop. | |
262 if (FAILED(Initialize())) { | |
263 return; | |
264 } | |
265 | |
266 ASSERT1(IsWindow()); | |
267 ShowWindow(SW_SHOWNORMAL); | |
268 SwitchToState(STATE_SHOW_NORMAL); | |
269 } | |
270 | |
271 CMessageLoop message_loop; | |
272 message_loop.Run(); | |
273 | |
274 SwitchToState(STATE_CLOSED); | |
275 } | |
276 | |
277 void SplashScreen::Close() { | |
278 AutoSync get_lock(lock_); | |
279 | |
280 if (state_ != STATE_CLOSED && IsWindow()) { | |
281 PostMessage(WM_CLOSE, 0, 0); | |
282 } | |
283 } | |
284 | |
285 } // namespace omaha | |
OLD | NEW |