blob: b0f81753bbababa39a03200394ad62e0d43efd66 [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/renderer/external_extension.h"
#include <stdint.h>
#include "base/macros.h"
#include "chrome/common/search_provider.mojom.h"
#include "content/public/renderer/render_thread.h"
#include "services/shell/public/cpp/interface_provider.h"
#include "third_party/WebKit/public/web/WebDocument.h"
#include "third_party/WebKit/public/web/WebLocalFrame.h"
#include "v8/include/v8.h"
using blink::WebLocalFrame;
using blink::WebView;
namespace extensions_v8 {
namespace {
const char* const kSearchProviderApi =
"var external;"
"if (!external)"
" external = {};"
"external.IsSearchProviderInstalled = function(name) {"
" native function NativeIsSearchProviderInstalled();"
" return NativeIsSearchProviderInstalled(name);"
"};";
const char kExternalExtensionName[] = "v8/External";
} // namespace
class ExternalExtensionWrapper : public v8::Extension {
public:
ExternalExtensionWrapper();
// Allows v8's javascript code to call the native functions defined
// in this class for window.external.
v8::Local<v8::FunctionTemplate> GetNativeFunctionTemplate(
v8::Isolate* isolate,
v8::Local<v8::String> name) override;
// Implementation of window.external.IsSearchProviderInstalled.
static void IsSearchProviderInstalled(
const v8::FunctionCallbackInfo<v8::Value>& args);
private:
DISALLOW_COPY_AND_ASSIGN(ExternalExtensionWrapper);
};
ExternalExtensionWrapper::ExternalExtensionWrapper()
: v8::Extension(kExternalExtensionName, kSearchProviderApi) {
}
v8::Local<v8::FunctionTemplate>
ExternalExtensionWrapper::GetNativeFunctionTemplate(
v8::Isolate* isolate,
v8::Local<v8::String> name) {
if (name->Equals(v8::String::NewFromUtf8(
isolate, "NativeIsSearchProviderInstalled"))) {
return v8::FunctionTemplate::New(isolate, IsSearchProviderInstalled);
}
return v8::Local<v8::FunctionTemplate>();
}
// static
void ExternalExtensionWrapper::IsSearchProviderInstalled(
const v8::FunctionCallbackInfo<v8::Value>& args) {
if (!args.Length() || !args[0]->IsString())
return;
v8::String::Utf8Value utf8name(args[0]);
if (!utf8name.length())
return;
std::string name(*utf8name);
WebLocalFrame* webframe = WebLocalFrame::frameForCurrentContext();
if (!webframe)
return;
chrome::mojom::InstallState install = chrome::mojom::InstallState::DENIED;
GURL inquiry_url = GURL(webframe->document().url()).Resolve(name);
if (!inquiry_url.is_empty()) {
webframe->didCallIsSearchProviderInstalled();
chrome::mojom::SearchProviderInstallStatePtr search_provider_service;
content::RenderThread::Get()->GetRemoteInterfaces()->GetInterface(
mojo::GetProxy(&search_provider_service));
if (!search_provider_service->GetInstallState(webframe->document().url(),
inquiry_url, &install)) {
DLOG(ERROR) << "Can't fetch search provider install state";
}
}
if (install == chrome::mojom::InstallState::DENIED) {
// FIXME: throw access denied exception.
v8::Isolate* isolate = args.GetIsolate();
isolate->ThrowException(v8::Exception::Error(v8::String::Empty(isolate)));
return;
}
args.GetReturnValue().Set(static_cast<int32_t>(install));
}
v8::Extension* ExternalExtension::Get() {
return new ExternalExtensionWrapper();
}
} // namespace extensions_v8