ozone: evdev: Sync caps lock LED state to evdev
[chromium-blink-merge.git] / chrome / app_installer / win / app_installer_main.cc
blob3266f9dde35bc96ab67404f92a738c4ace1f7b66
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/launcher_support/chrome_launcher_support.h"
24 #include "chrome/installer/util/util_constants.h"
25 #include "content/public/common/user_agent.h"
27 namespace app_installer {
29 namespace {
31 // Log provider UUID. Required for logging to Sawbuck.
32 // {d82c3b59-bacd-4625-8282-4d570c4dad12}
33 DEFINE_GUID(kAppInstallerLogProvider,
34 0xd82c3b59,
35 0xbacd,
36 0x4625,
37 0x82, 0x82, 0x4d, 0x57, 0x0c, 0x4d, 0xad, 0x12);
39 const wchar_t kChromeServer[] = L"chrome.google.com";
41 const wchar_t kInlineInstallDetail[] = L"/webstore/inlineinstall/detail/";
43 } // namespace
45 extern "C"
46 int WINAPI wWinMain(HINSTANCE instance,
47 HINSTANCE prev_instance,
48 wchar_t* command_line,
49 int show_command) {
50 base::AtExitManager exit_manager;
51 base::CommandLine::Init(0, NULL);
52 logging::LogEventProvider::Initialize(kAppInstallerLogProvider);
53 logging::LoggingSettings settings;
54 settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
55 logging::InitLogging(settings);
57 std::string app_id =
58 base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
59 switches::kAppId);
60 const char* sxs = installer::switches::kChromeSxS;
61 // --chrome-sxs on the command line takes precedence over chrome-sxs in the
62 // tag.
63 bool is_canary = base::CommandLine::ForCurrentProcess()->HasSwitch(sxs);
65 // --app-id on the command line inhibits tag parsing altogether.
66 if (app_id.empty()) {
67 base::FilePath current_exe;
68 if (!PathService::Get(base::FILE_EXE, &current_exe))
69 return COULD_NOT_GET_FILE_PATH;
71 // Get the tag added by dl.google.com. Note that this is passed in via URL
72 // parameters when requesting a file to download, so it must be validated
73 // before use.
74 std::string tag = GetTag(current_exe);
75 if (tag.empty())
76 return COULD_NOT_READ_TAG;
78 DVLOG(1) << "Tag: " << tag;
80 std::map<std::string, std::string> parsed_pairs;
81 if (!ParseTag(tag, &parsed_pairs))
82 return COULD_NOT_PARSE_TAG;
84 auto result = parsed_pairs.find(switches::kAppId);
85 if (result != parsed_pairs.end())
86 app_id = result->second;
88 if (!is_canary) {
89 result = parsed_pairs.find(sxs);
90 is_canary = result != parsed_pairs.end() && result->second == "1";
94 if (!IsValidAppId(app_id))
95 return INVALID_APP_ID;
97 // Get the inline install data for this app. We need to set the user agent
98 // string to be Chrome's, otherwise webstore will serve a different response
99 // (since inline installs don't work on non-Chrome).
100 std::vector<uint8_t> response_data;
101 if (!FetchUrl(base::SysUTF8ToWide(content::BuildUserAgentFromProduct(
102 chrome::VersionInfo().ProductNameAndVersionForUserAgent())),
103 kChromeServer, 0,
104 kInlineInstallDetail + base::SysUTF8ToWide(app_id),
105 &response_data) ||
106 response_data.empty()) {
107 return COULD_NOT_FETCH_INLINE_INSTALL_DATA;
110 // Check that the response is valid UTF-8.
111 std::string inline_install_json(response_data.begin(), response_data.end());
112 if (!base::StreamingUtf8Validator::Validate(inline_install_json))
113 return COULD_NOT_PARSE_INLINE_INSTALL_DATA;
115 // Parse the data to check it's valid JSON. The download page will just eval
116 // it.
117 base::JSONReader json_reader;
118 scoped_ptr<base::Value> inline_install_data(
119 json_reader.ReadToValue(inline_install_json));
120 if (!inline_install_data) {
121 LOG(ERROR) << json_reader.GetErrorMessage();
122 return COULD_NOT_PARSE_INLINE_INSTALL_DATA;
125 base::FilePath chrome_path =
126 chrome_launcher_support::GetAnyChromePath(is_canary);
127 // If none found, show EULA, download, and install Chrome.
128 if (chrome_path.empty()) {
129 ExitCode get_chrome_result = GetChrome(is_canary, inline_install_json);
130 if (get_chrome_result != SUCCESS)
131 return get_chrome_result;
133 chrome_path = chrome_launcher_support::GetAnyChromePath(is_canary);
134 if (chrome_path.empty())
135 return COULD_NOT_FIND_CHROME;
138 base::CommandLine cmd(chrome_path);
139 cmd.AppendSwitchASCII(kInstallChromeApp, app_id);
140 DVLOG(1) << "Install command: " << cmd.GetCommandLineString();
141 bool launched = base::LaunchProcess(cmd, base::LaunchOptions()).IsValid();
142 DVLOG(1) << "Launch " << (launched ? "success." : "failed.");
144 return SUCCESS;
147 } // namespace app_installer