| 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 |