Commit 675602a8 authored by Mike Dougherty's avatar Mike Dougherty Committed by Commit Bot

[iOS] Add CallJavaScriptFunction API to WebFrame.

Bug: 851636
Cq-Include-Trybots: luci.chromium.try:ios-simulator-full-configs;master.tryserver.chromium.mac:ios-simulator-cronet
Change-Id: I033579043cecd5a122175936255ab237e1ffb709
Reviewed-on: https://chromium-review.googlesource.com/1179091
Commit-Queue: Mike Dougherty <michaeldo@chromium.org>
Reviewed-by: default avatarEugene But <eugenebut@chromium.org>
Cr-Commit-Position: refs/heads/master@{#585557}
parent 0193d4af
......@@ -10,6 +10,10 @@
#include "base/macros.h"
#include "url/gurl.h"
namespace base {
class Value;
}
namespace web {
class WebFrame {
......@@ -22,6 +26,21 @@ class WebFrame {
// The security origin associated with this frame.
virtual GURL GetSecurityOrigin() const = 0;
// Calls the JavaScript function |name| in the frame context. For example, to
// call __gCrWeb.form.trackFormMutations(delay), pass
// 'form.trackFormMutations' as |name| and the value for the delay parameter
// to |parameters|. |name| must point to a function in the __gCrWeb object.
// |parameters| is a vector of values that will be passed to the function.
// This method returns immediately without waiting for the JavaScript
// execution. Calling the function is best effort and it is possible the
// webpage DOM could change in a way which prevents the function from
// executing.
// Returns true if function call was requested, false otherwise. Function call
// may still fail even if this function returns true.
virtual bool CallJavaScriptFunction(
const std::string& name,
const std::vector<base::Value>& parameters) = 0;
virtual ~WebFrame() {}
protected:
......
......@@ -167,6 +167,7 @@ source_set("context_menu") {
source_set("web_frame") {
deps = [
"//base",
"//crypto",
"//ios/web/public",
"//url",
]
......
......@@ -37,6 +37,14 @@ var frameId_ = null;
*/
var frameSymmetricKey_ = null;
/**
* The ID of the last processed message. If a received message has an ID less
* than or equal to |lastReceivedMessageId_|, it will be ignored.
* @type {number}
* @private
*/
var lastReceivedMessageId_ = -1;
/**
* Returns the frameId associated with this frame. A new value will be created
* for this frame the first time it is called. The frameId will persist as long
......@@ -58,6 +66,19 @@ __gCrWeb.frameMessaging['getFrameId'] = function() {
return /** @type {string} */ (frameId_);
};
/**
* Returns whether or not frame messaging is supported for this frame.
* @returns true if frame messaging is supported, false otherwise.
*/
var isFrameMessagingSupported_ = function() {
// - Only secure contexts support the crypto.subtle API.
// - Even though iOS 10 supports window.crypto.webkitSubtle instead of
// window.crypto.subtle, the AES-GCM cipher suite is not supported, so
// support will only be used from the official WebCrypto API.
// TODO(crbug.com/872818): Remove comment once only iOS 11+ is supported.
return window.isSecureContext && typeof window.crypto.subtle === 'object';
}
/**
* Exports |frameSymmetricKey_| as a base64 string. Key will be created if it
* does not already exist.
......@@ -67,23 +88,24 @@ __gCrWeb.frameMessaging['getFrameId'] = function() {
var exportKey_ = function(callback) {
// Early return with an empty key string if encryption is not supported in
// this frame.
// - Insecure contexts do not support the crypto.subtle API.
// - Even though iOS 10 supports window.crypto.webkitSubtle instead of
// window.crypto.subtle, the AES-GCM cipher suite is not supported, so
// support will only be used from the official WebCrypto API.
// TODO(crbug.com/872818): Remove comment once only iOS 11+ is supported.
if (!window.isSecureContext || !window.crypto.subtle) {
if (!isFrameMessagingSupported_()) {
callback("");
return;
}
getFrameSymmetricKey_(function(key) {
window.crypto.subtle.exportKey('raw', key)
.then(function(/** @type {ArrayBuffer} */ k) {
var keyBytes = new Uint8Array(k);
var key64 = btoa(String.fromCharCode.apply(null, keyBytes));
callback(key64);
try {
getFrameSymmetricKey_(function(key) {
window.crypto.subtle.exportKey('raw', key)
.then(function(/** @type {ArrayBuffer} */ k) {
var keyBytes = new Uint8Array(k);
var key64 = btoa(String.fromCharCode.apply(null, keyBytes));
callback(key64);
});
});
});
} catch (error) {
// AES-GCM will not be supported if a web developer overrode
// window.crypto.subtle with window.crypto.webkitSubtle on iOS 10.
callback("");
}
};
/**
......@@ -109,6 +131,110 @@ var getFrameSymmetricKey_ = function(callback) {
});
};
/**
* Executes |functionName| on __gCrWeb with the given |parameters|.
* @param {!string} functionPath The function to execute on __gCrWeb. Components
* may be separated by periods. For example: messaging.function
* @param {!Array} parameters The parameters to pass to |functionName|.
* @return The return value of executing |functionName| or null if it couldn't
* be executed.
*/
var callGCrWebFunction_ = function(functionPath, parameters) {
var functionReference = __gCrWeb;
var functionComponents = functionPath.split('.');
for (var component in functionComponents) {
functionReference = functionReference[component];
if (!functionReference) {
return null;
}
}
return functionReference.apply(null, parameters);
}
/**
* Decrypts and executes the function specified in |payload|.
* @param {!string} payload The encrypted message payload.
* @param {!string} iv The initialization vector used to encrypt the |payload|.
*/
var executeMessage_ = function(payload, iv) {
if (!frameSymmetricKey_) {
// Payload cannot be decrypted without a key. This message could be spam or
// sent by the native application by mistake.
return;
}
// Decode the base64 payload.
var encryptedFunctionArray =
new Uint8Array(Array.from(atob(payload)).map(function(a) {
return a.charCodeAt(0);
}));
// Decode the base64 initialization buffer.
var ivbuf = new Uint8Array(Array.from(atob(iv)).map(function(a) {
return a.charCodeAt(0);
}));
var algorithm = {'name': 'AES-GCM', iv: ivbuf};
getFrameSymmetricKey_(function(frameKey) {
window.crypto.subtle.decrypt(algorithm, frameKey, encryptedFunctionArray)
.then(function(decrypted) {
var callJSON =
String.fromCharCode.apply(null, new Uint8Array(decrypted));
var callDict = JSON.parse(callJSON);
// Verify that message id is valid.
if (!Number.isInteger(callDict['messageId']) ||
callDict['messageId'] <= lastReceivedMessageId_) {
return;
}
lastReceivedMessageId_ = callDict['messageId'];
if (typeof callDict['functionName'] !== 'string' ||
callDict['functionName'].length < 1 ||
!Array.isArray(callDict['parameters'])) {
return;
}
callGCrWebFunction_(callDict['functionName'], callDict['parameters']);
});
});
};
/**
* Routes an encrypted message to the targeted frame. Once the target frame is
* found, the |payload| will be decrypted and executed. This function is called
* by the native code.
* @param {!string} payload The encrypted message payload.
* @param {!string} iv The initialization vector used to encrypt the |payload|.
* @param {!string} target_frame_id The |frameId_| of the frame which should
* process the |payload|.
*/
__gCrWeb.frameMessaging['routeMessage'] =
function(payload, iv, target_frame_id) {
if (!isFrameMessagingSupported_()) {
// API is unsupported.
return;
}
if (target_frame_id === __gCrWeb.frameMessaging['getFrameId']()) {
executeMessage_(payload, iv);
return;
}
var framecount = window.frames.length;
for (var i = 0; i < framecount; i++) {
window.frames[i].postMessage(
{
type: 'org.chromium.encryptedMessage',
payload: payload,
iv: iv,
target_frame_id: target_frame_id
},
'*'
);
}
};
/**
* Creates (or gets the existing) encryption key and sends it to the native
* application.
......@@ -117,7 +243,8 @@ __gCrWeb.frameMessaging['registerFrame'] = function() {
exportKey_(function(frameKey) {
__gCrWeb.common.sendWebKitMessage('FrameBecameAvailable', {
'crwFrameId': __gCrWeb.frameMessaging['getFrameId'](),
'crwFrameKey': frameKey
'crwFrameKey': frameKey,
'crwFrameLastReceivedMessageId': lastReceivedMessageId_
});
});
};
......
......@@ -32,6 +32,17 @@ window.addEventListener('message', function(message) {
if (payload.hasOwnProperty('type') &&
payload.type == 'org.chromium.registerForFrameMessaging') {
__gCrWeb.frameMessaging['getExistingFrames']();
} else if (payload.hasOwnProperty('type') &&
payload.type == 'org.chromium.encryptedMessage') {
if (message.hasOwnProperty('payload') &&
message.hasOwnProperty('iv') &&
message.hasOwnProperty('target_frame_id')) {
__gCrWeb.frameMessaging['routeMessage'](
message['payload'],
message['iv'],
message['target_frame_id']
);
}
}
});
......
......@@ -10,6 +10,7 @@
#include <stddef.h>
#include <cmath>
#include <limits>
#include <memory>
#include <utility>
#include <vector>
......@@ -2454,7 +2455,9 @@ registerLoadRequestForURL:(const GURL&)requestURL
if (_isBeingDestroyed || ![message.body isKindOfClass:[NSDictionary class]] ||
![message.body[@"crwFrameId"] isKindOfClass:[NSString class]] ||
![message.body[@"crwFrameKey"] isKindOfClass:[NSString class]] ||
[message.body[@"crwFrameKey"] length] == 0) {
[message.body[@"crwFrameKey"] length] == 0 ||
![message.body[@"crwFrameLastReceivedMessageId"]
isKindOfClass:[NSNumber class]]) {
// WebController is being destroyed, message is invalid, or frame does not
// have a key.
return;
......@@ -2466,6 +2469,7 @@ registerLoadRequestForURL:(const GURL&)requestURL
std::string frameID = base::SysNSStringToUTF8(message.body[@"crwFrameId"]);
std::string encodedFrameKeyString =
base::SysNSStringToUTF8(message.body[@"crwFrameKey"]);
NSNumber* lastSentMessageID = message.body[@"crwFrameLastReceivedMessageId"];
if (!framesManager->GetFrameWithId(frameID)) {
GURL messageFrameOrigin =
web::GURLOriginWithWKSecurityOrigin(message.frameInfo.securityOrigin);
......@@ -2476,9 +2480,12 @@ registerLoadRequestForURL:(const GURL&)requestURL
crypto::SymmetricKey::Import(crypto::SymmetricKey::Algorithm::AES,
decodedFrameKeyString);
if (frameKey) {
int initialMessageID = lastSentMessageID.intValue == INT_MAX
? 0
: lastSentMessageID.intValue + 1;
auto newFrame = std::make_unique<web::WebFrameImpl>(
frameID, std::move(frameKey), message.frameInfo.mainFrame,
messageFrameOrigin, self.webState);
frameID, std::move(frameKey), initialMessageID,
message.frameInfo.mainFrame, messageFrameOrigin, self.webState);
framesManager->AddFrame(std::move(newFrame));
}
}
......
......@@ -19,8 +19,12 @@ class WebState;
class WebFrameImpl : public WebFrame {
public:
// Creates a new WebFrame. |initial_message_id| will be used as the message ID
// of the next message sent to the frame with the |CallJavaScriptFunction|
// API.
WebFrameImpl(const std::string& frame_id,
std::unique_ptr<crypto::SymmetricKey> frame_key,
int initial_message_id,
bool is_main_frame,
GURL security_origin,
web::WebState* web_state);
......@@ -34,6 +38,10 @@ class WebFrameImpl : public WebFrame {
bool IsMainFrame() const override;
GURL GetSecurityOrigin() const override;
bool CallJavaScriptFunction(
const std::string& name,
const std::vector<base::Value>& parameters) override;
private:
// The frame identifier which uniquely identifies this frame across the
// application's lifetime.
......@@ -41,6 +49,8 @@ class WebFrameImpl : public WebFrame {
// The symmetric encryption key used to encrypt messages addressed to the
// frame. Stored in a base64 encoded string.
std::unique_ptr<crypto::SymmetricKey> frame_key_;
// The message ID of the next JavaScript message to be sent.
int next_message_id_ = 0;
// Whether or not the receiver represents the main frame.
bool is_main_frame_ = false;
// The security origin associated with this frame.
......
......@@ -4,6 +4,14 @@
#include "ios/web/web_state/web_frame_impl.h"
#include "base/base64.h"
#include "base/json/json_writer.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "crypto/aead.h"
#include "crypto/random.h"
#import "ios/web/public/web_state/web_state.h"
#include "url/gurl.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
......@@ -14,11 +22,13 @@ namespace web {
WebFrameImpl::WebFrameImpl(const std::string& frame_id,
std::unique_ptr<crypto::SymmetricKey> frame_key,
int initial_message_id,
bool is_main_frame,
GURL security_origin,
web::WebState* web_state)
: frame_id_(frame_id),
frame_key_(std::move(frame_key)),
next_message_id_(initial_message_id),
is_main_frame_(is_main_frame),
security_origin_(security_origin),
web_state_(web_state) {
......@@ -43,4 +53,44 @@ GURL WebFrameImpl::GetSecurityOrigin() const {
return security_origin_;
}
bool WebFrameImpl::CallJavaScriptFunction(
const std::string& name,
const std::vector<base::Value>& parameters) {
int message_id = next_message_id_;
next_message_id_++;
base::DictionaryValue message;
message.SetKey("messageId", base::Value(message_id));
message.SetKey("functionName", base::Value(name));
base::ListValue parameters_value(parameters);
message.SetKey("parameters", std::move(parameters_value));
std::string json;
base::JSONWriter::Write(message, &json);
crypto::Aead aead(crypto::Aead::AES_256_GCM);
aead.Init(&frame_key_->key());
std::string iv;
crypto::RandBytes(base::WriteInto(&iv, aead.NonceLength() + 1),
aead.NonceLength());
std::string ciphertext;
if (!aead.Seal(json, iv, /*additional_data=*/nullptr, &ciphertext)) {
LOG(ERROR) << "Error sealing message for WebFrame.";
return false;
}
std::string encoded_iv;
base::Base64Encode(iv, &encoded_iv);
std::string encoded_message;
base::Base64Encode(ciphertext, &encoded_message);
std::string script = base::StringPrintf(
"__gCrWeb.frameMessaging.routeMessage('%s', '%s', '%s')",
encoded_message.c_str(), encoded_iv.c_str(), frame_id_.c_str());
GetWebState()->ExecuteJavaScript(base::UTF8ToUTF16(script));
return true;
}
} // namespace web
......@@ -5,8 +5,16 @@
#include "ios/web/web_state/web_frame_impl.h"
#import "base/base64.h"
#include "base/json/json_reader.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#import "base/strings/sys_string_conversions.h"
#include "base/test/ios/wait_util.h"
#include "base/values.h"
#include "crypto/aead.h"
#import "ios/web/public/test/fakes/test_web_state.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/gtest_mac.h"
#include "testing/platform_test.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
......@@ -16,11 +24,10 @@
using crypto::SymmetricKey;
namespace {
const char kFrameId[] = "12345678910ABCDEF12345678910ABCDEF";
const char kFrameId[] = "1effd8f52a067c8d3a01762d3c41dfd8";
// A base64 encoded sample key.
const char kFrameKey[] = "d1uJzdvOFIUT5kEpK4o+x5JCaSlYT/a45ISU7S9EzTo=";
const char kFrameKey[] = "R7lsXtR74c6R9A9k691gUQ8JAd0be+w//Lntgcbjwrc=";
// Returns a key which can be used to create a WebFrame.
std::unique_ptr<SymmetricKey> CreateKey() {
......@@ -30,6 +37,38 @@ std::unique_ptr<SymmetricKey> CreateKey() {
decoded_frame_key_string);
}
struct RouteMessageParameters {
NSString* encoded_function_json = nil;
NSString* encoded_iv = nil;
NSString* frame_id = nil;
};
RouteMessageParameters ParametersFromFunctionCallString(
NSString* function_call) {
NSRange parameters_start = [function_call rangeOfString:@"("];
NSRange parameters_end = [function_call rangeOfString:@")"];
NSString* parameter_string = [function_call
substringWithRange:NSMakeRange(parameters_start.location + 1,
parameters_end.location -
parameters_start.location - 1)];
NSArray* parameters = [parameter_string componentsSeparatedByString:@","];
RouteMessageParameters parsed_params;
if (parameters.count == 3) {
NSMutableCharacterSet* trim_characters_set =
[NSMutableCharacterSet whitespaceCharacterSet];
[trim_characters_set addCharactersInString:@"'"];
parsed_params.encoded_function_json =
[parameters[0] stringByTrimmingCharactersInSet:trim_characters_set];
parsed_params.encoded_iv =
[parameters[1] stringByTrimmingCharactersInSet:trim_characters_set];
parsed_params.frame_id =
[parameters[2] stringByTrimmingCharactersInSet:trim_characters_set];
}
return parsed_params;
}
} // namespace
namespace web {
......@@ -40,8 +79,9 @@ using WebFrameImplTest = PlatformTest;
TEST_F(WebFrameImplTest, CreateWebFrameForMainFrame) {
TestWebState test_web_state;
GURL security_origin;
WebFrameImpl web_frame(kFrameId, CreateKey(), /*is_main_frame=*/true,
security_origin, &test_web_state);
WebFrameImpl web_frame(kFrameId, CreateKey(), /*initial_message_id=*/0,
/*is_main_frame=*/true, security_origin,
&test_web_state);
EXPECT_EQ(&test_web_state, web_frame.GetWebState());
EXPECT_TRUE(web_frame.IsMainFrame());
......@@ -53,8 +93,9 @@ TEST_F(WebFrameImplTest, CreateWebFrameForMainFrame) {
TEST_F(WebFrameImplTest, CreateWebFrameForIFrame) {
TestWebState test_web_state;
GURL security_origin;
WebFrameImpl web_frame(kFrameId, CreateKey(), /*is_main_frame=*/false,
security_origin, &test_web_state);
WebFrameImpl web_frame(kFrameId, CreateKey(), /*initial_message_id=*/0,
/*is_main_frame=*/false, security_origin,
&test_web_state);
EXPECT_EQ(&test_web_state, web_frame.GetWebState());
EXPECT_FALSE(web_frame.IsMainFrame());
......@@ -62,4 +103,138 @@ TEST_F(WebFrameImplTest, CreateWebFrameForIFrame) {
EXPECT_EQ(kFrameId, web_frame.GetFrameId());
}
// Tests that |CallJavaScriptFunction| encrypts the message and passes it to
// __gCrWeb.frameMessaging.routeMessage in the main frame.
TEST_F(WebFrameImplTest, CallJavaScriptFunction) {
TestWebState test_web_state;
GURL security_origin;
WebFrameImpl web_frame(kFrameId, CreateKey(), /*initial_message_id=*/0,
/*is_main_frame=*/false, security_origin,
&test_web_state);
std::vector<base::Value> function_params;
function_params.push_back(base::Value("plaintextParam"));
web_frame.CallJavaScriptFunction("functionName", function_params);
NSString* last_script =
base::SysUTF16ToNSString(test_web_state.GetLastExecutedJavascript());
EXPECT_TRUE([last_script hasPrefix:@"__gCrWeb.frameMessaging.routeMessage"]);
// Verify the message does not contain the plaintext function name or
// parameters.
EXPECT_FALSE([last_script containsString:@"functionName"]);
EXPECT_FALSE([last_script containsString:@"plaintextParam"]);
RouteMessageParameters params = ParametersFromFunctionCallString(last_script);
// Verify that the message is a properly base64 encoded string.
std::string decoded_message;
EXPECT_TRUE(base::Base64Decode(
base::SysNSStringToUTF8(params.encoded_function_json), &decoded_message));
// Verify the message does not contain the plaintext function name or
// parameters.
EXPECT_FALSE([base::SysUTF8ToNSString(decoded_message)
containsString:@"functionName"]);
EXPECT_FALSE([base::SysUTF8ToNSString(decoded_message)
containsString:@"plaintextParam"]);
std::string iv_string = base::SysNSStringToUTF8(params.encoded_iv);
std::string decoded_iv;
// Verify that the initialization vector is a properly base64 encoded string.
EXPECT_TRUE(base::Base64Decode(iv_string, &decoded_iv));
// Ensure the frame ID matches.
EXPECT_NSEQ(base::SysUTF8ToNSString(kFrameId), params.frame_id);
}
// Tests that the WebFrame uses different initialization vectors for two
// sequential calls to |CallJavaScriptFunction|.
TEST_F(WebFrameImplTest, CallJavaScriptFunctionUniqueInitializationVector) {
TestWebState test_web_state;
GURL security_origin;
WebFrameImpl web_frame(kFrameId, CreateKey(), /*initial_message_id=*/0,
/*is_main_frame=*/false, security_origin,
&test_web_state);
std::vector<base::Value> function_params;
function_params.push_back(base::Value("plaintextParam"));
web_frame.CallJavaScriptFunction("functionName", function_params);
NSString* last_script1 =
base::SysUTF16ToNSString(test_web_state.GetLastExecutedJavascript());
RouteMessageParameters params1 =
ParametersFromFunctionCallString(last_script1);
// Call JavaScript Function again to verify that the same initialization
// vector is not reused and that the ciphertext is different.
web_frame.CallJavaScriptFunction("functionName", function_params);
NSString* last_script2 =
base::SysUTF16ToNSString(test_web_state.GetLastExecutedJavascript());
RouteMessageParameters params2 =
ParametersFromFunctionCallString(last_script2);
EXPECT_NSNE(params1.encoded_function_json, params2.encoded_function_json);
EXPECT_NSNE(params1.encoded_iv, params2.encoded_iv);
}
// Tests that the WebFrame properly encodes and encrypts all parameters for
// |CallJavaScriptFunction|.
TEST_F(WebFrameImplTest, CallJavaScriptFunctionMessageProperlyEncoded) {
std::unique_ptr<SymmetricKey> key = CreateKey();
const std::string key_string = key->key();
// Use an arbitrary nonzero message id to ensure it isn't matching a zero
// value by chance.
const int initial_message_id = 11;
TestWebState test_web_state;
GURL security_origin;
WebFrameImpl web_frame(kFrameId, std::move(key), initial_message_id,
/*is_main_frame=*/false, security_origin,
&test_web_state);
std::vector<base::Value> function_params;
std::string plaintext_param("plaintextParam");
function_params.push_back(base::Value(plaintext_param));
web_frame.CallJavaScriptFunction("functionName", function_params);
NSString* last_script =
base::SysUTF16ToNSString(test_web_state.GetLastExecutedJavascript());
RouteMessageParameters params = ParametersFromFunctionCallString(last_script);
std::string decoded_ciphertext;
EXPECT_TRUE(
base::Base64Decode(base::SysNSStringToUTF8(params.encoded_function_json),
&decoded_ciphertext));
std::string decoded_iv;
EXPECT_TRUE(base::Base64Decode(base::SysNSStringToUTF8(params.encoded_iv),
&decoded_iv));
// Decrypt message
crypto::Aead aead(crypto::Aead::AES_256_GCM);
aead.Init(&key_string);
std::string plaintext;
EXPECT_TRUE(aead.Open(decoded_ciphertext, decoded_iv,
/*additional_data=*/nullptr, &plaintext));
std::unique_ptr<base::Value> parsed_result(
base::JSONReader::Read(plaintext, false));
EXPECT_TRUE(parsed_result.get());
base::DictionaryValue* result_dict;
ASSERT_TRUE(parsed_result->GetAsDictionary(&result_dict));
int decrypted_message_id = 0;
EXPECT_TRUE(result_dict->GetInteger("messageId", &decrypted_message_id));
EXPECT_EQ(initial_message_id, decrypted_message_id);
std::string decrypted_functionName;
EXPECT_TRUE(result_dict->GetString("functionName", &decrypted_functionName));
EXPECT_STREQ("functionName", decrypted_functionName.c_str());
base::ListValue* decrypted_parameters;
EXPECT_TRUE(result_dict->GetList("parameters", &decrypted_parameters));
EXPECT_EQ(function_params.size(), decrypted_parameters->GetList().size());
EXPECT_EQ(plaintext_param, decrypted_parameters->GetList()[0].GetString());
}
} // namespace web
......@@ -54,8 +54,8 @@ class WebFramesManagerImplTest : public PlatformTest {
TEST_F(WebFramesManagerImplTest, GetMainWebFrame) {
GURL security_origin;
auto web_frame = std::make_unique<WebFrameImpl>(
"web_frame", CreateKey(), /*is_main_frame=*/true, security_origin,
&test_web_state_);
"web_frame", CreateKey(), /*initial_message_id=*/0,
/*is_main_frame=*/true, security_origin, &test_web_state_);
WebFrameImpl* web_frame_ptr = web_frame.get();
frames_manager_->AddFrame(std::move(web_frame));
......@@ -73,8 +73,8 @@ TEST_F(WebFramesManagerImplTest, NoMainWebFrame) {
GURL security_origin;
const std::string web_frame_frame_id = "web_frame";
auto web_frame = std::make_unique<WebFrameImpl>(
web_frame_frame_id, CreateKey(), /*is_main_frame=*/true, security_origin,
&test_web_state_);
web_frame_frame_id, CreateKey(), /*initial_message_id=*/0,
/*is_main_frame=*/true, security_origin, &test_web_state_);
frames_manager_->AddFrame(std::move(web_frame));
frames_manager_->RemoveFrameWithId(web_frame_frame_id);
......@@ -88,14 +88,14 @@ TEST_F(WebFramesManagerImplTest, NoMainWebFrame) {
TEST_F(WebFramesManagerImplTest, AddFrames) {
GURL security_origin;
auto main_web_frame = std::make_unique<WebFrameImpl>(
"main_web_frame", CreateKey(), /*is_main_frame=*/true, security_origin,
&test_web_state_);
"main_web_frame", CreateKey(), /*initial_message_id=*/0,
/*is_main_frame=*/true, security_origin, &test_web_state_);
WebFrameImpl* main_web_frame_ptr = main_web_frame.get();
frames_manager_->AddFrame(std::move(main_web_frame));
auto child_web_frame = std::make_unique<WebFrameImpl>(
"child_web_frame", CreateKey(), /*is_main_frame=*/false, security_origin,
&test_web_state_);
"child_web_frame", CreateKey(), /*initial_message_id=*/0,
/*is_main_frame=*/false, security_origin, &test_web_state_);
WebFrameImpl* child_web_frame_ptr = child_web_frame.get();
frames_manager_->AddFrame(std::move(child_web_frame));
......@@ -109,20 +109,20 @@ TEST_F(WebFramesManagerImplTest, AddFrames) {
TEST_F(WebFramesManagerImplTest, RemoveFrame) {
GURL security_origin;
auto main_web_frame = std::make_unique<WebFrameImpl>(
"main_web_frame", CreateKey(), /*is_main_frame=*/true, security_origin,
&test_web_state_);
"main_web_frame", CreateKey(), /*initial_message_id=*/0,
/*is_main_frame=*/true, security_origin, &test_web_state_);
WebFrameImpl* main_web_frame_ptr = main_web_frame.get();
frames_manager_->AddFrame(std::move(main_web_frame));
const std::string child_web_frame_1_frame_id = "child_web_frame_1_frame_id";
auto child_web_frame_1 = std::make_unique<WebFrameImpl>(
child_web_frame_1_frame_id, CreateKey(),
child_web_frame_1_frame_id, CreateKey(), /*initial_message_id=*/0,
/*is_main_frame=*/false, security_origin, &test_web_state_);
frames_manager_->AddFrame(std::move(child_web_frame_1));
auto child_web_frame_2 = std::make_unique<WebFrameImpl>(
"child_web_frame_2", CreateKey(), /*is_main_frame=*/false,
security_origin, &test_web_state_);
"child_web_frame_2", CreateKey(), /*initial_message_id=*/0,
/*is_main_frame=*/false, security_origin, &test_web_state_);
WebFrameImpl* child_web_frame_2_ptr = child_web_frame_2.get();
frames_manager_->AddFrame(std::move(child_web_frame_2));
......@@ -138,11 +138,11 @@ TEST_F(WebFramesManagerImplTest, RemoveFrame) {
TEST_F(WebFramesManagerImplTest, RemoveAllFrames) {
GURL security_origin;
frames_manager_->AddFrame(std::make_unique<WebFrameImpl>(
"main_web_frame", CreateKey(), /*is_main_frame=*/true, security_origin,
&test_web_state_));
"main_web_frame", CreateKey(), /*initial_message_id=*/0,
/*is_main_frame=*/true, security_origin, &test_web_state_));
frames_manager_->AddFrame(std::make_unique<WebFrameImpl>(
"web_frame", CreateKey(), /*is_main_frame=*/false, security_origin,
&test_web_state_));
"web_frame", CreateKey(), /*initial_message_id=*/0,
/*is_main_frame=*/false, security_origin, &test_web_state_));
ASSERT_EQ(2ul, frames_manager_->GetAllWebFrames().size());
frames_manager_->RemoveAllWebFrames();
......@@ -156,8 +156,8 @@ TEST_F(WebFramesManagerImplTest, RemoveNonexistantFrame) {
GURL security_origin;
const std::string main_web_frame_frame_id = "main_web_frame";
auto main_web_frame = std::make_unique<WebFrameImpl>(
main_web_frame_frame_id, CreateKey(), /*is_main_frame=*/true,
security_origin, &test_web_state_);
main_web_frame_frame_id, CreateKey(), /*initial_message_id=*/0,
/*is_main_frame=*/true, security_origin, &test_web_state_);
WebFrameImpl* main_web_frame_ptr = main_web_frame.get();
frames_manager_->AddFrame(std::move(main_web_frame));
......@@ -177,8 +177,8 @@ TEST_F(WebFramesManagerImplTest, GetFrameWithId) {
const std::string web_frame_frame_id = "web_frame_frame_id";
auto web_frame = std::make_unique<WebFrameImpl>(
web_frame_frame_id, CreateKey(), /*is_main_frame=*/false, security_origin,
&test_web_state_);
web_frame_frame_id, CreateKey(), /*initial_message_id=*/0,
/*is_main_frame=*/false, security_origin, &test_web_state_);
WebFrameImpl* web_frame_ptr = web_frame.get();
frames_manager_->AddFrame(std::move(web_frame));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment