Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/test/chromedriver/capabilities.h" | 5 #include "chrome/test/chromedriver/capabilities.h" |
| 6 | 6 |
| 7 #include <map> | 7 #include <map> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/callback.h" | 10 #include "base/callback.h" |
| 11 #include "base/json/string_escape.h" | |
| 11 #include "base/strings/string_number_conversions.h" | 12 #include "base/strings/string_number_conversions.h" |
| 12 #include "base/strings/string_split.h" | 13 #include "base/strings/string_split.h" |
| 13 #include "base/strings/string_tokenizer.h" | 14 #include "base/strings/string_tokenizer.h" |
| 14 #include "base/strings/string_util.h" | 15 #include "base/strings/string_util.h" |
| 15 #include "base/strings/stringprintf.h" | 16 #include "base/strings/stringprintf.h" |
| 17 #include "base/strings/utf_string_conversions.h" | |
| 16 #include "base/values.h" | 18 #include "base/values.h" |
| 17 #include "chrome/test/chromedriver/chrome/log.h" | 19 #include "chrome/test/chromedriver/chrome/log.h" |
| 18 #include "chrome/test/chromedriver/chrome/status.h" | 20 #include "chrome/test/chromedriver/chrome/status.h" |
| 19 | 21 |
| 20 namespace { | 22 namespace { |
| 21 | 23 |
| 22 typedef base::Callback<Status(const base::Value&, Capabilities*)> Parser; | 24 typedef base::Callback<Status(const base::Value&, Capabilities*)> Parser; |
| 23 | 25 |
| 24 Status ParseBoolean( | 26 Status ParseBoolean( |
| 25 bool* to_set, | 27 bool* to_set, |
| 26 const base::Value& option, | 28 const base::Value& option, |
| 27 Capabilities* capabilities) { | 29 Capabilities* capabilities) { |
| 28 if (!option.GetAsBoolean(to_set)) | 30 if (!option.GetAsBoolean(to_set)) |
| 29 return Status(kUnknownError, "value must be a boolean"); | 31 return Status(kUnknownError, "must be a boolean"); |
| 30 return Status(kOk); | 32 return Status(kOk); |
| 31 } | 33 } |
| 32 | 34 |
| 33 Status ParseString(std::string* to_set, | 35 Status ParseString(std::string* to_set, |
| 34 const base::Value& option, | 36 const base::Value& option, |
| 35 Capabilities* capabilities) { | 37 Capabilities* capabilities) { |
| 36 std::string str; | 38 std::string str; |
| 37 if (!option.GetAsString(&str)) | 39 if (!option.GetAsString(&str)) |
| 38 return Status(kUnknownError, "value must be a string"); | 40 return Status(kUnknownError, "must be a string"); |
| 39 if (str.empty()) | 41 if (str.empty()) |
| 40 return Status(kUnknownError, "value cannot be empty"); | 42 return Status(kUnknownError, "cannot be empty"); |
| 41 *to_set = str; | 43 *to_set = str; |
| 42 return Status(kOk); | 44 return Status(kOk); |
| 43 } | 45 } |
| 44 | 46 |
| 47 Status ParseFilePath(base::FilePath* to_set, | |
| 48 const base::Value& option, | |
| 49 Capabilities* capabilities) { | |
| 50 base::FilePath::StringType str; | |
| 51 if (!option.GetAsString(&str)) | |
| 52 return Status(kUnknownError, "must be a string"); | |
| 53 if (str.empty()) | |
|
chrisgao (Use stgao instead)
2013/08/29 22:53:32
I remember one webdriver client pass empty value f
kkania
2013/08/30 03:14:57
Let's have them fix their side.
| |
| 54 return Status(kUnknownError, "cannot be empty"); | |
| 55 *to_set = base::FilePath(str); | |
| 56 return Status(kOk); | |
| 57 } | |
| 58 | |
| 45 Status IgnoreDeprecatedOption( | 59 Status IgnoreDeprecatedOption( |
| 46 Log* log, | 60 Log* log, |
| 47 const char* option_name, | 61 const char* option_name, |
| 48 const base::Value& option, | 62 const base::Value& option, |
| 49 Capabilities* capabilities) { | 63 Capabilities* capabilities) { |
| 50 log->AddEntry(Log::kWarning, | 64 log->AddEntry(Log::kWarning, |
| 51 base::StringPrintf("deprecated chrome option is ignored: '%s'", | 65 base::StringPrintf("deprecated chrome option is ignored: '%s'", |
| 52 option_name)); | 66 option_name)); |
| 53 return Status(kOk); | 67 return Status(kOk); |
| 54 } | 68 } |
| 55 | 69 |
| 56 Status IgnoreCapability(const base::Value& option, Capabilities* capabilities) { | 70 Status IgnoreCapability(const base::Value& option, Capabilities* capabilities) { |
| 57 return Status(kOk); | 71 return Status(kOk); |
| 58 } | 72 } |
| 59 | 73 |
| 60 Status ParseChromeBinary( | |
| 61 const base::Value& option, | |
| 62 Capabilities* capabilities) { | |
| 63 base::FilePath::StringType path_str; | |
| 64 if (!option.GetAsString(&path_str)) | |
| 65 return Status(kUnknownError, "'binary' must be a string"); | |
| 66 base::FilePath chrome_exe(path_str); | |
| 67 capabilities->command.SetProgram(chrome_exe); | |
| 68 return Status(kOk); | |
| 69 } | |
| 70 | |
| 71 Status ParseLogPath(const base::Value& option, Capabilities* capabilities) { | 74 Status ParseLogPath(const base::Value& option, Capabilities* capabilities) { |
| 72 if (!option.GetAsString(&capabilities->log_path)) | 75 if (!option.GetAsString(&capabilities->log_path)) |
| 73 return Status(kUnknownError, "'logPath' must be a string"); | 76 return Status(kUnknownError, "must be a string"); |
| 74 return Status(kOk); | 77 return Status(kOk); |
| 75 } | 78 } |
| 76 | 79 |
| 77 Status ParseArgs(bool is_android, | 80 Status ParseSwitches(const base::Value& option, |
| 78 const base::Value& option, | 81 Capabilities* capabilities) { |
| 79 Capabilities* capabilities) { | 82 const base::ListValue* switches_list = NULL; |
| 80 const base::ListValue* args_list = NULL; | 83 if (!option.GetAsList(&switches_list)) |
| 81 if (!option.GetAsList(&args_list)) | 84 return Status(kUnknownError, "must be a list"); |
| 82 return Status(kUnknownError, "'args' must be a list"); | 85 for (size_t i = 0; i < switches_list->GetSize(); ++i) { |
| 83 for (size_t i = 0; i < args_list->GetSize(); ++i) { | |
| 84 std::string arg_string; | 86 std::string arg_string; |
| 85 if (!args_list->GetString(i, &arg_string)) | 87 if (!switches_list->GetString(i, &arg_string)) |
| 86 return Status(kUnknownError, "each argument must be a string"); | 88 return Status(kUnknownError, "each argument must be a string"); |
| 87 if (is_android) { | 89 capabilities->switches.SetSwitch(arg_string); |
|
chrisgao (Use stgao instead)
2013/08/29 22:53:32
An arg_string could be "--load-extension=/path/to/
kkania
2013/08/30 03:14:57
Done.
| |
| 88 capabilities->android_args += "--" + arg_string + " "; | |
| 89 } else { | |
| 90 size_t separator_index = arg_string.find("="); | |
| 91 if (separator_index != std::string::npos) { | |
| 92 CommandLine::StringType arg_string_native; | |
| 93 if (!args_list->GetString(i, &arg_string_native)) | |
| 94 return Status(kUnknownError, "each argument must be a string"); | |
| 95 capabilities->command.AppendSwitchNative( | |
| 96 arg_string.substr(0, separator_index), | |
| 97 arg_string_native.substr(separator_index + 1)); | |
| 98 } else { | |
| 99 capabilities->command.AppendSwitch(arg_string); | |
| 100 } | |
| 101 } | |
| 102 } | 90 } |
| 103 return Status(kOk); | 91 return Status(kOk); |
| 104 } | 92 } |
| 105 | 93 |
| 106 Status ParsePrefs(const base::Value& option, Capabilities* capabilities) { | 94 Status ParsePrefs(const base::Value& option, Capabilities* capabilities) { |
| 107 const base::DictionaryValue* prefs = NULL; | 95 const base::DictionaryValue* prefs = NULL; |
| 108 if (!option.GetAsDictionary(&prefs)) | 96 if (!option.GetAsDictionary(&prefs)) |
| 109 return Status(kUnknownError, "'prefs' must be a dictionary"); | 97 return Status(kUnknownError, "must be a dictionary"); |
| 110 capabilities->prefs.reset(prefs->DeepCopy()); | 98 capabilities->prefs.reset(prefs->DeepCopy()); |
| 111 return Status(kOk); | 99 return Status(kOk); |
| 112 } | 100 } |
| 113 | 101 |
| 114 Status ParseLocalState(const base::Value& option, Capabilities* capabilities) { | 102 Status ParseLocalState(const base::Value& option, Capabilities* capabilities) { |
|
chrisgao (Use stgao instead)
2013/08/29 22:53:32
Add a new function ParseDict instead of both Parse
kkania
2013/08/30 03:14:57
Done.
| |
| 115 const base::DictionaryValue* local_state = NULL; | 103 const base::DictionaryValue* local_state = NULL; |
| 116 if (!option.GetAsDictionary(&local_state)) | 104 if (!option.GetAsDictionary(&local_state)) |
| 117 return Status(kUnknownError, "'localState' must be a dictionary"); | 105 return Status(kUnknownError, "must be a dictionary"); |
| 118 capabilities->local_state.reset(local_state->DeepCopy()); | 106 capabilities->local_state.reset(local_state->DeepCopy()); |
| 119 return Status(kOk); | 107 return Status(kOk); |
| 120 } | 108 } |
| 121 | 109 |
| 122 Status ParseExtensions(const base::Value& option, Capabilities* capabilities) { | 110 Status ParseExtensions(const base::Value& option, Capabilities* capabilities) { |
| 123 const base::ListValue* extensions = NULL; | 111 const base::ListValue* extensions = NULL; |
| 124 if (!option.GetAsList(&extensions)) | 112 if (!option.GetAsList(&extensions)) |
| 125 return Status(kUnknownError, "'extensions' must be a list"); | 113 return Status(kUnknownError, "must be a list"); |
| 126 for (size_t i = 0; i < extensions->GetSize(); ++i) { | 114 for (size_t i = 0; i < extensions->GetSize(); ++i) { |
| 127 std::string extension; | 115 std::string extension; |
| 128 if (!extensions->GetString(i, &extension)) { | 116 if (!extensions->GetString(i, &extension)) { |
| 129 return Status(kUnknownError, | 117 return Status(kUnknownError, |
| 130 "each extension must be a base64 encoded string"); | 118 "each extension must be a base64 encoded string"); |
| 131 } | 119 } |
| 132 capabilities->extensions.push_back(extension); | 120 capabilities->extensions.push_back(extension); |
| 133 } | 121 } |
| 134 return Status(kOk); | 122 return Status(kOk); |
| 135 } | 123 } |
| 136 | 124 |
| 137 Status ParseProxy(const base::Value& option, Capabilities* capabilities) { | 125 Status ParseProxy(const base::Value& option, Capabilities* capabilities) { |
| 138 const base::DictionaryValue* proxy_dict; | 126 const base::DictionaryValue* proxy_dict; |
| 139 if (!option.GetAsDictionary(&proxy_dict)) | 127 if (!option.GetAsDictionary(&proxy_dict)) |
| 140 return Status(kUnknownError, "'proxy' must be a dictionary"); | 128 return Status(kUnknownError, "must be a dictionary"); |
| 141 std::string proxy_type; | 129 std::string proxy_type; |
| 142 if (!proxy_dict->GetString("proxyType", &proxy_type)) | 130 if (!proxy_dict->GetString("proxyType", &proxy_type)) |
| 143 return Status(kUnknownError, "'proxyType' must be a string"); | 131 return Status(kUnknownError, "'proxyType' must be a string"); |
| 144 proxy_type = StringToLowerASCII(proxy_type); | 132 proxy_type = StringToLowerASCII(proxy_type); |
| 145 if (proxy_type == "direct") { | 133 if (proxy_type == "direct") { |
| 146 capabilities->command.AppendSwitch("no-proxy-server"); | 134 capabilities->switches.SetSwitch("no-proxy-server"); |
| 147 } else if (proxy_type == "system") { | 135 } else if (proxy_type == "system") { |
| 148 // Chrome default. | 136 // Chrome default. |
| 149 } else if (proxy_type == "pac") { | 137 } else if (proxy_type == "pac") { |
| 150 CommandLine::StringType proxy_pac_url; | 138 CommandLine::StringType proxy_pac_url; |
| 151 if (!proxy_dict->GetString("proxyAutoconfigUrl", &proxy_pac_url)) | 139 if (!proxy_dict->GetString("proxyAutoconfigUrl", &proxy_pac_url)) |
| 152 return Status(kUnknownError, "'proxyAutoconfigUrl' must be a string"); | 140 return Status(kUnknownError, "'proxyAutoconfigUrl' must be a string"); |
| 153 capabilities->command.AppendSwitchNative("proxy-pac-url", proxy_pac_url); | 141 capabilities->switches.SetSwitch("proxy-pac-url", proxy_pac_url); |
| 154 } else if (proxy_type == "autodetect") { | 142 } else if (proxy_type == "autodetect") { |
| 155 capabilities->command.AppendSwitch("proxy-auto-detect"); | 143 capabilities->switches.SetSwitch("proxy-auto-detect"); |
| 156 } else if (proxy_type == "manual") { | 144 } else if (proxy_type == "manual") { |
| 157 const char* proxy_servers_options[][2] = { | 145 const char* proxy_servers_options[][2] = { |
| 158 {"ftpProxy", "ftp"}, {"httpProxy", "http"}, {"sslProxy", "https"}}; | 146 {"ftpProxy", "ftp"}, {"httpProxy", "http"}, {"sslProxy", "https"}}; |
| 159 const base::Value* option_value = NULL; | 147 const base::Value* option_value = NULL; |
| 160 std::string proxy_servers; | 148 std::string proxy_servers; |
| 161 for (size_t i = 0; i < arraysize(proxy_servers_options); ++i) { | 149 for (size_t i = 0; i < arraysize(proxy_servers_options); ++i) { |
| 162 if (!proxy_dict->Get(proxy_servers_options[i][0], &option_value) || | 150 if (!proxy_dict->Get(proxy_servers_options[i][0], &option_value) || |
| 163 option_value->IsType(base::Value::TYPE_NULL)) { | 151 option_value->IsType(base::Value::TYPE_NULL)) { |
| 164 continue; | 152 continue; |
| 165 } | 153 } |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 184 if (!option_value->GetAsString(&proxy_bypass_list)) | 172 if (!option_value->GetAsString(&proxy_bypass_list)) |
| 185 return Status(kUnknownError, "'noProxy' must be a string"); | 173 return Status(kUnknownError, "'noProxy' must be a string"); |
| 186 } | 174 } |
| 187 | 175 |
| 188 if (proxy_servers.empty() && proxy_bypass_list.empty()) { | 176 if (proxy_servers.empty() && proxy_bypass_list.empty()) { |
| 189 return Status(kUnknownError, | 177 return Status(kUnknownError, |
| 190 "proxyType is 'manual' but no manual " | 178 "proxyType is 'manual' but no manual " |
| 191 "proxy capabilities were found"); | 179 "proxy capabilities were found"); |
| 192 } | 180 } |
| 193 if (!proxy_servers.empty()) | 181 if (!proxy_servers.empty()) |
| 194 capabilities->command.AppendSwitchASCII("proxy-server", proxy_servers); | 182 capabilities->switches.SetSwitch("proxy-server", proxy_servers); |
| 195 if (!proxy_bypass_list.empty()) { | 183 if (!proxy_bypass_list.empty()) { |
| 196 capabilities->command.AppendSwitchASCII("proxy-bypass-list", | 184 capabilities->switches.SetSwitch("proxy-bypass-list", |
| 197 proxy_bypass_list); | 185 proxy_bypass_list); |
| 198 } | 186 } |
| 199 } else { | 187 } else { |
| 200 return Status(kUnknownError, "unrecognized proxy type:" + proxy_type); | 188 return Status(kUnknownError, "unrecognized proxy type:" + proxy_type); |
| 201 } | 189 } |
| 202 return Status(kOk); | 190 return Status(kOk); |
| 203 } | 191 } |
| 204 | 192 |
| 205 Status ParseExcludeSwitches(const base::Value& option, | 193 Status ParseExcludeSwitches(const base::Value& option, |
| 206 Capabilities* capabilities) { | 194 Capabilities* capabilities) { |
| 207 const base::ListValue* switches = NULL; | 195 const base::ListValue* switches = NULL; |
| 208 if (!option.GetAsList(&switches)) | 196 if (!option.GetAsList(&switches)) |
| 209 return Status(kUnknownError, "'excludeSwitches' must be a list"); | 197 return Status(kUnknownError, "must be a list"); |
| 210 for (size_t i = 0; i < switches->GetSize(); ++i) { | 198 for (size_t i = 0; i < switches->GetSize(); ++i) { |
| 211 std::string switch_name; | 199 std::string switch_name; |
| 212 if (!switches->GetString(i, &switch_name)) { | 200 if (!switches->GetString(i, &switch_name)) { |
| 213 return Status(kUnknownError, | 201 return Status(kUnknownError, |
| 214 "each switch to be removed must be a string"); | 202 "each switch to be removed must be a string"); |
| 215 } | 203 } |
| 216 capabilities->exclude_switches.insert(switch_name); | 204 capabilities->exclude_switches.insert(switch_name); |
| 217 } | 205 } |
| 218 return Status(kOk); | 206 return Status(kOk); |
| 219 } | 207 } |
| 220 | 208 |
| 221 Status ParseUseExistingBrowser(const base::Value& option, | 209 Status ParseUseExistingBrowser(const base::Value& option, |
| 222 Capabilities* capabilities) { | 210 Capabilities* capabilities) { |
| 223 std::string server_addr; | 211 std::string server_addr; |
| 224 if (!option.GetAsString(&server_addr)) | 212 if (!option.GetAsString(&server_addr)) |
| 225 return Status(kUnknownError, "must be 'host:port'"); | 213 return Status(kUnknownError, "must be 'host:port'"); |
| 226 | 214 |
| 227 std::vector<std::string> values; | 215 std::vector<std::string> values; |
| 228 base::SplitString(server_addr, ':', &values); | 216 base::SplitString(server_addr, ':', &values); |
| 229 if (values.size() != 2) | 217 if (values.size() != 2) |
| 230 return Status(kUnknownError, "must be 'host:port'"); | 218 return Status(kUnknownError, "must be 'host:port'"); |
| 231 | 219 |
| 232 // Ignoring host input for now, hardcoding to 127.0.0.1. | 220 // Ignoring host input for now, hardcoding to 127.0.0.1. |
| 233 base::StringToInt(values[1], &capabilities->existing_browser_port); | 221 base::StringToInt(values[1], &capabilities->existing_browser_port); |
| 234 if (capabilities->existing_browser_port <= 0) | 222 if (capabilities->existing_browser_port <= 0) |
| 235 return Status(kUnknownError, "port must be >= 0"); | 223 return Status(kUnknownError, "port must be >= 0"); |
|
chrisgao (Use stgao instead)
2013/08/29 22:53:32
">=" to ">"
kkania
2013/08/30 03:14:57
Done.
| |
| 236 return Status(kOk); | 224 return Status(kOk); |
| 237 } | 225 } |
| 238 | 226 |
| 239 Status ParseLoggingPrefs(const base::Value& option, | 227 Status ParseLoggingPrefs(const base::Value& option, |
| 240 Capabilities* capabilities) { | 228 Capabilities* capabilities) { |
| 241 const base::DictionaryValue* logging_prefs_dict = NULL; | 229 const base::DictionaryValue* logging_prefs_dict = NULL; |
| 242 if (!option.GetAsDictionary(&logging_prefs_dict)) | 230 if (!option.GetAsDictionary(&logging_prefs_dict)) |
| 243 return Status(kUnknownError, "'loggingPrefs' must be a dictionary"); | 231 return Status(kUnknownError, "must be a dictionary"); |
| 244 | 232 |
| 245 // TODO(klm): verify log types. | 233 // TODO(klm): verify log types. |
| 246 // TODO(klm): verify log levels. | 234 // TODO(klm): verify log levels. |
| 247 capabilities->logging_prefs.reset(logging_prefs_dict->DeepCopy()); | 235 capabilities->logging_prefs.reset(logging_prefs_dict->DeepCopy()); |
| 248 return Status(kOk); | 236 return Status(kOk); |
| 249 } | 237 } |
| 250 | 238 |
| 251 Status ParseChromeOptions( | 239 Status ParseChromeOptions( |
| 252 Log* log, | 240 Log* log, |
| 253 const base::Value& capability, | 241 const base::Value& capability, |
| 254 Capabilities* capabilities) { | 242 Capabilities* capabilities) { |
| 255 const base::DictionaryValue* chrome_options = NULL; | 243 const base::DictionaryValue* chrome_options = NULL; |
| 256 if (!capability.GetAsDictionary(&chrome_options)) | 244 if (!capability.GetAsDictionary(&chrome_options)) |
| 257 return Status(kUnknownError, "'chromeOptions' must be a dictionary"); | 245 return Status(kUnknownError, "must be a dictionary"); |
| 258 | 246 |
| 259 bool is_android = chrome_options->HasKey("androidPackage"); | 247 bool is_android = chrome_options->HasKey("androidPackage"); |
| 260 bool is_existing = chrome_options->HasKey("useExistingBrowser"); | 248 bool is_existing = chrome_options->HasKey("useExistingBrowser"); |
| 261 | 249 |
| 262 std::map<std::string, Parser> parser_map; | 250 std::map<std::string, Parser> parser_map; |
| 263 // Ignore 'binary' and 'extensions' capability, since the Java client | 251 // Ignore 'args', 'binary' and 'extensions' capabilities by default, since the |
| 264 // always passes them. | 252 // Java client always passes them. |
| 253 parser_map["args"] = base::Bind(&IgnoreCapability); | |
| 265 parser_map["binary"] = base::Bind(&IgnoreCapability); | 254 parser_map["binary"] = base::Bind(&IgnoreCapability); |
| 266 parser_map["extensions"] = base::Bind(&IgnoreCapability); | 255 parser_map["extensions"] = base::Bind(&IgnoreCapability); |
|
chrisgao (Use stgao instead)
2013/08/29 22:53:32
This function is for chromeOptions.*
But args, bin
kkania
2013/08/30 03:14:57
talked offline
| |
| 267 if (is_android) { | 256 if (is_android) { |
| 268 parser_map["androidActivity"] = | 257 parser_map["androidActivity"] = |
| 269 base::Bind(&ParseString, &capabilities->android_activity); | 258 base::Bind(&ParseString, &capabilities->android_activity); |
| 270 parser_map["androidDeviceSerial"] = | 259 parser_map["androidDeviceSerial"] = |
| 271 base::Bind(&ParseString, &capabilities->android_device_serial); | 260 base::Bind(&ParseString, &capabilities->android_device_serial); |
| 272 parser_map["androidPackage"] = | 261 parser_map["androidPackage"] = |
| 273 base::Bind(&ParseString, &capabilities->android_package); | 262 base::Bind(&ParseString, &capabilities->android_package); |
| 274 parser_map["androidProcess"] = | 263 parser_map["androidProcess"] = |
| 275 base::Bind(&ParseString, &capabilities->android_process); | 264 base::Bind(&ParseString, &capabilities->android_process); |
| 276 parser_map["args"] = base::Bind(&ParseArgs, true); | 265 parser_map["args"] = base::Bind(&ParseSwitches); |
| 266 parser_map["switches"] = base::Bind(&ParseSwitches); | |
| 277 } else if (is_existing) { | 267 } else if (is_existing) { |
| 278 parser_map["args"] = base::Bind(&IgnoreCapability); | |
| 279 parser_map["useExistingBrowser"] = base::Bind(&ParseUseExistingBrowser); | 268 parser_map["useExistingBrowser"] = base::Bind(&ParseUseExistingBrowser); |
|
chrisgao (Use stgao instead)
2013/08/29 22:53:32
not "debugger_address"?
kkania
2013/08/30 03:14:57
Done.
| |
| 280 } else { | 269 } else { |
| 281 parser_map["forceDevToolsScreenshot"] = base::Bind( | 270 parser_map["args"] = base::Bind(&ParseSwitches); |
| 282 &ParseBoolean, &capabilities->force_devtools_screenshot); | 271 parser_map["binary"] = base::Bind(&ParseFilePath, &capabilities->binary); |
| 283 parser_map["args"] = base::Bind(&ParseArgs, false); | |
| 284 parser_map["binary"] = base::Bind(&ParseChromeBinary); | |
| 285 parser_map["detach"] = base::Bind(&ParseBoolean, &capabilities->detach); | 272 parser_map["detach"] = base::Bind(&ParseBoolean, &capabilities->detach); |
| 286 parser_map["excludeSwitches"] = base::Bind(&ParseExcludeSwitches); | 273 parser_map["excludeSwitches"] = base::Bind(&ParseExcludeSwitches); |
| 287 parser_map["extensions"] = base::Bind(&ParseExtensions); | 274 parser_map["extensions"] = base::Bind(&ParseExtensions); |
| 275 parser_map["forceDevToolsScreenshot"] = base::Bind( | |
| 276 &ParseBoolean, &capabilities->force_devtools_screenshot); | |
| 288 parser_map["loadAsync"] = | 277 parser_map["loadAsync"] = |
| 289 base::Bind(&IgnoreDeprecatedOption, log, "loadAsync"); | 278 base::Bind(&IgnoreDeprecatedOption, log, "loadAsync"); |
| 290 parser_map["localState"] = base::Bind(&ParseLocalState); | 279 parser_map["localState"] = base::Bind(&ParseLocalState); |
| 291 parser_map["logPath"] = base::Bind(&ParseLogPath); | 280 parser_map["logPath"] = base::Bind(&ParseLogPath); |
| 292 parser_map["prefs"] = base::Bind(&ParsePrefs); | 281 parser_map["prefs"] = base::Bind(&ParsePrefs); |
| 282 parser_map["switches"] = base::Bind(&ParseSwitches); | |
|
chrisgao (Use stgao instead)
2013/08/29 22:53:32
What's this new "switches" for? Equivalent to "arg
kkania
2013/08/30 03:14:57
It's a synonym for args. Deleted.
| |
| 293 } | 283 } |
| 294 | 284 |
| 295 for (base::DictionaryValue::Iterator it(*chrome_options); !it.IsAtEnd(); | 285 for (base::DictionaryValue::Iterator it(*chrome_options); !it.IsAtEnd(); |
| 296 it.Advance()) { | 286 it.Advance()) { |
| 297 if (parser_map.find(it.key()) == parser_map.end()) { | 287 if (parser_map.find(it.key()) == parser_map.end()) { |
| 298 return Status(kUnknownError, | 288 return Status(kUnknownError, |
| 299 "unrecognized chrome option: " + it.key()); | 289 "unrecognized chrome option: " + it.key()); |
| 300 } | 290 } |
| 301 Status status = parser_map[it.key()].Run(it.value(), capabilities); | 291 Status status = parser_map[it.key()].Run(it.value(), capabilities); |
| 302 if (status.IsError()) | 292 if (status.IsError()) |
| 303 return Status(kUnknownError, "cannot parse " + it.key(), status); | 293 return Status(kUnknownError, "cannot parse " + it.key(), status); |
| 304 } | 294 } |
| 305 return Status(kOk); | 295 return Status(kOk); |
| 306 } | 296 } |
| 307 | 297 |
| 308 } // namespace | 298 } // namespace |
| 309 | 299 |
| 300 Switches::Switches() {} | |
| 301 | |
| 302 Switches::~Switches() {} | |
| 303 | |
| 304 void Switches::SetSwitch(const std::string& name) { | |
| 305 SetSwitch(name, NativeString()); | |
| 306 } | |
| 307 | |
| 308 void Switches::SetSwitch(const std::string& name, const std::string& value) { | |
| 309 #if defined(OS_WIN) | |
| 310 SetSwitch(name, UTF8ToUTF16(value)); | |
| 311 #else | |
| 312 switch_map_[name] = value; | |
| 313 #endif | |
| 314 } | |
| 315 | |
| 316 void Switches::SetSwitch(const std::string& name, const string16& value) { | |
| 317 #if defined(OS_WIN) | |
| 318 switch_map_[name] = value; | |
| 319 #else | |
| 320 SetSwitch(name, UTF16ToUTF8(value)); | |
| 321 #endif | |
| 322 } | |
| 323 | |
| 324 void Switches::SetSwitch(const std::string& name, const base::FilePath& value) { | |
| 325 SetSwitch(name, value.value()); | |
| 326 } | |
| 327 | |
| 328 void Switches::SetUnparsedSwitch(const std::string& unparsed_switch) { | |
| 329 std::string value; | |
| 330 size_t equals_index = unparsed_switch.find('='); | |
| 331 if (equals_index != std::string::npos) | |
| 332 value = unparsed_switch.substr(equals_index + 1); | |
| 333 | |
| 334 std::string name; | |
| 335 size_t start_index = 0; | |
| 336 if (unparsed_switch.substr(0, 2) == "--") | |
| 337 start_index = 2; | |
| 338 name = unparsed_switch.substr(start_index, equals_index - start_index); | |
| 339 | |
| 340 SetSwitch(name, value); | |
| 341 } | |
| 342 | |
| 343 bool Switches::HasSwitch(const std::string& name) const { | |
| 344 return switch_map_.count(name) > 0; | |
| 345 } | |
| 346 | |
| 347 std::string Switches::GetSwitchValue(const std::string& name) const { | |
| 348 NativeString value = GetSwitchValueNative(name); | |
| 349 #if defined(OS_WIN) | |
| 350 return UTF16ToUTF8(value); | |
| 351 #else | |
| 352 return value; | |
| 353 #endif | |
| 354 } | |
| 355 | |
| 356 Switches::NativeString Switches::GetSwitchValueNative( | |
| 357 const std::string& name) const { | |
| 358 SwitchMap::const_iterator iter = switch_map_.find(name); | |
| 359 if (iter == switch_map_.end()) | |
| 360 return NativeString(); | |
| 361 return iter->second; | |
| 362 } | |
| 363 | |
| 364 size_t Switches::GetSize() const { | |
| 365 return switch_map_.size(); | |
| 366 } | |
| 367 | |
| 368 void Switches::AppendToCommandLine(CommandLine* command) const { | |
| 369 for (SwitchMap::const_iterator iter = switch_map_.begin(); | |
| 370 iter != switch_map_.end(); | |
| 371 ++iter) { | |
| 372 command->AppendSwitchNative(iter->first, iter->second); | |
| 373 } | |
| 374 } | |
| 375 | |
| 376 std::string Switches::ToString() const { | |
| 377 std::string str; | |
| 378 SwitchMap::const_iterator iter = switch_map_.begin(); | |
| 379 while (iter != switch_map_.end()) { | |
| 380 str += "--" + iter->first; | |
| 381 std::string value = GetSwitchValue(iter->first); | |
| 382 if (value.length()) { | |
| 383 if (value.find(' ') != std::string::npos) | |
| 384 value = base::GetDoubleQuotedJson(value); | |
| 385 str += "=" + value; | |
| 386 } | |
| 387 ++iter; | |
| 388 if (iter == switch_map_.end()) | |
| 389 break; | |
| 390 str += " "; | |
| 391 } | |
| 392 return str; | |
| 393 } | |
| 394 | |
| 310 Capabilities::Capabilities() | 395 Capabilities::Capabilities() |
| 311 : force_devtools_screenshot(false), | 396 : force_devtools_screenshot(false), |
| 312 detach(false), | 397 detach(false), |
| 313 existing_browser_port(0), | 398 existing_browser_port(0) {} |
| 314 command(CommandLine::NO_PROGRAM) {} | |
| 315 | 399 |
| 316 Capabilities::~Capabilities() {} | 400 Capabilities::~Capabilities() {} |
| 317 | 401 |
| 318 bool Capabilities::IsAndroid() const { | 402 bool Capabilities::IsAndroid() const { |
| 319 return !android_package.empty(); | 403 return !android_package.empty(); |
| 320 } | 404 } |
| 321 | 405 |
| 322 bool Capabilities::IsExistingBrowser() const { | 406 bool Capabilities::IsExistingBrowser() const { |
| 323 return existing_browser_port > 0; | 407 return existing_browser_port > 0; |
| 324 } | 408 } |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 336 if (desired_caps.Get(it->first, &capability)) { | 420 if (desired_caps.Get(it->first, &capability)) { |
| 337 Status status = it->second.Run(*capability, this); | 421 Status status = it->second.Run(*capability, this); |
| 338 if (status.IsError()) { | 422 if (status.IsError()) { |
| 339 return Status( | 423 return Status( |
| 340 kUnknownError, "cannot parse capability: " + it->first, status); | 424 kUnknownError, "cannot parse capability: " + it->first, status); |
| 341 } | 425 } |
| 342 } | 426 } |
| 343 } | 427 } |
| 344 return Status(kOk); | 428 return Status(kOk); |
| 345 } | 429 } |
| OLD | NEW |