Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(255)

Side by Side Diff: goopdate/app.cc

Issue 624713003: Keep only base/extractor.[cc|h]. (Closed) Base URL: https://chromium.googlesource.com/external/omaha.git@master
Patch Set: Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « goopdate/app.h ('k') | goopdate/app_bundle.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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
OLDNEW
« no previous file with comments | « goopdate/app.h ('k') | goopdate/app_bundle.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698