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

Side by Side Diff: goopdate/app_bundle_state_initialized.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_bundle_state_initialized.h ('k') | goopdate/app_bundle_state_paused.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 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_bundle_state_initialized.h"
17 #include "omaha/base/debug.h"
18 #include "omaha/base/error.h"
19 #include "omaha/base/logging.h"
20 #include "omaha/common/app_registry_utils.h"
21 #include "omaha/common/config_manager.h"
22 #include "omaha/common/web_services_client.h"
23 #include "omaha/goopdate/app_bundle_state_busy.h"
24 #include "omaha/goopdate/app_bundle_state_paused.h"
25 #include "omaha/goopdate/app_bundle_state_stopped.h"
26 #include "omaha/goopdate/app_manager.h"
27 #include "omaha/goopdate/model.h"
28
29 namespace omaha {
30
31 namespace fsm {
32
33 HRESULT AppBundleStateInitialized::Pause(AppBundle* app_bundle) {
34 CORE_LOG(L3, (_T("[AppBundleStateInitialized::Pause][0x%p]"), app_bundle));
35 ASSERT1(app_bundle);
36 ASSERT1(app_bundle->model()->IsLockedByCaller());
37
38 ChangeState(app_bundle, new AppBundleStatePaused);
39 return S_OK;
40 }
41
42 HRESULT AppBundleStateInitialized::Stop(AppBundle* app_bundle) {
43 CORE_LOG(L3, (_T("[AppBundleStateInitialized::Stop][0x%p]"), app_bundle));
44 ASSERT1(app_bundle);
45 ASSERT1(app_bundle->model()->IsLockedByCaller());
46
47 ChangeState(app_bundle, new AppBundleStateStopped);
48 return S_OK;
49 }
50
51 // Remains in this state.
52 HRESULT AppBundleStateInitialized::CreateApp(AppBundle* app_bundle,
53 const CString& app_id,
54 App** app) {
55 CORE_LOG(L3, (_T("[AppBundleStateInitialized::CreateApp][0x%p]"),
56 app_bundle));
57 ASSERT1(app_bundle);
58 ASSERT1(app);
59 ASSERT1(app_bundle->model()->IsLockedByCaller());
60
61 // TODO(omaha): consider enabling this runtime test. Currently, there are
62 // a few unit tests that break this assumption mostly during the setup of
63 // the unit test itself.
64 #if 0
65 if (app_id.CompareNoCase(kGoogleUpdateAppId) == 0) {
66 CORE_LOG(LE, (_T("[Omaha itself can't be created as a new app]")));
67 return E_INVALIDARG;
68 }
69 #endif
70
71 if (has_installed_app_) {
72 CORE_LOG(LE, (_T("[CreateApp][Installed app already in bundle]")));
73 return HandleInvalidStateTransition(app_bundle, _T(__FUNCTION__));
74 }
75
76 GUID app_guid = {0};
77 HRESULT hr = StringToGuidSafe(app_id, &app_guid);
78 if (FAILED(hr)) {
79 CORE_LOG(LE, (_T("[invalid app id][%s]"), app_id));
80 return hr;
81 }
82
83 scoped_ptr<App> local_app(new App(app_guid, false, app_bundle));
84 hr = AddApp(app_bundle, local_app.get());
85 if (FAILED(hr)) {
86 return hr;
87 }
88
89 // When overinstalling, we want the install age for the existing install, so
90 // explicitly get it here. This is the only value read from the registry for
91 // installs.
92 AppManager::Instance()->ReadAppInstallTimeDiff(local_app.get());
93
94 *app = local_app.release();
95 has_new_app_ = true;
96 return S_OK;
97 }
98
99 // Remains in this state.
100 HRESULT AppBundleStateInitialized::CreateInstalledApp(AppBundle* app_bundle,
101 const CString& app_id,
102 App** app) {
103 CORE_LOG(L3, (_T("[AppBundleStateInitialized::CreateInstalledApp][0x%p]"),
104 app_bundle));
105 ASSERT1(app_bundle->model()->IsLockedByCaller());
106
107 if (has_new_app_) {
108 CORE_LOG(LE, (_T("[CreateInstalledApp][New app already in bundle]")));
109 return HandleInvalidStateTransition(app_bundle, _T(__FUNCTION__));
110 }
111
112 // Make sure that the application registration is up to date.
113 HRESULT hr = AppManager::Instance()->RunRegistrationUpdateHook(app_id);
114 if (FAILED(hr)) {
115 CORE_LOG(HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr ? L3 : LW,
116 (_T("[RunRegistrationUpdateHook failed][%s][0x%x]"),
117 app_id, hr));
118 }
119
120 hr = AddInstalledApp(app_bundle, app_id, app);
121 if (FAILED(hr)) {
122 return hr;
123 }
124
125 return S_OK;
126 }
127
128 // Remains in this state.
129 // This function must explicitly check to ensure duplicate apps are not added
130 // because AddInstalledApp errors are ignored. The check for an empty bundle
131 // also covers the has_new_app_ case.
132 HRESULT AppBundleStateInitialized::CreateAllInstalledApps(
133 AppBundle* app_bundle) {
134 CORE_LOG(L3, (_T("[AppBundleStateInitialized::CreateAllInstalledApps][0x%p]"),
135 app_bundle));
136 ASSERT1(app_bundle->model()->IsLockedByCaller());
137
138 if (app_bundle->GetNumberOfApps() > 0) {
139 CORE_LOG(LE, (_T("[CreateAllInstalledApps][Bundle already has apps]")));
140 return HandleInvalidStateTransition(app_bundle, _T(__FUNCTION__));
141 }
142 ASSERT1(!has_new_app_);
143
144 // Make sure the list of installed applications is up to date. This is
145 // primarily important for Google Pack, which supports updating third-party
146 // applications that are not aware of Omaha registration, and hence will not
147 // update the registration during an install or uninstall outside of Pack.
148 AppManager& app_manager = *AppManager::Instance();
149 HRESULT hr = app_manager.RunAllRegistrationUpdateHooks();
150 if (FAILED(hr)) {
151 CORE_LOG(LW, (_T("[RunAllRegistrationUpdateHooks failed][0x%x]"), hr));
152 }
153
154 AppIdVector registered_app_ids;
155 hr = app_manager.GetRegisteredApps(&registered_app_ids);
156 if (FAILED(hr)) {
157 CORE_LOG(LE, (_T("[GetRegisteredApps failed][0x%08x]"), hr));
158 return hr;
159 }
160
161 for (size_t i = 0; i != registered_app_ids.size(); ++i) {
162 const CString& app_id = registered_app_ids[i];
163
164 ASSERT(RegKey::HasKey(app_registry_utils::GetAppClientStateKey(
165 app_bundle->is_machine(), app_id)),
166 (_T("[Clients key without matching ClientState][%s]"), app_id));
167
168 App* app = NULL;
169 HRESULT hr = AddInstalledApp(app_bundle, app_id, &app);
170 if (FAILED(hr)) {
171 CORE_LOG(LW, (_T("[AddInstalledApp failed processing app][%s]"), app_id));
172 }
173 }
174
175 return S_OK;
176 }
177
178 // It is important that the lock is held for the entirety of this and similar
179 // methods with asynchronous callbacks because CompleteAsyncCall() must not be
180 // called before the state has been changed to busy.
181 HRESULT AppBundleStateInitialized::CheckForUpdate(AppBundle* app_bundle) {
182 CORE_LOG(L3, (_T("[AppBundleStateInitialized::CheckForUpdate][0x%p]"),
183 app_bundle));
184 ASSERT1(app_bundle);
185 ASSERT1(app_bundle->model()->IsLockedByCaller());
186 ASSERT1(!IsPendingNonBlockingCall(app_bundle));
187
188 if (app_bundle->GetNumberOfApps() == 0) {
189 CORE_LOG(LE, (_T("[CheckForUpdate][No apps in bundle]")));
190 return HandleInvalidStateTransition(app_bundle, _T(__FUNCTION__));
191 }
192
193 ASSERT1(has_new_app_ != has_installed_app_);
194
195 HRESULT hr = app_bundle->model()->CheckForUpdate(app_bundle);
196 if (FAILED(hr)) {
197 CORE_LOG(LE, (_T("[CheckForUpdates failed][0x%x][0x%p]"), hr, app_bundle));
198 return hr;
199 }
200
201 ChangeState(app_bundle, new AppBundleStateBusy);
202 return S_OK;
203 }
204
205 HRESULT AppBundleStateInitialized::UpdateAllApps(AppBundle* app_bundle) {
206 CORE_LOG(L3, (_T("[AppBundleStateInitialized::UpdateAllApps][0x%p]"),
207 app_bundle));
208 ASSERT1(app_bundle);
209 ASSERT1(app_bundle->model()->IsLockedByCaller());
210 ASSERT1(!IsPendingNonBlockingCall(app_bundle));
211
212 if (app_bundle->GetNumberOfApps() != 0) {
213 CORE_LOG(LE, (_T("[UpdateAllApps][Apps already in bundle]")));
214 return HandleInvalidStateTransition(app_bundle, _T(__FUNCTION__));
215 }
216
217 app_bundle->set_is_auto_update(true);
218
219 HRESULT hr = app_bundle->createAllInstalledApps();
220 if (FAILED(hr)) {
221 return hr;
222 }
223 ASSERT1(app_bundle->GetNumberOfApps() > 0);
224
225 hr = app_bundle->model()->UpdateAllApps(app_bundle);
226 if (FAILED(hr)) {
227 CORE_LOG(LE, (_T("[UpdateAllApps failed][0x%08x][0x%p]"), hr, app_bundle));
228 return hr;
229 }
230
231 ChangeState(app_bundle, new AppBundleStateBusy);
232 return S_OK;
233 }
234
235 HRESULT AppBundleStateInitialized::DownloadPackage(
236 AppBundle* app_bundle,
237 const CString& app_id,
238 const CString& package_name) {
239 CORE_LOG(L3, (_T("[AppBundleStateInitialized::DownloadPackage][0x%p]"),
240 app_bundle));
241 ASSERT1(app_bundle);
242 ASSERT1(app_bundle->model()->IsLockedByCaller());
243
244 if (app_bundle->GetNumberOfApps() == 0 || has_new_app_) {
245 CORE_LOG(LE, (_T("[DownloadPackage][No existing apps in bundle]")));
246 return HandleInvalidStateTransition(app_bundle, _T(__FUNCTION__));
247 }
248
249 return DoDownloadPackage(app_bundle, app_id, package_name);
250 }
251
252 // App is created with is_update=true because using an installed app's
253 // information, including a non-zero version, is an update.
254 HRESULT AppBundleStateInitialized::AddInstalledApp(AppBundle* app_bundle,
255 const CString& app_id,
256 App** app) {
257 ASSERT1(app_bundle);
258 ASSERT1(app);
259 ASSERT1(app_bundle->model()->IsLockedByCaller());
260
261 GUID app_guid = {0};
262 HRESULT hr = StringToGuidSafe(app_id, &app_guid);
263 if (FAILED(hr)) {
264 CORE_LOG(LE, (_T("[invalid app id][%s]"), app_id));
265 return hr;
266 }
267
268 scoped_ptr<App> local_app(new App(app_guid, true, app_bundle));
269
270 hr = AppManager::Instance()->ReadAppPersistentData(local_app.get());
271 if (FAILED(hr)) {
272 CORE_LOG(LE, (_T("[ReadAppPersistentData failed][0x%x][%s]"), hr, app_id));
273 return hr;
274 }
275
276 hr = AddApp(app_bundle, local_app.get());
277 if (FAILED(hr)) {
278 return hr;
279 }
280
281 has_installed_app_ = true;
282 *app = local_app.release();
283 return S_OK;
284 }
285
286 // Fails if the app already exists in the bundle.
287 HRESULT AppBundleStateInitialized::AddApp(AppBundle* app_bundle, App* app) {
288 ASSERT1(app_bundle);
289 ASSERT1(app);
290 ASSERT1(app_bundle->model()->IsLockedByCaller());
291
292 for (size_t i = 0; i != app_bundle->GetNumberOfApps(); ++i) {
293 App* existing_app = app_bundle->GetApp(i);
294 if (::IsEqualGUID(existing_app->app_guid(), app->app_guid())) {
295 CORE_LOG(LE, (_T("[App already in bundle][%s]"), app->app_guid_string()));
296 return GOOPDATE_E_CALL_UNEXPECTED;
297 }
298 }
299
300 AddAppToBundle(app_bundle, app);
301 return S_OK;
302 }
303
304 } // namespace fsm
305
306 } // namespace omaha
OLDNEW
« no previous file with comments | « goopdate/app_bundle_state_initialized.h ('k') | goopdate/app_bundle_state_paused.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698