| OLD | NEW |
| (Empty) |
| 1 // Copyright 2009-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/goopdate/app.h" | |
| 17 #include "omaha/base/error.h" | |
| 18 #include "omaha/base/debug.h" | |
| 19 #include "omaha/base/logging.h" | |
| 20 #include "omaha/base/safe_format.h" | |
| 21 #include "omaha/base/scoped_ptr_address.h" | |
| 22 #include "omaha/base/synchronized.h" | |
| 23 #include "omaha/base/time.h" | |
| 24 #include "omaha/common/config_manager.h" | |
| 25 #include "omaha/common/experiment_labels.h" | |
| 26 #include "omaha/goopdate/app_manager.h" | |
| 27 #include "omaha/goopdate/app_state.h" | |
| 28 #include "omaha/goopdate/app_state_init.h" | |
| 29 #include "omaha/goopdate/current_state.h" | |
| 30 #include "omaha/goopdate/model.h" | |
| 31 #include "omaha/goopdate/server_resource.h" | |
| 32 #include "omaha/goopdate/string_formatter.h" | |
| 33 | |
| 34 namespace omaha { | |
| 35 | |
| 36 App::App(const GUID& app_guid, bool is_update, AppBundle* app_bundle) | |
| 37 : ModelObject(app_bundle->model()), | |
| 38 app_bundle_(app_bundle), | |
| 39 is_update_(is_update), | |
| 40 has_update_available_(false), | |
| 41 app_guid_(app_guid), | |
| 42 iid_(GUID_NULL), | |
| 43 install_time_diff_sec_(0), | |
| 44 is_eula_accepted_(TRISTATE_NONE), // Cannot ping until set true. | |
| 45 browser_type_(BROWSER_UNKNOWN), | |
| 46 days_since_last_active_ping_(0), | |
| 47 days_since_last_roll_call_(0), | |
| 48 usage_stats_enable_(TRISTATE_NONE), | |
| 49 did_run_(ACTIVE_UNKNOWN), | |
| 50 is_canceled_(false), | |
| 51 completion_result_(PingEvent::EVENT_RESULT_SUCCESS), | |
| 52 installer_result_code_(0), | |
| 53 installer_result_extra_code1_(0), | |
| 54 post_install_action_(POST_INSTALL_ACTION_DEFAULT), | |
| 55 previous_total_download_bytes_(0), | |
| 56 download_start_time_ms_(0), | |
| 57 download_complete_time_ms_(0), | |
| 58 num_bytes_downloaded_(0) { | |
| 59 ASSERT1(!::IsEqualGUID(GUID_NULL, app_guid_)); | |
| 60 | |
| 61 current_version_.reset(new AppVersion(this)); | |
| 62 next_version_.reset(new AppVersion(this)); | |
| 63 | |
| 64 // TODO(omaha): set the working_version_ correctly to indicate which | |
| 65 // version of the app is modified: current version for components and | |
| 66 // next version for install/updates. The code do not support components yet | |
| 67 // and the working version in set to next always. | |
| 68 working_version_ = next_version_.get(); | |
| 69 app_state_.reset(new fsm::AppStateInit); | |
| 70 } | |
| 71 | |
| 72 // Destruction of App objects happens within the scope of their parent, | |
| 73 // which controls the locking. | |
| 74 App::~App() { | |
| 75 ASSERT1(model()->IsLockedByCaller()); | |
| 76 working_version_ = NULL; | |
| 77 app_bundle_ = NULL; | |
| 78 } | |
| 79 | |
| 80 STDMETHODIMP App::get_appId(BSTR* app_id) { | |
| 81 __mutexScope(model()->lock()); | |
| 82 ASSERT1(app_id); | |
| 83 *app_id = GuidToString(app_guid_).AllocSysString(); | |
| 84 return S_OK; | |
| 85 } | |
| 86 | |
| 87 STDMETHODIMP App::get_language(BSTR* language) { | |
| 88 __mutexScope(model()->lock()); | |
| 89 ASSERT1(language); | |
| 90 *language = language_.AllocSysString(); | |
| 91 return S_OK; | |
| 92 } | |
| 93 | |
| 94 STDMETHODIMP App::put_language(BSTR language) { | |
| 95 __mutexScope(model()->lock()); | |
| 96 language_ = language; | |
| 97 return S_OK; | |
| 98 } | |
| 99 | |
| 100 STDMETHODIMP App::get_ap(BSTR* ap) { | |
| 101 __mutexScope(model()->lock()); | |
| 102 ASSERT1(ap); | |
| 103 *ap = ap_.AllocSysString(); | |
| 104 return S_OK; | |
| 105 } | |
| 106 | |
| 107 STDMETHODIMP App::put_ap(BSTR ap) { | |
| 108 __mutexScope(model()->lock()); | |
| 109 ap_ = ap; | |
| 110 return S_OK; | |
| 111 } | |
| 112 | |
| 113 STDMETHODIMP App::get_pv(BSTR* pv) { | |
| 114 __mutexScope(model()->lock()); | |
| 115 ASSERT1(pv); | |
| 116 *pv = pv_.AllocSysString(); | |
| 117 return S_OK; | |
| 118 } | |
| 119 | |
| 120 STDMETHODIMP App::put_pv(BSTR pv) { | |
| 121 __mutexScope(model()->lock()); | |
| 122 pv_ = pv; | |
| 123 return S_OK; | |
| 124 } | |
| 125 | |
| 126 STDMETHODIMP App::get_ttToken(BSTR* tt_token) { | |
| 127 __mutexScope(model()->lock()); | |
| 128 ASSERT1(tt_token); | |
| 129 *tt_token = tt_token_.AllocSysString(); | |
| 130 return S_OK; | |
| 131 } | |
| 132 | |
| 133 STDMETHODIMP App::put_ttToken(BSTR tt_token) { | |
| 134 __mutexScope(model()->lock()); | |
| 135 tt_token_ = tt_token; | |
| 136 return S_OK; | |
| 137 } | |
| 138 | |
| 139 STDMETHODIMP App::get_iid(BSTR* iid) { | |
| 140 __mutexScope(model()->lock()); | |
| 141 ASSERT1(iid); | |
| 142 *iid = GuidToString(iid_).AllocSysString(); | |
| 143 return S_OK; | |
| 144 } | |
| 145 | |
| 146 STDMETHODIMP App::put_iid(BSTR iid) { | |
| 147 __mutexScope(model()->lock()); | |
| 148 return StringToGuidSafe(iid, &iid_); | |
| 149 } | |
| 150 | |
| 151 STDMETHODIMP App::get_brandCode(BSTR* brand_code) { | |
| 152 __mutexScope(model()->lock()); | |
| 153 ASSERT1(brand_code); | |
| 154 *brand_code = brand_code_.AllocSysString(); | |
| 155 return S_OK; | |
| 156 } | |
| 157 | |
| 158 STDMETHODIMP App::put_brandCode(BSTR brand_code) { | |
| 159 __mutexScope(model()->lock()); | |
| 160 brand_code_ = brand_code; | |
| 161 return S_OK; | |
| 162 } | |
| 163 | |
| 164 STDMETHODIMP App::get_clientId(BSTR* client_id) { | |
| 165 __mutexScope(model()->lock()); | |
| 166 ASSERT1(client_id); | |
| 167 *client_id = client_id_.AllocSysString(); | |
| 168 return S_OK; | |
| 169 } | |
| 170 | |
| 171 STDMETHODIMP App::put_clientId(BSTR client_id) { | |
| 172 __mutexScope(model()->lock()); | |
| 173 client_id_ = client_id; | |
| 174 return S_OK; | |
| 175 } | |
| 176 | |
| 177 STDMETHODIMP App::get_labels(BSTR* labels) { | |
| 178 __mutexScope(model()->lock()); | |
| 179 ASSERT1(labels); | |
| 180 *labels = GetExperimentLabels().AllocSysString(); | |
| 181 return S_OK; | |
| 182 } | |
| 183 | |
| 184 STDMETHODIMP App::put_labels(BSTR labels) { | |
| 185 __mutexScope(model()->lock()); | |
| 186 ExperimentLabels decoded_labels; | |
| 187 if (!decoded_labels.Deserialize(labels)) { | |
| 188 return E_INVALIDARG; | |
| 189 } | |
| 190 return decoded_labels.WriteToRegistry(app_bundle_->is_machine(), | |
| 191 app_guid_string()); | |
| 192 } | |
| 193 | |
| 194 STDMETHODIMP App::get_referralId(BSTR* referral_id) { | |
| 195 __mutexScope(model()->lock()); | |
| 196 ASSERT1(referral_id); | |
| 197 *referral_id = referral_id_.AllocSysString(); | |
| 198 return S_OK; | |
| 199 } | |
| 200 | |
| 201 STDMETHODIMP App::put_referralId(BSTR referral_id) { | |
| 202 __mutexScope(model()->lock()); | |
| 203 referral_id_ = referral_id; | |
| 204 return S_OK; | |
| 205 } | |
| 206 | |
| 207 STDMETHODIMP App::get_installTimeDiffSec(UINT* install_time_diff_sec) { | |
| 208 __mutexScope(model()->lock()); | |
| 209 ASSERT1(install_time_diff_sec); | |
| 210 *install_time_diff_sec = install_time_diff_sec_; | |
| 211 return S_OK; | |
| 212 } | |
| 213 | |
| 214 STDMETHODIMP App::get_isEulaAccepted(VARIANT_BOOL* is_eula_accepted) { | |
| 215 __mutexScope(model()->lock()); | |
| 216 ASSERT1(is_eula_accepted); | |
| 217 *is_eula_accepted = App::is_eula_accepted() ? VARIANT_TRUE : VARIANT_FALSE; | |
| 218 return S_OK; | |
| 219 } | |
| 220 | |
| 221 STDMETHODIMP App::put_isEulaAccepted(VARIANT_BOOL is_eula_accepted) { | |
| 222 __mutexScope(model()->lock()); | |
| 223 is_eula_accepted_ = is_eula_accepted ? TRISTATE_TRUE : TRISTATE_FALSE; | |
| 224 return S_OK; | |
| 225 } | |
| 226 | |
| 227 STDMETHODIMP App::get_displayName(BSTR* display_name) { | |
| 228 __mutexScope(model()->lock()); | |
| 229 ASSERT1(display_name); | |
| 230 *display_name = display_name_.AllocSysString(); | |
| 231 return S_OK; | |
| 232 } | |
| 233 | |
| 234 STDMETHODIMP App::put_displayName(BSTR display_name) { | |
| 235 __mutexScope(model()->lock()); | |
| 236 display_name_ = display_name; | |
| 237 return S_OK; | |
| 238 } | |
| 239 | |
| 240 STDMETHODIMP App::get_browserType(UINT* browser_type) { | |
| 241 __mutexScope(model()->lock()); | |
| 242 ASSERT1(browser_type); | |
| 243 *browser_type = browser_type_; | |
| 244 return S_OK; | |
| 245 } | |
| 246 | |
| 247 STDMETHODIMP App::put_browserType(UINT browser_type) { | |
| 248 __mutexScope(model()->lock()); | |
| 249 if (browser_type >= BROWSER_MAX) { | |
| 250 return E_INVALIDARG; | |
| 251 } | |
| 252 browser_type_ = static_cast<BrowserType>(browser_type); | |
| 253 return S_OK; | |
| 254 } | |
| 255 | |
| 256 STDMETHODIMP App::get_clientInstallData(BSTR* data) { | |
| 257 __mutexScope(model()->lock()); | |
| 258 ASSERT1(data); | |
| 259 *data = client_install_data_.AllocSysString(); | |
| 260 return S_OK; | |
| 261 } | |
| 262 | |
| 263 STDMETHODIMP App::put_clientInstallData(BSTR data) { | |
| 264 __mutexScope(model()->lock()); | |
| 265 client_install_data_ = data; | |
| 266 return S_OK; | |
| 267 } | |
| 268 | |
| 269 STDMETHODIMP App::get_serverInstallDataIndex(BSTR* index) { | |
| 270 __mutexScope(model()->lock()); | |
| 271 ASSERT1(index); | |
| 272 *index = server_install_data_index_.AllocSysString(); | |
| 273 return S_OK; | |
| 274 } | |
| 275 | |
| 276 STDMETHODIMP App::put_serverInstallDataIndex(BSTR index) { | |
| 277 __mutexScope(model()->lock()); | |
| 278 server_install_data_index_ = index; | |
| 279 return S_OK; | |
| 280 } | |
| 281 | |
| 282 STDMETHODIMP App::get_usageStatsEnable(UINT* usage_stats_enable) { | |
| 283 __mutexScope(model()->lock()); | |
| 284 ASSERT1(usage_stats_enable); | |
| 285 *usage_stats_enable = usage_stats_enable_; | |
| 286 return S_OK; | |
| 287 } | |
| 288 | |
| 289 STDMETHODIMP App::put_usageStatsEnable(UINT usage_stats_enable) { | |
| 290 __mutexScope(model()->lock()); | |
| 291 if (usage_stats_enable > TRISTATE_NONE) { | |
| 292 return E_INVALIDARG; | |
| 293 } | |
| 294 usage_stats_enable_ = static_cast<Tristate>(usage_stats_enable); | |
| 295 return S_OK; | |
| 296 } | |
| 297 | |
| 298 // TODO(omaha3): Replace decisions based on state() with calls to AppState. | |
| 299 // In this case, there should be a GetCurrentState() method on AppState. | |
| 300 STDMETHODIMP App::get_currentState(IDispatch** current_state) { | |
| 301 __mutexScope(model()->lock()); | |
| 302 | |
| 303 CORE_LOG(L3, (_T("[App::get_currentState][0x%p]"), this)); | |
| 304 ASSERT1(current_state); | |
| 305 | |
| 306 ULONGLONG bytes_downloaded = 0; | |
| 307 ULONGLONG total_bytes_to_download = 0; | |
| 308 ULONGLONG next_download_retry_time = 0; | |
| 309 LONG download_time_remaining_ms = kCurrentStateProgressUnknown; | |
| 310 LONG install_progress_percentage = kCurrentStateProgressUnknown; | |
| 311 LONG install_time_remaining_ms = kCurrentStateProgressUnknown; | |
| 312 | |
| 313 HRESULT hr = S_OK; | |
| 314 switch (state()) { | |
| 315 case STATE_INIT: | |
| 316 break; | |
| 317 case STATE_WAITING_TO_CHECK_FOR_UPDATE: | |
| 318 break; | |
| 319 case STATE_CHECKING_FOR_UPDATE: | |
| 320 break; | |
| 321 case STATE_UPDATE_AVAILABLE: | |
| 322 break; | |
| 323 case STATE_NO_UPDATE: | |
| 324 ASSERT1(error_code() == S_OK || | |
| 325 error_code() == GOOPDATE_E_UPDATE_DEFERRED); | |
| 326 ASSERT1(!completion_message_.IsEmpty()); | |
| 327 ASSERT1(completion_result_ == PingEvent::EVENT_RESULT_SUCCESS || | |
| 328 completion_result_ == PingEvent::EVENT_RESULT_UPDATE_DEFERRED); | |
| 329 ASSERT1(installer_result_code_ == 0); | |
| 330 break; | |
| 331 case STATE_WAITING_TO_DOWNLOAD: | |
| 332 case STATE_RETRYING_DOWNLOAD: | |
| 333 case STATE_DOWNLOADING: | |
| 334 case STATE_DOWNLOAD_COMPLETE: | |
| 335 case STATE_EXTRACTING: | |
| 336 case STATE_APPLYING_DIFFERENTIAL_PATCH: | |
| 337 case STATE_READY_TO_INSTALL: | |
| 338 hr = GetDownloadProgress(&bytes_downloaded, | |
| 339 &total_bytes_to_download, | |
| 340 &download_time_remaining_ms, | |
| 341 &next_download_retry_time); | |
| 342 break; | |
| 343 case STATE_WAITING_TO_INSTALL: | |
| 344 break; | |
| 345 case STATE_INSTALLING: | |
| 346 // TODO(omaha3): Obtain install_progress_percentage and | |
| 347 // install_time_remaining_ms. | |
| 348 break; | |
| 349 case STATE_INSTALL_COMPLETE: | |
| 350 install_progress_percentage = 100; | |
| 351 install_time_remaining_ms = 0; | |
| 352 | |
| 353 ASSERT1(error_code() == S_OK); | |
| 354 ASSERT1(!completion_message_.IsEmpty()); | |
| 355 ASSERT1(completion_result_ == PingEvent::EVENT_RESULT_SUCCESS || | |
| 356 completion_result_ == PingEvent::EVENT_RESULT_SUCCESS_REBOOT); | |
| 357 break; | |
| 358 case STATE_PAUSED: | |
| 359 break; | |
| 360 case STATE_ERROR: | |
| 361 ASSERT1(error_code() != S_OK); | |
| 362 ASSERT1(!completion_message_.IsEmpty()); | |
| 363 ASSERT1( | |
| 364 completion_result_ == PingEvent::EVENT_RESULT_ERROR || | |
| 365 completion_result_ == PingEvent::EVENT_RESULT_CANCELLED || | |
| 366 completion_result_ == PingEvent::EVENT_RESULT_INSTALLER_ERROR_MSI || | |
| 367 completion_result_ == PingEvent::EVENT_RESULT_INSTALLER_ERROR_OTHER || | |
| 368 completion_result_ == PingEvent::EVENT_RESULT_INSTALLER_ERROR_SYSTEM); | |
| 369 break; | |
| 370 default: | |
| 371 ASSERT1(false); | |
| 372 hr = E_FAIL; | |
| 373 break; | |
| 374 } | |
| 375 | |
| 376 if (FAILED(hr)) { | |
| 377 return hr; | |
| 378 } | |
| 379 | |
| 380 CComObject<CurrentAppState>* state_object = NULL; | |
| 381 hr = CurrentAppState::Create(state(), | |
| 382 next_version()->version(), | |
| 383 bytes_downloaded, | |
| 384 total_bytes_to_download, | |
| 385 download_time_remaining_ms, | |
| 386 next_download_retry_time, | |
| 387 install_progress_percentage, | |
| 388 install_time_remaining_ms, | |
| 389 is_canceled_, | |
| 390 error_context_.error_code, | |
| 391 error_context_.extra_code1, | |
| 392 completion_message_, | |
| 393 installer_result_code_, | |
| 394 installer_result_extra_code1_, | |
| 395 post_install_launch_command_line_, | |
| 396 post_install_url_, | |
| 397 post_install_action_, | |
| 398 &state_object); | |
| 399 if (FAILED(hr)) { | |
| 400 return hr; | |
| 401 } | |
| 402 | |
| 403 return state_object->QueryInterface(current_state); | |
| 404 } | |
| 405 | |
| 406 // TODO(omaha3): If some packages are already cached, there may be awkward jumps | |
| 407 // in progress if we don't filter those out of bytes_total from the beginning. | |
| 408 // TODO(omaha3): For now we use the package's expected_size to calculate | |
| 409 // bytes_total. This may or may not be what we want. See the TODO for | |
| 410 // Package::OnProgress(). | |
| 411 // TODO(omaha3): Maybe optimize, especially in states other than | |
| 412 // STATE_DOWNLOADING. | |
| 413 HRESULT App::GetDownloadProgress(uint64* bytes_downloaded, | |
| 414 uint64* bytes_total, | |
| 415 LONG* time_remaining_ms, | |
| 416 uint64* next_retry_time) { | |
| 417 ASSERT1(model()->IsLockedByCaller()); | |
| 418 | |
| 419 ASSERT1(bytes_downloaded); | |
| 420 ASSERT1(bytes_total); | |
| 421 ASSERT1(time_remaining_ms); | |
| 422 ASSERT1(next_retry_time); | |
| 423 | |
| 424 *bytes_downloaded = 0; | |
| 425 *bytes_total = 0; | |
| 426 *next_retry_time = 0; | |
| 427 | |
| 428 *time_remaining_ms = kCurrentStateProgressUnknown; | |
| 429 | |
| 430 for (size_t i = 0; i < working_version_->GetNumberOfPackages(); ++i) { | |
| 431 const Package* package = working_version_->GetPackage(i); | |
| 432 | |
| 433 const uint64 package_bytes = package->bytes_downloaded(); | |
| 434 ASSERT1((*bytes_downloaded + package_bytes > *bytes_downloaded) || | |
| 435 package_bytes == 0); | |
| 436 *bytes_downloaded += package_bytes; | |
| 437 | |
| 438 const uint64 package_size = package->expected_size(); | |
| 439 ASSERT1(0 < package_size); | |
| 440 ASSERT1(*bytes_total + package_size > *bytes_total); | |
| 441 *bytes_total += package_size; | |
| 442 | |
| 443 LONG package_remaining_time_ms = | |
| 444 package->GetEstimatedRemainingDownloadTimeMs(); | |
| 445 if (*time_remaining_ms < package_remaining_time_ms) { | |
| 446 *time_remaining_ms = package_remaining_time_ms; | |
| 447 } | |
| 448 | |
| 449 uint64 package_next_retry_time = package->next_download_retry_time(); | |
| 450 if (package_bytes < package_size && package_next_retry_time != 0 && | |
| 451 (*next_retry_time == 0 || *next_retry_time > package_next_retry_time)) { | |
| 452 *next_retry_time = package_next_retry_time; | |
| 453 } | |
| 454 } | |
| 455 | |
| 456 ASSERT1(*bytes_downloaded <= *bytes_total); | |
| 457 | |
| 458 ASSERT1(previous_total_download_bytes_ == *bytes_total || | |
| 459 previous_total_download_bytes_ == 0); | |
| 460 previous_total_download_bytes_ = *bytes_total; | |
| 461 | |
| 462 return S_OK; | |
| 463 } | |
| 464 | |
| 465 AppBundle* App::app_bundle() { | |
| 466 __mutexScope(model()->lock()); | |
| 467 return app_bundle_; | |
| 468 } | |
| 469 | |
| 470 const AppBundle* App::app_bundle() const { | |
| 471 __mutexScope(model()->lock()); | |
| 472 return app_bundle_; | |
| 473 } | |
| 474 | |
| 475 AppVersion* App::current_version() { | |
| 476 __mutexScope(model()->lock()); | |
| 477 return current_version_.get(); | |
| 478 } | |
| 479 | |
| 480 const AppVersion* App::current_version() const { | |
| 481 __mutexScope(model()->lock()); | |
| 482 return current_version_.get(); | |
| 483 } | |
| 484 | |
| 485 AppVersion* App::next_version() { | |
| 486 __mutexScope(model()->lock()); | |
| 487 return next_version_.get(); | |
| 488 } | |
| 489 | |
| 490 const AppVersion* App::next_version() const { | |
| 491 __mutexScope(model()->lock()); | |
| 492 return next_version_.get(); | |
| 493 } | |
| 494 | |
| 495 CString App::app_guid_string() const { | |
| 496 return GuidToString(app_guid()); | |
| 497 } | |
| 498 | |
| 499 GUID App::app_guid() const { | |
| 500 __mutexScope(model()->lock()); | |
| 501 return app_guid_; | |
| 502 } | |
| 503 | |
| 504 void App::set_app_guid(const GUID& app_guid) { | |
| 505 __mutexScope(model()->lock()); | |
| 506 app_guid_ = app_guid; | |
| 507 } | |
| 508 | |
| 509 CString App::language() const { | |
| 510 __mutexScope(model()->lock()); | |
| 511 return language_; | |
| 512 } | |
| 513 | |
| 514 bool App::is_eula_accepted() const { | |
| 515 __mutexScope(model()->lock()); | |
| 516 return is_eula_accepted_ == TRISTATE_TRUE; | |
| 517 } | |
| 518 | |
| 519 CString App::display_name() const { | |
| 520 __mutexScope(model()->lock()); | |
| 521 return display_name_; | |
| 522 } | |
| 523 | |
| 524 CurrentState App::state() const { | |
| 525 __mutexScope(model()->lock()); | |
| 526 return app_state_->state(); | |
| 527 } | |
| 528 | |
| 529 bool App::is_update() const { | |
| 530 __mutexScope(model()->lock()); | |
| 531 ASSERT1(current_version_->version().IsEmpty() != is_update_); | |
| 532 return is_update_; | |
| 533 } | |
| 534 | |
| 535 bool App::has_update_available() const { | |
| 536 __mutexScope(model()->lock()); | |
| 537 return has_update_available_; | |
| 538 } | |
| 539 | |
| 540 void App::set_has_update_available(bool has_update_available) { | |
| 541 __mutexScope(model()->lock()); | |
| 542 has_update_available_ = has_update_available; | |
| 543 } | |
| 544 | |
| 545 GUID App::iid() const { | |
| 546 __mutexScope(model()->lock()); | |
| 547 return iid_; | |
| 548 } | |
| 549 | |
| 550 CString App::client_id() const { | |
| 551 __mutexScope(model()->lock()); | |
| 552 return client_id_; | |
| 553 } | |
| 554 | |
| 555 CString App::GetExperimentLabels() const { | |
| 556 __mutexScope(model()->lock()); | |
| 557 ExperimentLabels stored_labels; | |
| 558 VERIFY1(SUCCEEDED(stored_labels.ReadFromRegistry(app_bundle_->is_machine(), | |
| 559 app_guid_string()))); | |
| 560 return stored_labels.Serialize(); | |
| 561 } | |
| 562 | |
| 563 CString App::referral_id() const { | |
| 564 __mutexScope(model()->lock()); | |
| 565 return referral_id_; | |
| 566 } | |
| 567 | |
| 568 BrowserType App::browser_type() const { | |
| 569 __mutexScope(model()->lock()); | |
| 570 return browser_type_; | |
| 571 } | |
| 572 | |
| 573 Tristate App::usage_stats_enable() const { | |
| 574 __mutexScope(model()->lock()); | |
| 575 return usage_stats_enable_; | |
| 576 } | |
| 577 | |
| 578 CString App::client_install_data() const { | |
| 579 __mutexScope(model()->lock()); | |
| 580 return client_install_data_; | |
| 581 } | |
| 582 | |
| 583 CString App::server_install_data() const { | |
| 584 __mutexScope(model()->lock()); | |
| 585 return server_install_data_; | |
| 586 } | |
| 587 | |
| 588 void App::set_server_install_data(const CString& server_install_data) { | |
| 589 __mutexScope(model()->lock()); | |
| 590 server_install_data_ = server_install_data; | |
| 591 } | |
| 592 | |
| 593 CString App::brand_code() const { | |
| 594 __mutexScope(model()->lock()); | |
| 595 return brand_code_; | |
| 596 } | |
| 597 | |
| 598 // TODO(omaha): for better accuracy, compute the value when used. | |
| 599 uint32 App::install_time_diff_sec() const { | |
| 600 __mutexScope(model()->lock()); | |
| 601 return install_time_diff_sec_; | |
| 602 } | |
| 603 | |
| 604 ActiveStates App::did_run() const { | |
| 605 __mutexScope(model()->lock()); | |
| 606 return did_run_; | |
| 607 } | |
| 608 | |
| 609 int App::days_since_last_active_ping() const { | |
| 610 __mutexScope(model()->lock()); | |
| 611 return days_since_last_active_ping_; | |
| 612 } | |
| 613 | |
| 614 void App::set_days_since_last_active_ping(int days) { | |
| 615 __mutexScope(model()->lock()); | |
| 616 days_since_last_active_ping_ = days; | |
| 617 } | |
| 618 | |
| 619 int App::days_since_last_roll_call() const { | |
| 620 __mutexScope(model()->lock()); | |
| 621 return days_since_last_roll_call_; | |
| 622 } | |
| 623 | |
| 624 void App::set_days_since_last_roll_call(int days) { | |
| 625 __mutexScope(model()->lock()); | |
| 626 days_since_last_roll_call_ = days; | |
| 627 } | |
| 628 | |
| 629 CString App::ap() const { | |
| 630 __mutexScope(model()->lock()); | |
| 631 return ap_; | |
| 632 } | |
| 633 | |
| 634 CString App::tt_token() const { | |
| 635 __mutexScope(model()->lock()); | |
| 636 return tt_token_; | |
| 637 } | |
| 638 | |
| 639 CString App::server_install_data_index() const { | |
| 640 __mutexScope(model()->lock()); | |
| 641 return server_install_data_index_; | |
| 642 } | |
| 643 | |
| 644 HRESULT App::error_code() const { | |
| 645 __mutexScope(model()->lock()); | |
| 646 return error_context_.error_code; | |
| 647 } | |
| 648 | |
| 649 ErrorContext App::error_context() const { | |
| 650 __mutexScope(model()->lock()); | |
| 651 return error_context_; | |
| 652 } | |
| 653 | |
| 654 int App::installer_result_code() const { | |
| 655 __mutexScope(model()->lock()); | |
| 656 return installer_result_code_; | |
| 657 } | |
| 658 | |
| 659 int App::installer_result_extra_code1() const { | |
| 660 __mutexScope(model()->lock()); | |
| 661 return installer_result_extra_code1_; | |
| 662 } | |
| 663 | |
| 664 const PingEventVector& App::ping_events() const { | |
| 665 __mutexScope(model()->lock()); | |
| 666 return ping_events_; | |
| 667 } | |
| 668 | |
| 669 AppVersion* App::working_version() { | |
| 670 __mutexScope(model()->lock()); | |
| 671 return working_version_; | |
| 672 } | |
| 673 | |
| 674 const AppVersion* App::working_version() const { | |
| 675 __mutexScope(model()->lock()); | |
| 676 return working_version_; | |
| 677 } | |
| 678 | |
| 679 CString App::FetchAndResetLogText() { | |
| 680 __mutexScope(model()->lock()); | |
| 681 CString event_log_text(event_log_text_); | |
| 682 event_log_text_.Empty(); | |
| 683 | |
| 684 return event_log_text; | |
| 685 } | |
| 686 | |
| 687 void App::LogTextAppendFormat(const TCHAR* format, ...) { | |
| 688 ASSERT1(format); | |
| 689 | |
| 690 CString log_string; | |
| 691 | |
| 692 va_list arguments; | |
| 693 va_start(arguments, format); | |
| 694 SafeCStringFormatV(&log_string, format, arguments); | |
| 695 va_end(arguments); | |
| 696 | |
| 697 __mutexScope(model()->lock()); | |
| 698 SafeCStringAppendFormat(&event_log_text_, _T("App=%s, Ver=%s, %s\n"), | |
| 699 app_guid_string().GetString(), | |
| 700 current_version()->version().GetString(), | |
| 701 log_string.GetString()); | |
| 702 } | |
| 703 | |
| 704 void App::AddPingEvent(const PingEventPtr& ping_event) { | |
| 705 __mutexScope(model()->lock()); | |
| 706 ping_events_.push_back(ping_event); | |
| 707 CORE_LOG(L3, (_T("[ping event added][%s]"), ping_event->ToString())); | |
| 708 } | |
| 709 | |
| 710 HRESULT App::CheckGroupPolicy() const { | |
| 711 __mutexScope(model()->lock()); | |
| 712 | |
| 713 bool is_auto_update = false; | |
| 714 | |
| 715 if (is_update_) { | |
| 716 if (!ConfigManager::Instance()->CanUpdateApp( | |
| 717 app_guid_, | |
| 718 !app_bundle_->is_auto_update())) { | |
| 719 return GOOPDATE_E_APP_UPDATE_DISABLED_BY_POLICY; | |
| 720 } | |
| 721 } else { | |
| 722 ASSERT1(!is_auto_update); | |
| 723 if (!ConfigManager::Instance()->CanInstallApp(app_guid_)) { | |
| 724 return GOOPDATE_E_APP_INSTALL_DISABLED_BY_POLICY; | |
| 725 } | |
| 726 } | |
| 727 | |
| 728 return S_OK; | |
| 729 } | |
| 730 | |
| 731 void App::SetDownloadStartTime() { | |
| 732 __mutexScope(model()->lock()); | |
| 733 ASSERT1(download_complete_time_ms_ == 0); | |
| 734 ASSERT1(num_bytes_downloaded_ == 0); | |
| 735 | |
| 736 download_start_time_ms_ = GetCurrentMsTime(); | |
| 737 } | |
| 738 | |
| 739 void App::SetDownloadCompleteTime() { | |
| 740 __mutexScope(model()->lock()); | |
| 741 download_complete_time_ms_ = GetCurrentMsTime(); | |
| 742 } | |
| 743 | |
| 744 void App::UpdateNumBytesDownloaded(uint64 num_bytes) { | |
| 745 __mutexScope(model()->lock()); | |
| 746 | |
| 747 CORE_LOG(L3, (_T("[RecordDownloadedBytes][new bytes downloaded: %llu]"), | |
| 748 num_bytes)); | |
| 749 num_bytes_downloaded_ += num_bytes; | |
| 750 } | |
| 751 | |
| 752 int App::GetDownloadTimeMs() const { | |
| 753 __mutexScope(model()->lock()); | |
| 754 | |
| 755 if (download_complete_time_ms_ < download_start_time_ms_) { | |
| 756 return 0; | |
| 757 } | |
| 758 | |
| 759 return static_cast<int>(download_complete_time_ms_ - download_start_time_ms_); | |
| 760 } | |
| 761 | |
| 762 uint64 App::num_bytes_downloaded() const { | |
| 763 __mutexScope(model()->lock()); | |
| 764 return num_bytes_downloaded_; | |
| 765 } | |
| 766 | |
| 767 uint64 App::GetPackagesTotalSize() const { | |
| 768 __mutexScope(model()->lock()); | |
| 769 | |
| 770 uint64 total_size = 0; | |
| 771 const size_t num_packages = working_version_->GetNumberOfPackages(); | |
| 772 for (size_t i = 0; i < num_packages; ++i) { | |
| 773 total_size += working_version_->GetPackage(i)->expected_size(); | |
| 774 } | |
| 775 | |
| 776 return total_size; | |
| 777 } | |
| 778 | |
| 779 // | |
| 780 // State transition methods. | |
| 781 // These should not do anything except acquire the lock if appropriate and call | |
| 782 // the corresponding AppState method. | |
| 783 // | |
| 784 | |
| 785 // This is the first transition. EULA acceptance must have been set by now. | |
| 786 // Fail so that client developers realize quickly that something is wrong. | |
| 787 // Otherwise, they might ship a client that installs apps that never update. | |
| 788 void App::QueueUpdateCheck() { | |
| 789 __mutexScope(model()->lock()); | |
| 790 | |
| 791 ASSERT1(is_eula_accepted_ != TRISTATE_NONE); | |
| 792 if (is_eula_accepted_ == TRISTATE_NONE) { | |
| 793 CString message; | |
| 794 StringFormatter formatter(app_bundle_->display_language()); | |
| 795 VERIFY1(SUCCEEDED(formatter.LoadString(IDS_INSTALL_FAILED, &message))); | |
| 796 Error(ErrorContext(GOOPDATE_E_CALL_UNEXPECTED), message); | |
| 797 } | |
| 798 | |
| 799 app_state_->QueueUpdateCheck(this); | |
| 800 } | |
| 801 | |
| 802 void App::PreUpdateCheck(xml::UpdateRequest* update_request) { | |
| 803 ASSERT1(update_request); | |
| 804 __mutexScope(model()->lock()); | |
| 805 app_state_->PreUpdateCheck(this, update_request); | |
| 806 } | |
| 807 | |
| 808 void App::PostUpdateCheck(HRESULT result, | |
| 809 xml::UpdateResponse* update_response) { | |
| 810 ASSERT1(update_response); | |
| 811 __mutexScope(model()->lock()); | |
| 812 app_state_->PostUpdateCheck(this, result, update_response); | |
| 813 } | |
| 814 | |
| 815 void App::QueueDownload() { | |
| 816 __mutexScope(model()->lock()); | |
| 817 app_state_->QueueDownload(this); | |
| 818 } | |
| 819 | |
| 820 void App::QueueDownloadOrInstall() { | |
| 821 __mutexScope(model()->lock()); | |
| 822 app_state_->QueueDownloadOrInstall(this); | |
| 823 } | |
| 824 | |
| 825 // Does not take the lock because this is a blocking call. | |
| 826 void App::Download(DownloadManagerInterface* download_manager) { | |
| 827 app_state_->Download(this, download_manager); | |
| 828 } | |
| 829 | |
| 830 void App::Downloading() { | |
| 831 __mutexScope(model()->lock()); | |
| 832 app_state_->Downloading(this); | |
| 833 } | |
| 834 | |
| 835 void App::DownloadComplete() { | |
| 836 __mutexScope(model()->lock()); | |
| 837 app_state_->DownloadComplete(this); | |
| 838 } | |
| 839 | |
| 840 void App::MarkReadyToInstall() { | |
| 841 __mutexScope(model()->lock()); | |
| 842 app_state_->MarkReadyToInstall(this); | |
| 843 } | |
| 844 | |
| 845 void App::QueueInstall() { | |
| 846 __mutexScope(model()->lock()); | |
| 847 app_state_->QueueInstall(this); | |
| 848 } | |
| 849 | |
| 850 // Does not take the lock because this is a blocking call. | |
| 851 void App::Install(InstallManagerInterface* install_manager) { | |
| 852 app_state_->Install(this, install_manager); | |
| 853 } | |
| 854 | |
| 855 void App::Installing() { | |
| 856 __mutexScope(model()->lock()); | |
| 857 app_state_->Installing(this); | |
| 858 } | |
| 859 | |
| 860 void App::ReportInstallerComplete(const InstallerResultInfo& result_info) { | |
| 861 __mutexScope(model()->lock()); | |
| 862 app_state_->ReportInstallerComplete(this, | |
| 863 result_info); | |
| 864 } | |
| 865 | |
| 866 void App::Pause() { | |
| 867 __mutexScope(model()->lock()); | |
| 868 return app_state_->Pause(this); | |
| 869 } | |
| 870 | |
| 871 void App::Cancel() { | |
| 872 __mutexScope(model()->lock()); | |
| 873 return app_state_->Cancel(this); | |
| 874 } | |
| 875 | |
| 876 void App::Error(const ErrorContext& error_context, const CString& message) { | |
| 877 __mutexScope(model()->lock()); | |
| 878 app_state_->Error(this, error_context, message); | |
| 879 } | |
| 880 | |
| 881 void App::ChangeState(fsm::AppState* app_state) { | |
| 882 ASSERT1(app_state); | |
| 883 ASSERT1(model()->IsLockedByCaller()); | |
| 884 CurrentState existing_state = app_state_->state(); | |
| 885 app_state_.reset(app_state); | |
| 886 PingEventPtr ping_event( | |
| 887 app_state->CreatePingEvent(this, existing_state)); | |
| 888 if (ping_event.get()) { | |
| 889 AddPingEvent(ping_event); | |
| 890 } | |
| 891 } | |
| 892 | |
| 893 void App::SetError(const ErrorContext& error_context, const CString& message) { | |
| 894 ASSERT1(FAILED(error_context.error_code)); | |
| 895 ASSERT1(!message.IsEmpty()); | |
| 896 ASSERT1(model()->IsLockedByCaller()); | |
| 897 | |
| 898 error_context_ = error_context; | |
| 899 completion_message_ = message; | |
| 900 | |
| 901 is_canceled_ = (error_context_.error_code == GOOPDATE_E_CANCELLED); | |
| 902 completion_result_ = is_canceled_ ? PingEvent::EVENT_RESULT_CANCELLED : | |
| 903 PingEvent::EVENT_RESULT_ERROR; | |
| 904 } | |
| 905 | |
| 906 void App::SetNoUpdate(const ErrorContext& error_context, | |
| 907 const CString& message) { | |
| 908 ASSERT1(!message.IsEmpty()); | |
| 909 ASSERT1(model()->IsLockedByCaller()); | |
| 910 | |
| 911 error_context_ = error_context; | |
| 912 completion_message_ = message; | |
| 913 | |
| 914 const bool is_deferred_update = | |
| 915 (error_context_.error_code == GOOPDATE_E_UPDATE_DEFERRED); | |
| 916 completion_result_ = is_deferred_update ? | |
| 917 PingEvent::EVENT_RESULT_UPDATE_DEFERRED : | |
| 918 PingEvent::EVENT_RESULT_SUCCESS; | |
| 919 } | |
| 920 | |
| 921 void App::SetInstallerResult(const InstallerResultInfo& result_info) { | |
| 922 ASSERT1(result_info.type != INSTALLER_RESULT_UNKNOWN); | |
| 923 ASSERT1(!result_info.text.IsEmpty()); | |
| 924 ASSERT1(model()->IsLockedByCaller()); | |
| 925 | |
| 926 completion_message_ = result_info.text; | |
| 927 installer_result_code_ = result_info.code; | |
| 928 installer_result_extra_code1_ = result_info.extra_code1; | |
| 929 post_install_launch_command_line_ = | |
| 930 result_info.post_install_launch_command_line; | |
| 931 post_install_url_ = result_info.post_install_url; | |
| 932 post_install_action_ = result_info.post_install_action; | |
| 933 | |
| 934 switch (result_info.type) { | |
| 935 case INSTALLER_RESULT_SUCCESS: { | |
| 936 error_context_.error_code = S_OK; | |
| 937 | |
| 938 // TODO(omaha3): Determine whether a reboot is required. See TODO in | |
| 939 // InstallerWrapper. | |
| 940 const bool is_reboot_required = false; | |
| 941 completion_result_ = is_reboot_required ? | |
| 942 PingEvent::EVENT_RESULT_SUCCESS_REBOOT : | |
| 943 PingEvent::EVENT_RESULT_SUCCESS; | |
| 944 | |
| 945 // We do not know whether Goopdate has succeeded because its installer has | |
| 946 // not completed. | |
| 947 if (!::IsEqualGUID(kGoopdateGuid, app_guid_)) { | |
| 948 AppManager::Instance()->PersistSuccessfulInstall(*this); | |
| 949 } | |
| 950 break; | |
| 951 } | |
| 952 case INSTALLER_RESULT_ERROR_MSI: | |
| 953 completion_result_ = PingEvent::EVENT_RESULT_INSTALLER_ERROR_MSI; | |
| 954 error_context_.error_code = GOOPDATEINSTALL_E_INSTALLER_FAILED; | |
| 955 break; | |
| 956 case INSTALLER_RESULT_ERROR_SYSTEM: | |
| 957 completion_result_ = PingEvent::EVENT_RESULT_INSTALLER_ERROR_SYSTEM; | |
| 958 error_context_.error_code = GOOPDATEINSTALL_E_INSTALLER_FAILED; | |
| 959 break; | |
| 960 case INSTALLER_RESULT_ERROR_OTHER: | |
| 961 completion_result_ = PingEvent::EVENT_RESULT_INSTALLER_ERROR_OTHER; | |
| 962 error_context_.error_code = GOOPDATEINSTALL_E_INSTALLER_FAILED; | |
| 963 break; | |
| 964 case INSTALLER_RESULT_UNKNOWN: | |
| 965 default: | |
| 966 ASSERT1(false); | |
| 967 completion_result_ = PingEvent::EVENT_RESULT_ERROR; | |
| 968 error_context_.error_code = E_FAIL; | |
| 969 } | |
| 970 } | |
| 971 | |
| 972 CString App::GetInstallData() const { | |
| 973 __mutexScope(model()->lock()); | |
| 974 | |
| 975 ASSERT1(state() >= STATE_UPDATE_AVAILABLE && | |
| 976 state() <= STATE_INSTALL_COMPLETE); | |
| 977 | |
| 978 if (!client_install_data_.IsEmpty()) { | |
| 979 return client_install_data_; | |
| 980 } | |
| 981 | |
| 982 return server_install_data_; | |
| 983 } | |
| 984 | |
| 985 // IApp. | |
| 986 STDMETHODIMP AppWrapper::get_currentVersion(IDispatch** current_version) { | |
| 987 __mutexScope(model()->lock()); | |
| 988 return AppVersionWrapper::Create(controlling_ptr(), | |
| 989 wrapped_obj()->current_version(), | |
| 990 current_version); | |
| 991 } | |
| 992 | |
| 993 STDMETHODIMP AppWrapper::get_nextVersion(IDispatch** next_version) { | |
| 994 __mutexScope(model()->lock()); | |
| 995 return AppVersionWrapper::Create(controlling_ptr(), | |
| 996 wrapped_obj()->next_version(), | |
| 997 next_version); | |
| 998 } | |
| 999 | |
| 1000 // IApp. | |
| 1001 STDMETHODIMP AppWrapper::get_appId(BSTR* app_id) { | |
| 1002 __mutexScope(model()->lock()); | |
| 1003 return wrapped_obj()->get_appId(app_id); | |
| 1004 } | |
| 1005 | |
| 1006 STDMETHODIMP AppWrapper::get_pv(BSTR* pv) { | |
| 1007 __mutexScope(model()->lock()); | |
| 1008 return wrapped_obj()->get_pv(pv); | |
| 1009 } | |
| 1010 | |
| 1011 STDMETHODIMP AppWrapper::put_pv(BSTR pv) { | |
| 1012 __mutexScope(model()->lock()); | |
| 1013 return wrapped_obj()->put_pv(pv); | |
| 1014 } | |
| 1015 | |
| 1016 STDMETHODIMP AppWrapper::get_language(BSTR* language) { | |
| 1017 __mutexScope(model()->lock()); | |
| 1018 return wrapped_obj()->get_language(language); | |
| 1019 } | |
| 1020 | |
| 1021 STDMETHODIMP AppWrapper::put_language(BSTR language) { | |
| 1022 __mutexScope(model()->lock()); | |
| 1023 return wrapped_obj()->put_language(language); | |
| 1024 } | |
| 1025 | |
| 1026 STDMETHODIMP AppWrapper::get_ap(BSTR* ap) { | |
| 1027 __mutexScope(model()->lock()); | |
| 1028 return wrapped_obj()->get_ap(ap); | |
| 1029 } | |
| 1030 | |
| 1031 STDMETHODIMP AppWrapper::put_ap(BSTR ap) { | |
| 1032 __mutexScope(model()->lock()); | |
| 1033 return wrapped_obj()->put_ap(ap); | |
| 1034 } | |
| 1035 | |
| 1036 STDMETHODIMP AppWrapper::get_ttToken(BSTR* tt_token) { | |
| 1037 __mutexScope(model()->lock()); | |
| 1038 return wrapped_obj()->get_ttToken(tt_token); | |
| 1039 } | |
| 1040 | |
| 1041 STDMETHODIMP AppWrapper::put_ttToken(BSTR tt_token) { | |
| 1042 __mutexScope(model()->lock()); | |
| 1043 return wrapped_obj()->put_ttToken(tt_token); | |
| 1044 } | |
| 1045 | |
| 1046 STDMETHODIMP AppWrapper::get_iid(BSTR* iid) { | |
| 1047 __mutexScope(model()->lock()); | |
| 1048 return wrapped_obj()->get_iid(iid); | |
| 1049 } | |
| 1050 | |
| 1051 STDMETHODIMP AppWrapper::put_iid(BSTR iid) { | |
| 1052 __mutexScope(model()->lock()); | |
| 1053 return wrapped_obj()->put_iid(iid); | |
| 1054 } | |
| 1055 | |
| 1056 STDMETHODIMP AppWrapper::get_brandCode(BSTR* brand_code) { | |
| 1057 __mutexScope(model()->lock()); | |
| 1058 return wrapped_obj()->get_brandCode(brand_code); | |
| 1059 } | |
| 1060 | |
| 1061 STDMETHODIMP AppWrapper::put_brandCode(BSTR brand_code) { | |
| 1062 __mutexScope(model()->lock()); | |
| 1063 return wrapped_obj()->put_brandCode(brand_code); | |
| 1064 } | |
| 1065 | |
| 1066 STDMETHODIMP AppWrapper::get_clientId(BSTR* client_id) { | |
| 1067 __mutexScope(model()->lock()); | |
| 1068 return wrapped_obj()->get_clientId(client_id); | |
| 1069 } | |
| 1070 | |
| 1071 STDMETHODIMP AppWrapper::put_clientId(BSTR client_id) { | |
| 1072 __mutexScope(model()->lock()); | |
| 1073 return wrapped_obj()->put_clientId(client_id); | |
| 1074 } | |
| 1075 | |
| 1076 STDMETHODIMP AppWrapper::get_labels(BSTR* labels) { | |
| 1077 __mutexScope(model()->lock()); | |
| 1078 return wrapped_obj()->get_labels(labels); | |
| 1079 } | |
| 1080 | |
| 1081 STDMETHODIMP AppWrapper::put_labels(BSTR labels) { | |
| 1082 __mutexScope(model()->lock()); | |
| 1083 return wrapped_obj()->put_labels(labels); | |
| 1084 } | |
| 1085 | |
| 1086 STDMETHODIMP AppWrapper::get_referralId(BSTR* referral_id) { | |
| 1087 __mutexScope(model()->lock()); | |
| 1088 return wrapped_obj()->get_referralId(referral_id); | |
| 1089 } | |
| 1090 | |
| 1091 STDMETHODIMP AppWrapper::put_referralId(BSTR referral_id) { | |
| 1092 __mutexScope(model()->lock()); | |
| 1093 return wrapped_obj()->put_referralId(referral_id); | |
| 1094 } | |
| 1095 | |
| 1096 STDMETHODIMP AppWrapper::get_installTimeDiffSec(UINT* install_time_diff_sec) { | |
| 1097 __mutexScope(model()->lock()); | |
| 1098 return wrapped_obj()->get_installTimeDiffSec(install_time_diff_sec); | |
| 1099 } | |
| 1100 | |
| 1101 STDMETHODIMP AppWrapper::get_isEulaAccepted(VARIANT_BOOL* is_eula_accepted) { | |
| 1102 __mutexScope(model()->lock()); | |
| 1103 return wrapped_obj()->get_isEulaAccepted(is_eula_accepted); | |
| 1104 } | |
| 1105 | |
| 1106 STDMETHODIMP AppWrapper::put_isEulaAccepted(VARIANT_BOOL is_eula_accepted) { | |
| 1107 __mutexScope(model()->lock()); | |
| 1108 return wrapped_obj()->put_isEulaAccepted(is_eula_accepted); | |
| 1109 } | |
| 1110 | |
| 1111 STDMETHODIMP AppWrapper::get_displayName(BSTR* display_name) { | |
| 1112 __mutexScope(model()->lock()); | |
| 1113 return wrapped_obj()->get_displayName(display_name); | |
| 1114 } | |
| 1115 | |
| 1116 STDMETHODIMP AppWrapper::put_displayName(BSTR display_name) { | |
| 1117 __mutexScope(model()->lock()); | |
| 1118 return wrapped_obj()->put_displayName(display_name); | |
| 1119 } | |
| 1120 | |
| 1121 STDMETHODIMP AppWrapper::get_browserType(UINT* browser_type) { | |
| 1122 __mutexScope(model()->lock()); | |
| 1123 return wrapped_obj()->get_browserType(browser_type); | |
| 1124 } | |
| 1125 | |
| 1126 STDMETHODIMP AppWrapper::put_browserType(UINT browser_type) { | |
| 1127 __mutexScope(model()->lock()); | |
| 1128 return wrapped_obj()->put_browserType(browser_type); | |
| 1129 } | |
| 1130 | |
| 1131 STDMETHODIMP AppWrapper::get_clientInstallData(BSTR* data) { | |
| 1132 __mutexScope(model()->lock()); | |
| 1133 return wrapped_obj()->get_clientInstallData(data); | |
| 1134 } | |
| 1135 | |
| 1136 STDMETHODIMP AppWrapper::put_clientInstallData(BSTR data) { | |
| 1137 __mutexScope(model()->lock()); | |
| 1138 return wrapped_obj()->put_clientInstallData(data); | |
| 1139 } | |
| 1140 | |
| 1141 STDMETHODIMP AppWrapper::get_serverInstallDataIndex(BSTR* index) { | |
| 1142 __mutexScope(model()->lock()); | |
| 1143 return wrapped_obj()->get_serverInstallDataIndex(index); | |
| 1144 } | |
| 1145 | |
| 1146 STDMETHODIMP AppWrapper::put_serverInstallDataIndex(BSTR index) { | |
| 1147 __mutexScope(model()->lock()); | |
| 1148 return wrapped_obj()->put_serverInstallDataIndex(index); | |
| 1149 } | |
| 1150 | |
| 1151 STDMETHODIMP AppWrapper::get_usageStatsEnable(UINT* usage_stats_enable) { | |
| 1152 __mutexScope(model()->lock()); | |
| 1153 return wrapped_obj()->get_usageStatsEnable(usage_stats_enable); | |
| 1154 } | |
| 1155 | |
| 1156 STDMETHODIMP AppWrapper::put_usageStatsEnable(UINT usage_stats_enable) { | |
| 1157 __mutexScope(model()->lock()); | |
| 1158 return wrapped_obj()->put_usageStatsEnable(usage_stats_enable); | |
| 1159 } | |
| 1160 | |
| 1161 STDMETHODIMP AppWrapper::get_currentState(IDispatch** current_state_disp) { | |
| 1162 __mutexScope(model()->lock()); | |
| 1163 return wrapped_obj()->get_currentState(current_state_disp); | |
| 1164 } | |
| 1165 | |
| 1166 | |
| 1167 // Sets app's app_state to state. Used by unit tests to set up the state to the | |
| 1168 // correct precondition for the test case. App friends this function, allowing | |
| 1169 // it to call the private member function. | |
| 1170 void SetAppStateForUnitTest(App* app, fsm::AppState* state) { | |
| 1171 ASSERT1(app); | |
| 1172 ASSERT1(state); | |
| 1173 __mutexScope(app->model()->lock()); | |
| 1174 app->ChangeState(state); | |
| 1175 } | |
| 1176 | |
| 1177 } // namespace omaha | |
| OLD | NEW |