- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / installer / setup / chrome_frame_quick_enable.cc
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 (ready-mode doesn't count).
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       !cf_state->uninstall_command().HasSwitch(
56           switches::kChromeFrameReadyMode)) {
57     LOG(ERROR) << "Chrome Frame already installed.";
58     return installer_state.system_install() ?
59         SYSTEM_LEVEL_INSTALL_EXISTS : USER_LEVEL_INSTALL_EXISTS;
60   }
61
62   return FIRST_INSTALL_SUCCESS;
63 }
64
65 }  // end namespace
66
67 InstallStatus ChromeFrameQuickEnable(const InstallationState& machine_state,
68                                      InstallerState* installer_state) {
69   DCHECK(installer_state);
70   VLOG(1) << "Chrome Frame Quick Enable";
71   InstallStatus status = CheckQuickEnablePreconditions(machine_state,
72                                                        *installer_state);
73
74   if (status == FIRST_INSTALL_SUCCESS) {
75     scoped_ptr<Product> multi_cf(new Product(
76         BrowserDistribution::GetSpecificDistribution(
77             BrowserDistribution::CHROME_FRAME)));
78     multi_cf->SetOption(installer::kOptionMultiInstall, true);
79     Product* cf = installer_state->AddProduct(&multi_cf);
80     if (!cf) {
81       LOG(ERROR) << "AddProduct failed";
82       status = INSTALL_FAILED;
83     } else {
84       base::ScopedTempDir temp_path;
85       if (!temp_path.CreateUniqueTempDir()) {
86         PLOG(ERROR) << "Failed to create Temp directory";
87         return INSTALL_FAILED;
88       }
89       scoped_ptr<WorkItemList> item_list(WorkItem::CreateWorkItemList());
90       const ProductState* chrome_state =
91           machine_state.GetProductState(installer_state->system_install(),
92                                         BrowserDistribution::CHROME_BROWSER);
93       DCHECK(chrome_state);  // Checked in CheckQuickEnablePreconditions.
94
95       // Temporarily remove Chrome from the product list.
96       // This is so that the operations below do not affect the installation
97       // state of Chrome.
98       installer_state->RemoveProduct(
99           installer_state->FindProduct(BrowserDistribution::CHROME_BROWSER));
100
101       base::FilePath setup_path(chrome_state->GetSetupPath());
102       const Version& new_version = chrome_state->version();
103
104       // This creates the uninstallation entry for GCF.
105       AddUninstallShortcutWorkItems(*installer_state, setup_path, new_version,
106                                     *cf, item_list.get());
107       // Always set the "lang" value since quick-enable always happens in the
108       // context of an interactive session with a user.
109       AddVersionKeyWorkItems(installer_state->root_key(), cf->distribution(),
110                              new_version, true, item_list.get());
111       AddChromeFrameWorkItems(machine_state, *installer_state, setup_path,
112                               new_version, *cf, item_list.get());
113
114       const Version* opv = chrome_state->old_version();
115       AppendPostInstallTasks(*installer_state, setup_path, opv,
116                              new_version, temp_path.path(), item_list.get());
117
118       // Before updating the channel values, add Chrome back to the mix so that
119       // all multi-installed products' channel values get updated.
120       installer_state->AddProductFromState(BrowserDistribution::CHROME_BROWSER,
121                                            *chrome_state);
122       AddGoogleUpdateWorkItems(machine_state, *installer_state,
123                                item_list.get());
124
125       // Add the items to remove the quick-enable-cf command from the registry.
126       AddQuickEnableChromeFrameWorkItems(
127           *installer_state, machine_state,
128           chrome_state->uninstall_command().GetProgram(),
129           new_version,
130           item_list.get());
131
132       if (!item_list->Do()) {
133         item_list->Rollback();
134         status = INSTALL_FAILED;
135       } else {
136         DCHECK_EQ(FIRST_INSTALL_SUCCESS, status);
137         VLOG(1) << "Chrome Frame successfully activated.";
138       }
139     }
140   }
141
142   // If quick-enable succeeded, check to see if the EULA has not yet been
143   // accepted for the binaries.  If this is the case, we must also flip the
144   // eulaaccepted bit for them.  Otherwise, Google Update would not update
145   // Chrome Frame, and that would be bad.  Don't flip the EULA bit for Chrome
146   // itself, as it will show the EULA on first-run and mark its acceptance
147   // accordingly.
148   if (!InstallUtil::GetInstallReturnCode(status)) {
149     const bool system_level = installer_state->system_install();
150     const ProductState* binaries =
151         machine_state.GetProductState(system_level,
152                                       BrowserDistribution::CHROME_BINARIES);
153     DCHECK(binaries);
154     DWORD eula_accepted;
155
156     if (binaries != NULL &&
157         binaries->GetEulaAccepted(&eula_accepted) &&
158         eula_accepted == 0 &&
159         !GoogleUpdateSettings::SetEULAConsent(
160             machine_state,
161             BrowserDistribution::GetSpecificDistribution(
162                 BrowserDistribution::CHROME_BINARIES),
163             true)) {
164       LOG(ERROR) << "Failed to set EULA consent for multi-install binaries.";
165     }
166   }
167
168   return status;
169 }
170
171 }  // namespace installer