OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "chrome/installer/setup/chrome_frame_quick_enable.h" | |
6 | |
7 #include <windows.h> | |
8 | |
9 #include "base/files/scoped_temp_dir.h" | |
10 #include "base/logging.h" | |
11 #include "base/strings/string_util.h" | |
12 #include "base/win/registry.h" | |
13 #include "chrome/installer/setup/install_worker.h" | |
14 #include "chrome/installer/util/google_update_constants.h" | |
15 #include "chrome/installer/util/google_update_settings.h" | |
16 #include "chrome/installer/util/install_util.h" | |
17 #include "chrome/installer/util/installation_state.h" | |
18 #include "chrome/installer/util/installer_state.h" | |
19 #include "chrome/installer/util/product.h" | |
20 #include "chrome/installer/util/work_item.h" | |
21 #include "chrome/installer/util/work_item_list.h" | |
22 | |
23 using base::win::RegKey; | |
24 | |
25 namespace installer { | |
26 | |
27 namespace { | |
28 | |
29 InstallStatus CheckQuickEnablePreconditions( | |
30 const InstallationState& machine_state, | |
31 const InstallerState& installer_state) { | |
32 // Make sure Chrome is multi-installed. | |
33 const ProductState* chrome_state = | |
34 machine_state.GetProductState(installer_state.system_install(), | |
35 BrowserDistribution::CHROME_BROWSER); | |
36 if (chrome_state == NULL) { | |
37 LOG(ERROR) << "Chrome Frame quick enable requires Chrome to be installed."; | |
38 return CHROME_NOT_INSTALLED; | |
39 } else if (!chrome_state->is_multi_install()) { | |
40 LOG(ERROR) << "Chrome Frame quick enable requires multi-install of Chrome."; | |
41 return NON_MULTI_INSTALLATION_EXISTS; | |
42 } | |
43 | |
44 // Chrome Frame must not be installed. | |
45 const ProductState* cf_state = | |
46 machine_state.GetProductState(installer_state.system_install(), | |
47 BrowserDistribution::CHROME_FRAME); | |
48 // Make sure we check both user and system installations. | |
49 if (!cf_state) { | |
50 cf_state = machine_state.GetProductState(!installer_state.system_install(), | |
51 BrowserDistribution::CHROME_FRAME); | |
52 } | |
53 | |
54 if (cf_state != NULL) { | |
55 LOG(ERROR) << "Chrome Frame already installed."; | |
56 return installer_state.system_install() ? | |
57 SYSTEM_LEVEL_INSTALL_EXISTS : USER_LEVEL_INSTALL_EXISTS; | |
58 } | |
59 | |
60 return FIRST_INSTALL_SUCCESS; | |
61 } | |
62 | |
63 } // end namespace | |
64 | |
65 InstallStatus ChromeFrameQuickEnable(const InstallationState& machine_state, | |
66 InstallerState* installer_state) { | |
67 DCHECK(installer_state); | |
68 VLOG(1) << "Chrome Frame Quick Enable"; | |
69 InstallStatus status = CheckQuickEnablePreconditions(machine_state, | |
70 *installer_state); | |
71 | |
72 if (status == FIRST_INSTALL_SUCCESS) { | |
73 scoped_ptr<Product> multi_cf(new Product( | |
74 BrowserDistribution::GetSpecificDistribution( | |
75 BrowserDistribution::CHROME_FRAME))); | |
76 multi_cf->SetOption(installer::kOptionMultiInstall, true); | |
77 Product* cf = installer_state->AddProduct(&multi_cf); | |
78 if (!cf) { | |
79 LOG(ERROR) << "AddProduct failed"; | |
80 status = INSTALL_FAILED; | |
81 } else { | |
82 base::ScopedTempDir temp_path; | |
83 if (!temp_path.CreateUniqueTempDir()) { | |
84 PLOG(ERROR) << "Failed to create Temp directory"; | |
85 return INSTALL_FAILED; | |
86 } | |
87 scoped_ptr<WorkItemList> item_list(WorkItem::CreateWorkItemList()); | |
88 const ProductState* chrome_state = | |
89 machine_state.GetProductState(installer_state->system_install(), | |
90 BrowserDistribution::CHROME_BROWSER); | |
91 DCHECK(chrome_state); // Checked in CheckQuickEnablePreconditions. | |
92 | |
93 // Temporarily remove Chrome from the product list. | |
94 // This is so that the operations below do not affect the installation | |
95 // state of Chrome. | |
96 installer_state->RemoveProduct( | |
97 installer_state->FindProduct(BrowserDistribution::CHROME_BROWSER)); | |
98 | |
99 base::FilePath setup_path(chrome_state->GetSetupPath()); | |
100 const Version& new_version = chrome_state->version(); | |
101 | |
102 // This creates the uninstallation entry for GCF. | |
103 AddUninstallShortcutWorkItems(*installer_state, setup_path, new_version, | |
104 *cf, item_list.get()); | |
105 // Always set the "lang" value since quick-enable always happens in the | |
106 // context of an interactive session with a user. | |
107 AddVersionKeyWorkItems(installer_state->root_key(), cf->distribution(), | |
108 new_version, true, item_list.get()); | |
109 | |
110 const Version* opv = chrome_state->old_version(); | |
111 AppendPostInstallTasks(*installer_state, setup_path, opv, | |
112 new_version, temp_path.path(), item_list.get()); | |
113 | |
114 // Before updating the channel values, add Chrome back to the mix so that | |
115 // all multi-installed products' channel values get updated. | |
116 installer_state->AddProductFromState(BrowserDistribution::CHROME_BROWSER, | |
117 *chrome_state); | |
118 AddGoogleUpdateWorkItems(machine_state, *installer_state, | |
119 item_list.get()); | |
120 | |
121 // Add the items to remove the quick-enable-cf command from the registry. | |
122 AddQuickEnableChromeFrameWorkItems( | |
123 *installer_state, machine_state, | |
124 chrome_state->uninstall_command().GetProgram(), | |
125 new_version, | |
126 item_list.get()); | |
127 | |
128 if (!item_list->Do()) { | |
129 item_list->Rollback(); | |
130 status = INSTALL_FAILED; | |
131 } else { | |
132 DCHECK_EQ(FIRST_INSTALL_SUCCESS, status); | |
133 VLOG(1) << "Chrome Frame successfully activated."; | |
134 } | |
135 } | |
136 } | |
137 | |
138 // If quick-enable succeeded, check to see if the EULA has not yet been | |
139 // accepted for the binaries. If this is the case, we must also flip the | |
140 // eulaaccepted bit for them. Otherwise, Google Update would not update | |
141 // Chrome Frame, and that would be bad. Don't flip the EULA bit for Chrome | |
142 // itself, as it will show the EULA on first-run and mark its acceptance | |
143 // accordingly. | |
144 if (!InstallUtil::GetInstallReturnCode(status)) { | |
145 const bool system_level = installer_state->system_install(); | |
146 const ProductState* binaries = | |
147 machine_state.GetProductState(system_level, | |
148 BrowserDistribution::CHROME_BINARIES); | |
149 DCHECK(binaries); | |
150 DWORD eula_accepted; | |
151 | |
152 if (binaries != NULL && | |
153 binaries->GetEulaAccepted(&eula_accepted) && | |
154 eula_accepted == 0 && | |
155 !GoogleUpdateSettings::SetEULAConsent( | |
156 machine_state, | |
157 BrowserDistribution::GetSpecificDistribution( | |
158 BrowserDistribution::CHROME_BINARIES), | |
159 true)) { | |
160 LOG(ERROR) << "Failed to set EULA consent for multi-install binaries."; | |
161 } | |
162 } | |
163 | |
164 return status; | |
165 } | |
166 | |
167 } // namespace installer | |
OLD | NEW |