| Index: components/web_view/frame.cc
|
| diff --git a/components/web_view/frame.cc b/components/web_view/frame.cc
|
| index ad6e818d2b767833eb124fa33c29d49e3123a378..e0ddf37e8ac24cc8dbccf3064b696722c31825ad 100644
|
| --- a/components/web_view/frame.cc
|
| +++ b/components/web_view/frame.cc
|
| @@ -29,6 +29,7 @@ DEFINE_LOCAL_VIEW_PROPERTY_KEY(Frame*, kFrame, nullptr);
|
| namespace {
|
|
|
| const uint32_t kNoParentId = 0u;
|
| +const mojo::ConnectionSpecificId kInvalidConnectionId = 0u;
|
|
|
| FrameDataPtr FrameToFrameData(const Frame* frame) {
|
| FrameDataPtr frame_data(FrameData::New());
|
| @@ -57,6 +58,7 @@ Frame::Frame(FrameTree* tree,
|
| const ClientPropertyMap& client_properties)
|
| : tree_(tree),
|
| view_(nullptr),
|
| + embedded_connection_id_(kInvalidConnectionId),
|
| id_(frame_id),
|
| app_id_(app_id),
|
| parent_(nullptr),
|
| @@ -66,7 +68,7 @@ Frame::Frame(FrameTree* tree,
|
| loading_(false),
|
| progress_(0.f),
|
| client_properties_(client_properties),
|
| - weak_factory_(this),
|
| + embed_weak_ptr_factory_(this),
|
| navigate_weak_ptr_factory_(this) {
|
| if (view)
|
| SetView(view);
|
| @@ -86,7 +88,7 @@ Frame::~Frame() {
|
| }
|
| }
|
|
|
| -void Frame::Init(Frame* parent) {
|
| +void Frame::Init(Frame* parent, mojo::ViewTreeClientPtr view_tree_client) {
|
| {
|
| // Set the FrameTreeClient to null so that we don't notify the client of the
|
| // add before OnConnect().
|
| @@ -96,7 +98,7 @@ void Frame::Init(Frame* parent) {
|
| parent->Add(this);
|
| }
|
|
|
| - InitClient(ClientType::NEW_APP, nullptr);
|
| + InitClient(ClientType::NEW_APP, nullptr, view_tree_client.Pass());
|
| }
|
|
|
| // static
|
| @@ -145,7 +147,16 @@ double Frame::GatherProgress(int* frame_count) const {
|
|
|
| void Frame::InitClient(
|
| ClientType client_type,
|
| - scoped_ptr<FrameTreeServerBinding> frame_tree_server_binding) {
|
| + scoped_ptr<FrameTreeServerBinding> frame_tree_server_binding,
|
| + mojo::ViewTreeClientPtr view_tree_client) {
|
| + if (client_type == ClientType::NEW_APP && view_tree_client.get()) {
|
| + embedded_connection_id_ = kInvalidConnectionId;
|
| + embed_weak_ptr_factory_.InvalidateWeakPtrs();
|
| + view_->Embed(
|
| + view_tree_client.Pass(),
|
| + base::Bind(&Frame::OnEmbedAck, embed_weak_ptr_factory_.GetWeakPtr()));
|
| + }
|
| +
|
| std::vector<const Frame*> frames;
|
| tree_->root()->BuildFrameTree(&frames);
|
|
|
| @@ -199,10 +210,13 @@ void Frame::ChangeClient(FrameTreeClient* frame_tree_client,
|
| progress_ = 0.f;
|
| app_id_ = app_id;
|
|
|
| - if (client_type == ClientType::NEW_APP)
|
| - view_->Embed(view_tree_client.Pass());
|
| + InitClient(client_type, frame_tree_server_binding.Pass(),
|
| + view_tree_client.Pass());
|
| +}
|
|
|
| - InitClient(client_type, frame_tree_server_binding.Pass());
|
| +void Frame::OnEmbedAck(bool success, mojo::ConnectionSpecificId connection_id) {
|
| + if (success)
|
| + embedded_connection_id_ = connection_id;
|
| }
|
|
|
| void Frame::SetView(mojo::View* view) {
|
| @@ -400,7 +414,6 @@ void Frame::OnViewDestroying(mojo::View* view) {
|
| // destructor.
|
| view_ownership_ = ViewOwnership::DOESNT_OWN_VIEW;
|
|
|
| - // TODO(sky): Change browser to create a child for each FrameTree.
|
| if (tree_->root() == this) {
|
| view_->RemoveObserver(this);
|
| view_ = nullptr;
|
| @@ -463,29 +476,33 @@ void Frame::OnCreatedFrame(
|
| uint32_t parent_id,
|
| uint32_t frame_id,
|
| mojo::Map<mojo::String, mojo::Array<uint8_t>> client_properties) {
|
| - // TODO(sky): I need a way to verify the frame_id. Unfortunately the code here
|
| - // doesn't know the connection id of the embedder, so it's not possible to
|
| - // do it.
|
| + if ((frame_id >> 16) != embedded_connection_id_) {
|
| + // TODO(sky): kill connection here?
|
| + // TODO(sky): there is a race in that there is no guarantee we received the
|
| + // connection id before the frame tries to create a new frame. Ideally we
|
| + // could pause the frame until we get the connection id, but bindings don't
|
| + // offer such an API.
|
| + DVLOG(1) << "OnCreatedFrame supplied invalid frame id, expecting"
|
| + << embedded_connection_id_;
|
| + return;
|
| + }
|
|
|
| if (FindFrame(frame_id)) {
|
| // TODO(sky): kill connection here?
|
| - DVLOG(1) << "OnCreatedLocalFrame supplied id of existing frame.";
|
| + DVLOG(1) << "OnCreatedFrame supplied id of existing frame.";
|
| return;
|
| }
|
|
|
| Frame* parent_frame = FindFrameWithIdFromSameApp(parent_id);
|
| if (!parent_frame) {
|
| - DVLOG(1) << "OnCreatedLocalFrame supplied invalid parent_id.";
|
| - return;
|
| - }
|
| -
|
| - if (parent_frame != this && parent_frame->frame_tree_client_) {
|
| - DVLOG(1) << "OnCreatedLocalFrame supplied parent from another connection.";
|
| + DVLOG(1) << "OnCreatedFrame supplied invalid parent_id.";
|
| return;
|
| }
|
|
|
| - tree_->CreateSharedFrame(parent_frame, frame_id, app_id_,
|
| - client_properties.To<ClientPropertyMap>());
|
| + Frame* child_frame =
|
| + tree_->CreateSharedFrame(parent_frame, frame_id, app_id_,
|
| + client_properties.To<ClientPropertyMap>());
|
| + child_frame->embedded_connection_id_ = embedded_connection_id_;
|
| }
|
|
|
| void Frame::RequestNavigate(NavigationTargetType target_type,
|
|
|