#include "content/renderer/java/gin_java_bridge_dispatcher.h"
#include <utility>
#include "base/auto_reset.h"
#include "base/containers/contains.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "content/public/common/content_features.h"
#include "content/public/renderer/render_frame.h"
#include "content/renderer/java/gin_java_bridge_object.h"
#include "net/base/scheme_host_port_matcher.h"
#include "third_party/blink/public/platform/browser_interface_broker_proxy.h"
#include "third_party/blink/public/web/web_local_frame.h"
#include "third_party/blink/public/web/web_view.h"
#include "url/origin.h"
namespace content {
GinJavaBridgeDispatcher::GinJavaBridgeDispatcher(RenderFrame* render_frame)
: RenderFrameObserver(render_frame) {}
GinJavaBridgeDispatcher::~GinJavaBridgeDispatcher() = default;
void GinJavaBridgeDispatcher::DidClearWindowObject() {
if (inside_did_clear_window_object_)
return;
base::AutoReset<bool> flag_entry(&inside_did_clear_window_object_, true);
if (!named_objects_.empty()) {
CHECK(remote_);
}
for (NamedObjectMap::const_iterator iter = named_objects_.begin();
iter != named_objects_.end(); ++iter) {
if (objects_.Lookup(iter->second.object_id)) {
objects_.Remove(iter->second.object_id);
}
url::Origin security_origin = url::Origin(
render_frame()->GetWebFrame()->GetDocument().GetSecurityOrigin());
bool should_inject =
iter->second.matcher.Includes(security_origin.GetURL());
if (should_inject) {
GinJavaBridgeObject* object = GinJavaBridgeObject::InjectNamed(
render_frame()->GetWebFrame(), weak_ptr_factory_.GetWeakPtr(),
iter->first, iter->second.object_id);
if (object) {
objects_.AddWithID(object, iter->second.object_id);
} else {
GetRemoteObjectHost()->ObjectWrapperDeleted(iter->second.object_id);
}
}
}
}
void GinJavaBridgeDispatcher::AddNamedObject(const std::string& name,
ObjectID object_id,
const std::string& matcher) {
CHECK(remote_);
named_objects_.insert(std::make_pair(
name, NamedObject{object_id,
net::SchemeHostPortMatcher::FromRawString(matcher)}));
}
void GinJavaBridgeDispatcher::RemoveNamedObject(const std::string& name) {
DCHECK(base::Contains(named_objects_, name));
named_objects_.erase(name);
}
void GinJavaBridgeDispatcher::SetHost(
mojo::PendingRemote<mojom::GinJavaBridgeHost> host) {
CHECK(!remote_);
CHECK(named_objects_.empty());
remote_.Bind(std::move(host));
}
GinJavaBridgeObject* GinJavaBridgeDispatcher::GetObject(ObjectID object_id) {
GinJavaBridgeObject* result = objects_.Lookup(object_id);
if (!result) {
result = GinJavaBridgeObject::InjectAnonymous(
render_frame()->GetWebFrame(), weak_ptr_factory_.GetWeakPtr(),
object_id);
if (result)
objects_.AddWithID(result, object_id);
}
return result;
}
void GinJavaBridgeDispatcher::OnGinJavaBridgeObjectDeleted(
GinJavaBridgeObject* object) {
int object_id = object->object_id();
if (objects_.Lookup(object_id) != object) return;
objects_.Remove(object_id);
GetRemoteObjectHost()->ObjectWrapperDeleted(object_id);
}
void GinJavaBridgeDispatcher::OnDestruct() {
}
mojom::GinJavaBridgeHost* GinJavaBridgeDispatcher::GetRemoteObjectHost() {
CHECK(remote_);
return remote_.get();
}
}