Commit 6aeb48b5 authored by Alex Clarke's avatar Alex Clarke Committed by Commit Bot

Changes to allow telemetry to connect to weblayer_shell

This requires the following changes:

* It must be possible for the Java App to turn DevTools on. To implement this I opted for
an interface similar to AwDevToolsServer.

* Telemetry expects the DevTools version query contain a product with a
recognizable version number.  This requires overriding ContentBrowserClientImpl::GetProduct

* Telemetry expects DevTools targets to be discoverable, this requires overriding the
DevToolsManagerDelegate.

Bug: 1022812
Change-Id: Idae5ac1aa05e700781c96181d3fec0ab3776003c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1906151
Commit-Queue: Scott Violet <sky@chromium.org>
Reviewed-by: default avatarScott Violet <sky@chromium.org>
Reviewed-by: default avatarTobias Sargeant <tobiasjs@chromium.org>
Reviewed-by: default avatarClark DuVall <cduvall@chromium.org>
Cr-Commit-Position: refs/heads/master@{#715019}
parent b2c6e2fb
...@@ -190,12 +190,17 @@ jumbo_static_library("weblayer_lib") { ...@@ -190,12 +190,17 @@ jumbo_static_library("weblayer_lib") {
if (is_android) { if (is_android) {
# TODO(timvolodine): move this to safe_browsing/ # TODO(timvolodine): move this to safe_browsing/
sources += [ sources += [
"browser/devtools_manager_delegate_android.cc",
"browser/devtools_manager_delegate_android.h",
"browser/devtools_server_android.cc",
"browser/devtools_server_android.h",
"browser/safe_browsing/safe_browsing_service.cc", "browser/safe_browsing/safe_browsing_service.cc",
"browser/safe_browsing/safe_browsing_service.h", "browser/safe_browsing/safe_browsing_service.h",
"browser/safe_browsing/safe_browsing_ui_manager.cc", "browser/safe_browsing/safe_browsing_ui_manager.cc",
"browser/safe_browsing/safe_browsing_ui_manager.h", "browser/safe_browsing/safe_browsing_ui_manager.h",
"browser/safe_browsing/url_checker_delegate_impl.cc", "browser/safe_browsing/url_checker_delegate_impl.cc",
"browser/safe_browsing/url_checker_delegate_impl.h", "browser/safe_browsing/url_checker_delegate_impl.h",
"browser/weblayer_impl_android.cc",
] ]
} }
......
...@@ -44,6 +44,7 @@ ...@@ -44,6 +44,7 @@
#include "components/crash/content/browser/crash_handler_host_linux.h" #include "components/crash/content/browser/crash_handler_host_linux.h"
#include "ui/base/resource/resource_bundle_android.h" #include "ui/base/resource/resource_bundle_android.h"
#include "weblayer/browser/android_descriptors.h" #include "weblayer/browser/android_descriptors.h"
#include "weblayer/browser/devtools_manager_delegate_android.h"
#include "weblayer/browser/safe_browsing/safe_browsing_service.h" #include "weblayer/browser/safe_browsing/safe_browsing_service.h"
#endif #endif
...@@ -105,9 +106,14 @@ ContentBrowserClientImpl::GetWebContentsViewDelegate( ...@@ -105,9 +106,14 @@ ContentBrowserClientImpl::GetWebContentsViewDelegate(
content::WebContents* web_contents) { content::WebContents* web_contents) {
return nullptr; return nullptr;
} }
content::DevToolsManagerDelegate* content::DevToolsManagerDelegate*
ContentBrowserClientImpl::GetDevToolsManagerDelegate() { ContentBrowserClientImpl::GetDevToolsManagerDelegate() {
#if defined(OS_ANDROID)
return new DevToolsManagerDelegateAndroid();
#else
return new content::DevToolsManagerDelegate(); return new content::DevToolsManagerDelegate();
#endif
} }
base::Optional<service_manager::Manifest> base::Optional<service_manager::Manifest>
...@@ -117,8 +123,12 @@ ContentBrowserClientImpl::GetServiceManifestOverlay(base::StringPiece name) { ...@@ -117,8 +123,12 @@ ContentBrowserClientImpl::GetServiceManifestOverlay(base::StringPiece name) {
return base::nullopt; return base::nullopt;
} }
std::string ContentBrowserClientImpl::GetProduct() {
return version_info::GetProductNameAndVersionForUserAgent();
}
std::string ContentBrowserClientImpl::GetUserAgent() { std::string ContentBrowserClientImpl::GetUserAgent() {
std::string product = version_info::GetProductNameAndVersionForUserAgent(); std::string product = GetProduct();
const base::CommandLine& command_line = const base::CommandLine& command_line =
*base::CommandLine::ForCurrentProcess(); *base::CommandLine::ForCurrentProcess();
......
...@@ -34,6 +34,7 @@ class ContentBrowserClientImpl : public content::ContentBrowserClient { ...@@ -34,6 +34,7 @@ class ContentBrowserClientImpl : public content::ContentBrowserClient {
content::DevToolsManagerDelegate* GetDevToolsManagerDelegate() override; content::DevToolsManagerDelegate* GetDevToolsManagerDelegate() override;
base::Optional<service_manager::Manifest> GetServiceManifestOverlay( base::Optional<service_manager::Manifest> GetServiceManifestOverlay(
base::StringPiece name) override; base::StringPiece name) override;
std::string GetProduct() override;
std::string GetUserAgent() override; std::string GetUserAgent() override;
blink::UserAgentMetadata GetUserAgentMetadata() override; blink::UserAgentMetadata GetUserAgentMetadata() override;
void OverrideWebkitPrefs(content::RenderViewHost* render_view_host, void OverrideWebkitPrefs(content::RenderViewHost* render_view_host,
......
// Copyright 2019 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 "weblayer/browser/devtools_manager_delegate_android.h"
namespace weblayer {
DevToolsManagerDelegateAndroid::DevToolsManagerDelegateAndroid() = default;
DevToolsManagerDelegateAndroid::~DevToolsManagerDelegateAndroid() = default;
std::string DevToolsManagerDelegateAndroid::GetDiscoveryPageHTML() {
const char html[] =
"<html>"
"<head><title>WebLayer remote debugging</title></head>"
"<body>Please use <a href=\'chrome://inspect\'>chrome://inspect</a>"
"</body>"
"</html>";
return html;
}
bool DevToolsManagerDelegateAndroid::IsBrowserTargetDiscoverable() {
return true;
}
} // namespace weblayer
// Copyright 2019 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.
#ifndef WEBLAYER_BROWSER_DEVTOOLS_MANAGER_DELEGATE_ANDROID_H_
#define WEBLAYER_BROWSER_DEVTOOLS_MANAGER_DELEGATE_ANDROID_H_
#include "base/macros.h"
#include "content/public/browser/devtools_manager_delegate.h"
namespace weblayer {
class DevToolsManagerDelegateAndroid : public content::DevToolsManagerDelegate {
public:
DevToolsManagerDelegateAndroid();
~DevToolsManagerDelegateAndroid() override;
// content::DevToolsManagerDelegate implementation.
std::string GetDiscoveryPageHTML() override;
bool IsBrowserTargetDiscoverable() override;
private:
DISALLOW_COPY_AND_ASSIGN(DevToolsManagerDelegateAndroid);
};
} // namespace weblayer
#endif // WEBLAYER_BROWSER_DEVTOOLS_MANAGER_DELEGATE_ANDROID_H_
// Copyright 2019 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 "weblayer/browser/devtools_server_android.h"
#include "base/command_line.h"
#include "base/strings/stringprintf.h"
#include "content/public/browser/android/devtools_auth.h"
#include "content/public/browser/devtools_manager_delegate.h"
#include "content/public/browser/devtools_socket_factory.h"
#include "content/public/common/content_switches.h"
#include "net/base/net_errors.h"
#include "net/socket/unix_domain_server_socket_posix.h"
namespace weblayer {
namespace {
bool g_remote_debugging_enabled = false;
const int kBackLog = 10;
const char kSocketNameFormat[] = "weblayer_devtools_remote_%d";
const char kTetheringSocketName[] = "weblayer_devtools_tethering_%d_%d";
class UnixDomainServerSocketFactory : public content::DevToolsSocketFactory {
public:
explicit UnixDomainServerSocketFactory(const std::string& socket_name)
: socket_name_(socket_name) {}
private:
// content::DevToolsAgentHost::ServerSocketFactory.
std::unique_ptr<net::ServerSocket> CreateForHttpServer() override {
auto socket = std::make_unique<net::UnixDomainServerSocket>(
base::BindRepeating(&content::CanUserConnectToDevTools),
true /* use_abstract_namespace */);
if (socket->BindAndListen(socket_name_, kBackLog) != net::OK)
return nullptr;
return std::move(socket);
}
std::unique_ptr<net::ServerSocket> CreateForTethering(
std::string* name) override {
*name = base::StringPrintf(kTetheringSocketName, getpid(),
++last_tethering_socket_);
auto socket = std::make_unique<net::UnixDomainServerSocket>(
base::BindRepeating(&content::CanUserConnectToDevTools),
true /* use_abstract_namespace */);
if (socket->BindAndListen(*name, kBackLog) != net::OK)
return nullptr;
return std::move(socket);
}
std::string socket_name_;
int last_tethering_socket_ = 0;
DISALLOW_COPY_AND_ASSIGN(UnixDomainServerSocketFactory);
};
} // namespace
// static
void DevToolsServerAndroid::SetRemoteDebuggingEnabled(bool enabled) {
if (g_remote_debugging_enabled == enabled)
return;
g_remote_debugging_enabled = enabled;
if (enabled) {
auto factory = std::make_unique<UnixDomainServerSocketFactory>(
base::StringPrintf(kSocketNameFormat, getpid()));
content::DevToolsAgentHost::StartRemoteDebuggingServer(
std::move(factory), base::FilePath(), base::FilePath());
} else {
content::DevToolsAgentHost::StopRemoteDebuggingServer();
}
}
// static
bool DevToolsServerAndroid::GetRemoteDebuggingEnabled() {
return g_remote_debugging_enabled;
}
} // namespace weblayer
// Copyright 2019 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.
#ifndef WEBLAYER_BROWSER_DEVTOOLS_SERVER_ANDROID_H_
#define WEBLAYER_BROWSER_DEVTOOLS_SERVER_ANDROID_H_
namespace weblayer {
class DevToolsServerAndroid {
public:
static void SetRemoteDebuggingEnabled(bool enabled);
static bool GetRemoteDebuggingEnabled();
};
} // namespace weblayer
#endif // WEBLAYER_BROWSER_DEVTOOLS_SERVER_ANDROID_H_
...@@ -88,6 +88,7 @@ generate_jni("jni") { ...@@ -88,6 +88,7 @@ generate_jni("jni") {
"org/chromium/weblayer_private/TabCallbackProxy.java", "org/chromium/weblayer_private/TabCallbackProxy.java",
"org/chromium/weblayer_private/TabImpl.java", "org/chromium/weblayer_private/TabImpl.java",
"org/chromium/weblayer_private/TopControlsContainerView.java", "org/chromium/weblayer_private/TopControlsContainerView.java",
"org/chromium/weblayer_private/WebLayerImpl.java",
] ]
} }
......
...@@ -23,6 +23,8 @@ import org.chromium.base.ContentUriUtils; ...@@ -23,6 +23,8 @@ import org.chromium.base.ContentUriUtils;
import org.chromium.base.ContextUtils; import org.chromium.base.ContextUtils;
import org.chromium.base.PathUtils; import org.chromium.base.PathUtils;
import org.chromium.base.StrictModeContext; import org.chromium.base.StrictModeContext;
import org.chromium.base.annotations.JNINamespace;
import org.chromium.base.annotations.NativeMethods;
import org.chromium.base.annotations.UsedByReflection; import org.chromium.base.annotations.UsedByReflection;
import org.chromium.base.library_loader.LibraryLoader; import org.chromium.base.library_loader.LibraryLoader;
import org.chromium.base.library_loader.LibraryProcessType; import org.chromium.base.library_loader.LibraryProcessType;
...@@ -47,6 +49,7 @@ import java.lang.reflect.Method; ...@@ -47,6 +49,7 @@ import java.lang.reflect.Method;
* Root implementation class for WebLayer. * Root implementation class for WebLayer.
* This is constructed by the client library using reflection. * This is constructed by the client library using reflection.
*/ */
@JNINamespace("weblayer")
@UsedByReflection("WebLayer") @UsedByReflection("WebLayer")
public final class WebLayerImpl extends IWebLayer.Stub { public final class WebLayerImpl extends IWebLayer.Stub {
// TODO: should there be one tag for all this code? // TODO: should there be one tag for all this code?
...@@ -164,6 +167,16 @@ public final class WebLayerImpl extends IWebLayer.Stub { ...@@ -164,6 +167,16 @@ public final class WebLayerImpl extends IWebLayer.Stub {
return mProfileManager.getProfile(profilePath); return mProfileManager.getProfile(profilePath);
} }
@Override
public void setRemoteDebuggingEnabled(boolean enabled) {
WebLayerImplJni.get().setRemoteDebuggingEnabled(enabled);
}
@Override
public boolean isRemoteDebuggingEnabled() {
return WebLayerImplJni.get().isRemoteDebuggingEnabled();
}
/** /**
* Returns the package ID to use when calling R.onResourcesLoaded(). * Returns the package ID to use when calling R.onResourcesLoaded().
*/ */
...@@ -193,4 +206,10 @@ public final class WebLayerImpl extends IWebLayer.Stub { ...@@ -193,4 +206,10 @@ public final class WebLayerImpl extends IWebLayer.Stub {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
} }
@NativeMethods
interface Natives {
void setRemoteDebuggingEnabled(boolean enabled);
boolean isRemoteDebuggingEnabled();
}
} }
...@@ -35,4 +35,10 @@ interface IWebLayer { ...@@ -35,4 +35,10 @@ interface IWebLayer {
// Create or get the profile matching profilePath. // Create or get the profile matching profilePath.
IProfile getProfile(in String profilePath) = 4; IProfile getProfile(in String profilePath) = 4;
// Enable or disable DevTools remote debugging server.
void setRemoteDebuggingEnabled(boolean enabled) = 5;
// Returns whether or not the DevTools remote debugging server is enabled.
boolean isRemoteDebuggingEnabled() = 6;
} }
...@@ -9,4 +9,4 @@ package org.chromium.weblayer_private.interfaces; ...@@ -9,4 +9,4 @@ package org.chromium.weblayer_private.interfaces;
* *
* Whenever any AIDL file is changed, sVersionNumber must be incremented. * Whenever any AIDL file is changed, sVersionNumber must be incremented.
* */ * */
public final class WebLayerVersion { public static final int sVersionNumber = 13; } public final class WebLayerVersion { public static final int sVersionNumber = 14; }
// Copyright 2019 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 "weblayer/browser/devtools_server_android.h"
#include "weblayer/browser/java/jni/WebLayerImpl_jni.h"
namespace weblayer {
static void JNI_WebLayerImpl_SetRemoteDebuggingEnabled(JNIEnv* env,
jboolean enabled) {
DevToolsServerAndroid::SetRemoteDebuggingEnabled(enabled);
}
static jboolean JNI_WebLayerImpl_IsRemoteDebuggingEnabled(JNIEnv* env) {
return DevToolsServerAndroid::GetRemoteDebuggingEnabled();
}
} // namespace weblayer
...@@ -6,65 +6,10 @@ ...@@ -6,65 +6,10 @@
#include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents.h"
#include "content/public/browser/web_ui_data_source.h" #include "content/public/browser/web_ui_data_source.h"
#include "weblayer/browser/devtools_server_android.h"
#include "weblayer/grit/weblayer_resources.h" #include "weblayer/grit/weblayer_resources.h"
#if defined(OS_ANDROID)
#include "content/public/browser/android/devtools_auth.h"
#include "content/public/browser/devtools_manager_delegate.h"
#include "content/public/browser/devtools_socket_factory.h"
#include "net/socket/unix_domain_server_socket_posix.h"
#endif
namespace weblayer { namespace weblayer {
namespace {
#if defined(OS_ANDROID)
bool g_remote_debugging_enabled = false;
const char kSocketNameFormat[] = "weblayer_devtools_remote_%d";
const char kTetheringSocketName[] = "weblayer_devtools_tethering_%d_%d";
const int kBackLog = 10;
// Factory for UnixDomainServerSocket.
class UnixDomainServerSocketFactory : public content::DevToolsSocketFactory {
public:
explicit UnixDomainServerSocketFactory(const std::string& socket_name)
: socket_name_(socket_name) {}
private:
// content::DevToolsAgentHost::ServerSocketFactory.
std::unique_ptr<net::ServerSocket> CreateForHttpServer() override {
auto socket = std::make_unique<net::UnixDomainServerSocket>(
base::BindRepeating(&content::CanUserConnectToDevTools),
true /* use_abstract_namespace */);
if (socket->BindAndListen(socket_name_, kBackLog) != net::OK)
return nullptr;
return std::move(socket);
}
std::unique_ptr<net::ServerSocket> CreateForTethering(
std::string* name) override {
*name = base::StringPrintf(kTetheringSocketName, getpid(),
++last_tethering_socket_);
auto socket = std::make_unique<net::UnixDomainServerSocket>(
base::BindRepeating(&content::CanUserConnectToDevTools),
true /* use_abstract_namespace */);
if (socket->BindAndListen(*name, kBackLog) != net::OK)
return nullptr;
return std::move(socket);
}
std::string socket_name_;
int last_tethering_socket_ = 0;
DISALLOW_COPY_AND_ASSIGN(UnixDomainServerSocketFactory);
};
#endif
} // namespace
const char kChromeUIWebLayerHost[] = "weblayer"; const char kChromeUIWebLayerHost[] = "weblayer";
...@@ -87,22 +32,11 @@ WebLayerInternalsUI::~WebLayerInternalsUI() {} ...@@ -87,22 +32,11 @@ WebLayerInternalsUI::~WebLayerInternalsUI() {}
#if defined(OS_ANDROID) #if defined(OS_ANDROID)
void WebLayerInternalsUI::GetRemoteDebuggingEnabled( void WebLayerInternalsUI::GetRemoteDebuggingEnabled(
GetRemoteDebuggingEnabledCallback callback) { GetRemoteDebuggingEnabledCallback callback) {
std::move(callback).Run(g_remote_debugging_enabled); std::move(callback).Run(DevToolsServerAndroid::GetRemoteDebuggingEnabled());
} }
void WebLayerInternalsUI::SetRemoteDebuggingEnabled(bool enabled) { void WebLayerInternalsUI::SetRemoteDebuggingEnabled(bool enabled) {
if (g_remote_debugging_enabled == enabled) DevToolsServerAndroid::SetRemoteDebuggingEnabled(enabled);
return;
g_remote_debugging_enabled = enabled;
if (enabled) {
auto factory = std::make_unique<UnixDomainServerSocketFactory>(
base::StringPrintf(kSocketNameFormat, getpid()));
content::DevToolsAgentHost::StartRemoteDebuggingServer(
std::move(factory), base::FilePath(), base::FilePath());
} else {
content::DevToolsAgentHost::StopRemoteDebuggingServer();
}
} }
#endif #endif
......
...@@ -169,6 +169,28 @@ public final class WebLayer { ...@@ -169,6 +169,28 @@ public final class WebLayer {
return Profile.of(iprofile); return Profile.of(iprofile);
} }
/**
* To enable or disable DevTools remote debugging.
*/
public void setRemoteDebuggingEnabled(boolean enabled) {
try {
mImpl.setRemoteDebuggingEnabled(enabled);
} catch (RemoteException e) {
throw new APICallException(e);
}
}
/**
* @return Whether or not DevTools remote debugging is enabled.
*/
public boolean isRemoteDebuggingEnabled() {
try {
return mImpl.isRemoteDebuggingEnabled();
} catch (RemoteException e) {
throw new APICallException(e);
}
}
@NonNull @NonNull
public static Fragment createBrowserFragment(@Nullable String profilePath) { public static Fragment createBrowserFragment(@Nullable String profilePath) {
ThreadCheck.ensureOnUiThread(); ThreadCheck.ensureOnUiThread();
......
...@@ -114,15 +114,17 @@ public class WebLayerShellActivity extends FragmentActivity { ...@@ -114,15 +114,17 @@ public class WebLayerShellActivity extends FragmentActivity {
// BrowserFragment immediately, resulting in synchronous init. By the time this line // BrowserFragment immediately, resulting in synchronous init. By the time this line
// executes, the synchronous init has already happened. // executes, the synchronous init has already happened.
WebLayer.create(getApplication()) WebLayer.create(getApplication())
.addCallback(webLayer -> onWebLayerReady(savedInstanceState)); .addCallback(webLayer -> onWebLayerReady(webLayer, savedInstanceState));
} catch (UnsupportedVersionException e) { } catch (UnsupportedVersionException e) {
throw new RuntimeException("Failed to initialize WebLayer", e); throw new RuntimeException("Failed to initialize WebLayer", e);
} }
} }
private void onWebLayerReady(Bundle savedInstanceState) { private void onWebLayerReady(WebLayer webLayer, Bundle savedInstanceState) {
if (isFinishing() || isDestroyed()) return; if (isFinishing() || isDestroyed()) return;
webLayer.setRemoteDebuggingEnabled(true);
Fragment fragment = getOrCreateBrowserFragment(savedInstanceState); Fragment fragment = getOrCreateBrowserFragment(savedInstanceState);
mBrowser = Browser.fromFragment(fragment); mBrowser = Browser.fromFragment(fragment);
mBrowser.getActiveTab().setFullscreenCallback(new FullscreenCallback() { mBrowser.getActiveTab().setFullscreenCallback(new FullscreenCallback() {
......
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