Explicitly add python-numpy dependency to install-build-deps.
[chromium-blink-merge.git] / chrome / app_installer / win / app_installer_main.cc
blob8c10b7f29353e81582e11b3b7317b1058514846c
1 // Copyright 2014 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.
5 #include <windows.h>
6 #include <initguid.h>
8 #include "base/at_exit.h"
9 #include "base/base_paths.h"
10 #include "base/basictypes.h"
11 #include "base/command_line.h"
12 #include "base/i18n/streaming_utf8_validator.h"
13 #include "base/json/json_reader.h"
14 #include "base/logging.h"
15 #include "base/logging_win.h"
16 #include "base/path_service.h"
17 #include "base/process/launch.h"
18 #include "base/strings/sys_string_conversions.h"
19 #include "base/values.h"
20 #include "chrome/app_installer/win/app_installer_util.h"
21 #include "chrome/common/chrome_switches.h"
22 #include "chrome/common/chrome_version_info.h"
23 #include "chrome/installer/util/util_constants.h"
24 #include "content/public/common/user_agent.h"
26 namespace app_installer {
28 namespace {
30 // Log provider UUID. Required for logging to Sawbuck.
31 // {d82c3b59-bacd-4625-8282-4d570c4dad12}
32 DEFINE_GUID(kAppInstallerLogProvider,
33 0xd82c3b59,
34 0xbacd,
35 0x4625,
36 0x82, 0x82, 0x4d, 0x57, 0x0c, 0x4d, 0xad, 0x12);
38 const wchar_t kChromeServer[] = L"chrome.google.com";
40 const wchar_t kInlineInstallDetail[] = L"/webstore/inlineinstall/detail/";
42 } // namespace
44 extern "C"
45 int WINAPI wWinMain(HINSTANCE instance,
46 HINSTANCE prev_instance,
47 wchar_t* command_line,
48 int show_command) {
49 base::AtExitManager exit_manager;
50 base::CommandLine::Init(0, NULL);
51 logging::LogEventProvider::Initialize(kAppInstallerLogProvider);
52 logging::LoggingSettings settings;
53 settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
54 logging::InitLogging(settings);
56 std::string app_id =
57 base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
58 switches::kAppId);
59 const char* sxs = installer::switches::kChromeSxS;
60 // --chrome-sxs on the command line takes precedence over chrome-sxs in the
61 // tag.
62 bool is_canary = base::CommandLine::ForCurrentProcess()->HasSwitch(sxs);
64 // --app-id on the command line inhibits tag parsing altogether.
65 if (app_id.empty()) {
66 base::FilePath current_exe;
67 if (!PathService::Get(base::FILE_EXE, &current_exe))
68 return COULD_NOT_GET_FILE_PATH;
70 // Get the tag added by dl.google.com. Note that this is passed in via URL
71 // parameters when requesting a file to download, so it must be validated
72 // before use.
73 std::string tag = GetTag(current_exe);
74 if (tag.empty())
75 return COULD_NOT_READ_TAG;
77 DVLOG(1) << "Tag: " << tag;
79 std::map<std::string, std::string> parsed_pairs;
80 if (!ParseTag(tag, &parsed_pairs))
81 return COULD_NOT_PARSE_TAG;
83 auto result = parsed_pairs.find(switches::kAppId);
84 if (result != parsed_pairs.end())
85 app_id = result->second;
87 if (!is_canary) {
88 result = parsed_pairs.find(sxs);
89 is_canary = result != parsed_pairs.end() && result->second == "1";
93 if (!IsValidAppId(app_id))
94 return INVALID_APP_ID;
96 // Get the inline install data for this app. We need to set the user agent
97 // string to be Chrome's, otherwise webstore will serve a different response
98 // (since inline installs don't work on non-Chrome).
99 std::vector<uint8_t> response_data;
100 if (!FetchUrl(base::SysUTF8ToWide(content::BuildUserAgentFromProduct(
101 chrome::VersionInfo().ProductNameAndVersionForUserAgent())),
102 kChromeServer, 0,
103 kInlineInstallDetail + base::SysUTF8ToWide(app_id),
104 &response_data) ||
105 response_data.empty()) {
106 return COULD_NOT_FETCH_INLINE_INSTALL_DATA;
109 // Check that the response is valid UTF-8.
110 std::string inline_install_json(response_data.begin(), response_data.end());
111 if (!base::StreamingUtf8Validator::Validate(inline_install_json))
112 return COULD_NOT_PARSE_INLINE_INSTALL_DATA;
114 // Parse the data to check it's valid JSON. The download page will just eval
115 // it.
116 base::JSONReader json_reader;
117 scoped_ptr<base::Value> inline_install_data(
118 json_reader.ReadToValue(inline_install_json));
119 if (!inline_install_data) {
120 LOG(ERROR) << json_reader.GetErrorMessage();
121 return COULD_NOT_PARSE_INLINE_INSTALL_DATA;
124 base::FilePath chrome_path = GetChromeExePath(is_canary);
125 // If none found, show EULA, download, and install Chrome.
126 if (chrome_path.empty()) {
127 ExitCode get_chrome_result = GetChrome(is_canary, inline_install_json);
128 if (get_chrome_result != SUCCESS)
129 return get_chrome_result;
131 chrome_path = GetChromeExePath(is_canary);
132 if (chrome_path.empty())
133 return COULD_NOT_FIND_CHROME;
136 base::CommandLine cmd(chrome_path);
137 cmd.AppendSwitchASCII(kInstallChromeApp, app_id);
138 DVLOG(1) << "Install command: " << cmd.GetCommandLineString();
139 bool launched = base::LaunchProcess(cmd, base::LaunchOptions(), NULL);
140 DVLOG(1) << "Launch " << (launched ? "success." : "failed.");
142 return SUCCESS;
145 } // namespace app_installer