Commit e0b4355f authored by Erik Chen's avatar Erik Chen Committed by Commit Bot

Add Android OOP HP end-to-end tests.

This CL has three components:
  1) The bulk of the logic in OOP HP was refactored into ProfilingTestDriver.
  2) Adds a java instrumentation test, along with a JNI shim that forwards into
  ProfilingTestDriver.
  3) Creates a new apk: chrome_public_apk_for_test that contains the same
  content as chrome_public_apk, as well as native files needed for (2).
  chrome_public_apk_test now targets chrome_public_apk_for_test instead of
  chrome_public_apk.

Other ideas, discarded:
  * Originally, I attempted to make the browser_tests target runnable on
  Android. The primary problem is that native test harness cannot fork
  or spawn processes. This is difficult to solve.

More details on each of the components:
(1) ProfilingTestDriver
  * The TracingController test was migrated to use ProfilingTestDriver, but the
  write-to-file test was left as-is. The latter behavior will likely be phased
  out, but I'll clean that up in a future CL.
  * gtest isn't supported for Android instrumentation tests. ProfilingTestDriver
  has a single function RunTest that returns a 'bool' indicating success. On
  failure, the class uses LOG(ERROR) to print the nature of the error. This will
  cause the error to be printed out on browser_test error. On instrumentation
  test failure, the error will be forwarded to logcat, which is available on all
  infra bot test runs.
(2) Instrumentation test
  * For now, I only added a single test for the "browser" mode. Furthermore, I'm
  only testing the start with command-line path.
(3) New apk
  * libchromefortest is a new shared library that contains all content from
  libchrome, but also contains native sources for the JNI shim.
  * chrome_public_apk_for_test is a new apk that contains all content from
  chrome_public_apk, but uses a single shared library libchromefortest rather
  than libchrome. This also contains java sources for the JNI shim.
  * There is no way to just add a second shared library to chrome_public_apk
  that just contains the native sources from the JNI shim without causing ODR
  issues.
  * chrome_public_test_apk now has apk_under_test = chrome_public_apk_for_test.
  * There is no way to add native JNI sources as a shared library to
  chrome_public_test_apk without causing ODR issues.

Finally, this CL drastically increases the timeout to wait for native
initialization. The previous timeout was 2 *
CriteriaHelper.DEFAULT_MAX_TIME_TO_POLL, which flakily failed for this test.
This suggests that this step/timeout is generally flaky. I increased the timeout
to 20 * CriteriaHelper.DEFAULT_MAX_TIME_TO_POLL.

Bug: 753218
Change-Id: Ic224b7314fff57f1770a4048aa5753f54e040b55
Reviewed-on: https://chromium-review.googlesource.com/770148
Commit-Queue: Erik Chen <erikchen@chromium.org>
Reviewed-by: default avatarJohn Budorick <jbudorick@chromium.org>
Reviewed-by: default avatarBrett Wilson <brettw@chromium.org>
Cr-Commit-Position: refs/heads/master@{#517541}
parent 5427a3a3
......@@ -494,6 +494,7 @@ android_library("chrome_test_java") {
"//chrome/android/webapk/libs/client:client_java",
"//chrome/android/webapk/libs/common:common_java",
"//chrome/android/webapk/libs/runtime_library:webapk_service_aidl_java",
"//chrome/browser/profiling_host:profiling_host_javatests",
"//chrome/test/android:chrome_java_test_support",
"//components/autofill/android:autofill_java",
"//components/background_task_scheduler:background_task_scheduler_java",
......@@ -726,39 +727,68 @@ jinja_template_resources("chrome_sync_shell_apk_template_resources") {
variables = chrome_sync_shell_jinja_variables
}
shared_library("libchrome") {
# This template contains common code for both libchrome and libchromefortest.
# The former is used in chrome_public_apk. The latter is used in
# chrome_public_apk_for_test. The distinction is necessary because the latter
# requires additional native sources for JNI shims only used by tests.
template("chrome_shared_library") {
shared_library(target_name) {
forward_variables_from(invoker, "*")
deps += [
"//build/config:exe_and_shlib_deps",
"//chrome:chrome_android_core",
]
if (enable_vr) {
# Ensure libgvr static library appears before gcc library in linking order.
# See https://crbug.com/704305 for details.
libs = [ "//third_party/gvr-android-sdk/libgvr_shim_static_${current_cpu}.a" ]
}
if (use_order_profiling) {
deps += [ "//tools/cygprofile" ]
}
# See crbug.com/705088, crbug.com/717815.
if (target_cpu == "arm" && (is_asan || use_order_profiling)) {
ldflags = [ "-Wl,--long-plt" ]
}
if (chromium_linker_supported && use_lld) {
configs += [ "//build/config/android:lld_pack_relocations" ]
}
public_configs = extra_chrome_shared_library_configs
deps += extra_chrome_shared_library_deps
}
}
chrome_shared_library("libchrome") {
sources = [
"../app/android/chrome_main_delegate_android_initializer.cc",
"../browser/android/chrome_entry_point.cc",
]
deps = [
":chrome_jni_registration($default_toolchain)",
"//build/config:exe_and_shlib_deps",
"//chrome:chrome_android_core",
]
}
if (enable_vr) {
# Ensure libgvr static library appears before gcc library in linking order.
# See https://crbug.com/704305 for details.
libs =
[ "//third_party/gvr-android-sdk/libgvr_shim_static_${current_cpu}.a" ]
}
if (use_order_profiling) {
deps += [ "//tools/cygprofile" ]
}
# See crbug.com/705088, crbug.com/717815.
if (target_cpu == "arm" && (is_asan || use_order_profiling)) {
ldflags = [ "-Wl,--long-plt" ]
}
if (chromium_linker_supported && use_lld) {
configs += [ "//build/config/android:lld_pack_relocations" ]
}
public_configs = extra_chrome_shared_library_configs
deps += extra_chrome_shared_library_deps
chrome_shared_library("libchromefortest") {
testonly = true
sources = [
"../app/android/chrome_main_delegate_android_initializer.cc",
"../browser/android/chrome_entry_point_for_test.cc",
"../browser/profiling_host/profiling_test_driver.cc",
"../browser/profiling_host/profiling_test_driver.h",
"../browser/profiling_host/test_android_shim.cc",
"../browser/profiling_host/test_android_shim.h",
]
deps = [
":chrome_jni_for_test_registration($default_toolchain)",
"//base/test:test_support",
"//chrome/browser/profiling_host:jni_headers",
]
}
# Ensure that .pak files are built only once (build them in the default
......@@ -771,6 +801,13 @@ if (current_toolchain == default_toolchain) {
exception_files = jni_exception_files
}
generate_jni_registration("chrome_jni_for_test_registration") {
testonly = true
target = ":chrome_public_apk_for_test"
output = "$root_gen_dir/chrome/browser/android/${target_name}.h"
exception_files = jni_exception_files
}
generate_jni_registration("chrome_sync_shell_jni_registration") {
testonly = true
target = ":chrome_sync_shell_apk"
......@@ -995,6 +1032,17 @@ chrome_public_apk_tmpl_shared("chrome_public_apk") {
shared_libraries = [ ":libchrome" ]
}
chrome_public_apk_tmpl_shared("chrome_public_apk_for_test") {
testonly = true
android_manifest = chrome_public_android_manifest
android_manifest_dep = ":chrome_public_android_manifest"
apk_name = "ChromePublicForTest"
shared_libraries = [ ":libchromefortest" ]
deps = [
"//chrome/browser/profiling_host:profiling_host_javatests",
]
}
chrome_public_apk_tmpl_shared("chrome_modern_public_apk") {
android_manifest = chrome_modern_public_android_manifest
android_manifest_dep = ":chrome_modern_public_android_manifest"
......@@ -1089,7 +1137,7 @@ jinja_template("chrome_sync_shell_test_apk_manifest") {
instrumentation_test_apk("chrome_public_test_apk") {
apk_name = "ChromePublicTest"
apk_under_test = ":chrome_public_apk"
apk_under_test = ":chrome_public_apk_for_test"
android_manifest = chrome_public_test_apk_manifest
android_manifest_dep = ":chrome_public_test_apk_manifest"
......
// Copyright 2017 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.
package org.chromium.chrome.browser.profiling_host;
import android.support.test.filters.MediumTest;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.chromium.base.test.util.CommandLineFlags;
import org.chromium.chrome.browser.ChromeActivity;
import org.chromium.chrome.browser.ChromeSwitches;
import org.chromium.chrome.test.ChromeActivityTestRule;
import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
/**
* Test suite for out of process heap profiling.
*/
@RunWith(ChromeJUnit4ClassRunner.class)
@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
public class ProfilingProcessHostAndroidTest {
private static final String TAG = "ProfilingProcessHostAndroidTest";
@Rule
public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
new ChromeActivityTestRule<>(ChromeActivity.class);
@Before
public void setUp() throws InterruptedException {
mActivityTestRule.startMainActivityOnBlankPage();
}
@Test
@MediumTest
@CommandLineFlags.Add({"memlog=browser"})
public void testModeBrowser() throws Exception {
TestAndroidShim profilingProcessHost = new TestAndroidShim();
Assert.assertTrue(profilingProcessHost.runTestForMode("browser"));
}
}
// Copyright 2017 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.
package org.chromium.chrome.browser.profiling_host;
import org.chromium.base.annotations.MainDex;
/**
* Provides direct access to test_android_shim, which in turn forwards to
* ProfilingTestDriver. Only used for testing.
*/
@MainDex
public class TestAndroidShim {
public TestAndroidShim() {
mNativeTestAndroidShim = nativeInit();
}
public boolean runTestForMode(String mode) {
return nativeRunTestForMode(mNativeTestAndroidShim, mode);
}
/**
* Clean up the C++ side of this class.
* After the call, this class instance shouldn't be used.
*/
public void destroy() {
if (mNativeTestAndroidShim != 0) {
nativeDestroy(mNativeTestAndroidShim);
mNativeTestAndroidShim = 0;
}
}
private long mNativeTestAndroidShim;
private native long nativeInit();
private native void nativeDestroy(long nativeTestAndroidShim);
private native boolean nativeRunTestForMode(long nativeTestAndroidShim, String mode);
}
// Copyright 2017 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 "base/android/jni_android.h"
#include "base/android/jni_utils.h"
#include "base/android/library_loader/library_loader_hooks.h"
#include "base/bind.h"
#include "base/test/test_support_android.h"
#include "chrome/app/android/chrome_jni_onload.h"
#include "chrome/browser/android/chrome_jni_for_test_registration.h"
namespace {
bool NativeInit() {
return android::OnJNIOnLoadInit();
}
} // namespace
// This is called by the VM when the shared library is first loaded.
JNI_EXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
// By default, all JNI methods are registered. However, since render processes
// don't need very much Java code, we enable selective JNI registration on the
// Java side and only register a subset of JNI methods.
base::android::InitVM(vm);
JNIEnv* env = base::android::AttachCurrentThread();
if (!base::android::IsSelectiveJniRegistrationEnabled(env) &&
!RegisterNonMainDexNatives(env)) {
return -1;
}
if (!RegisterMainDexNatives(env)) {
return -1;
}
if (!android::OnJNIOnLoadRegisterJNI(env)) {
return -1;
}
base::android::SetNativeInitializationHook(NativeInit);
return JNI_VERSION_1_4;
}
......@@ -8,6 +8,8 @@ if (!is_android) {
sources = [
"memlog_browsertest.cc",
"profiling_test_driver.cc",
"profiling_test_driver.h",
]
defines = [ "HAS_OUT_OF_PROC_TEST_RUNNER" ]
......@@ -21,7 +23,33 @@ if (!is_android) {
]
}
} else {
import("//build/config/android/rules.gni")
# In-process browser tests aren't supported on Android.
group("profiling_browsertests") {
}
generate_jni("jni_headers") {
sources = [
"../../android/javatests/src/org/chromium/chrome/browser/profiling_host/TestAndroidShim.java",
]
jni_package = "chrome_profiling_host"
}
android_library("profiling_host_javatests") {
testonly = true
java_files = [
"../../android/javatests/src/org/chromium/chrome/browser/profiling_host/ProfilingProcessHostAndroidTest.java",
"../../android/javatests/src/org/chromium/chrome/browser/profiling_host/TestAndroidShim.java",
]
deps = [
"//base:base_java",
"//base:base_java_test_support",
"//chrome/android:chrome_java",
"//chrome/test/android:chrome_java_test_support",
"//third_party/android_support_test_runner:rules_java",
"//third_party/android_support_test_runner:runner_java",
"//third_party/junit",
]
}
}
......@@ -3,17 +3,13 @@
// found in the LICENSE file.
#include "base/allocator/features.h"
#include "base/allocator/partition_allocator/partition_alloc.h"
#include "base/json/json_reader.h"
#include "base/memory/ref_counted_memory.h"
#include "base/run_loop.h"
#include "base/task_scheduler/post_task.h"
#include "base/threading/thread_restrictions.h"
#include "base/trace_event/trace_buffer.h"
#include "base/trace_event/trace_config_memory_test_util.h"
#include "base/trace_event/trace_log.h"
#include "build/build_config.h"
#include "chrome/browser/profiling_host/profiling_process_host.h"
#include "chrome/browser/profiling_host/profiling_test_driver.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/common/chrome_switches.h"
......@@ -21,7 +17,6 @@
#include "chrome/test/base/ui_test_utils.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/tracing_controller.h"
#include "content/public/browser/web_contents.h"
#include "content/public/test/browser_test.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
......@@ -408,60 +403,15 @@ IN_PROC_BROWSER_TEST_P(MemlogBrowserTest, EndToEnd) {
// Ensure invocations via TracingController can generate a valid JSON file with
// expected data.
IN_PROC_BROWSER_TEST_P(MemlogBrowserTest, TracingControllerEndToEnd) {
if (!GetParam()) {
// Test that nothing has been started if the flag is not passed. Then early
// exit.
ASSERT_FALSE(profiling::ProfilingProcessHost::has_started());
return;
} else {
ASSERT_TRUE(profiling::ProfilingProcessHost::has_started());
}
MakeTestAllocations();
base::RunLoop run_loop;
scoped_refptr<base::RefCountedString> result;
// Once the ProfilingProcessHost has dumped to the trace, stop the trace and
// collate the results into |result|, then quit the nested run loop.
auto finish_sink_callback = base::Bind(
[](scoped_refptr<base::RefCountedString>* result, base::Closure finished,
std::unique_ptr<const base::DictionaryValue> metadata,
base::RefCountedString* in) {
*result = in;
std::move(finished).Run();
},
&result, run_loop.QuitClosure());
scoped_refptr<content::TracingController::TraceDataEndpoint> sink =
content::TracingController::CreateStringEndpoint(
std::move(finish_sink_callback));
base::OnceClosure stop_tracing_closure = base::BindOnce(
base::IgnoreResult<bool (content::TracingController::*)( // NOLINT
const scoped_refptr<content::TracingController::TraceDataEndpoint>&)>(
&content::TracingController::StopTracing),
base::Unretained(content::TracingController::GetInstance()), sink);
base::OnceClosure stop_tracing_ui_thread_closure =
base::BindOnce(base::IgnoreResult(&base::TaskRunner::PostTask),
base::ThreadTaskRunnerHandle::Get(), FROM_HERE,
std::move(stop_tracing_closure));
profiling::ProfilingProcessHost::GetInstance()
->SetDumpProcessForTracingCallback(
std::move(stop_tracing_ui_thread_closure));
// Spin a nested RunLoop until the heap dump has been added to the trace.
content::TracingController::GetInstance()->StartTracing(
base::trace_event::TraceConfig(
base::trace_event::TraceConfigMemoryTestUtil::
GetTraceConfig_PeriodicTriggers(100000, 100000)),
base::Closure());
run_loop.Run();
std::unique_ptr<base::Value> dump_json =
base::JSONReader::Read(result->data());
ASSERT_TRUE(dump_json);
ValidateBrowserAllocations(dump_json.get());
ValidateRendererAllocations(dump_json.get());
// TODO(ajwong): Test GPU dumps http://crbug.com/780955
profiling::ProfilingTestDriver driver;
profiling::ProfilingTestDriver::Options options;
options.mode =
GetParam()
? profiling::ProfilingProcessHost::ConvertStringToMode(GetParam())
: profiling::ProfilingProcessHost::Mode::kNone;
options.profiling_already_started = true;
EXPECT_TRUE(driver.RunTest(options));
}
// TODO(ajwong): Test what happens if profiling process crashes.
......
......@@ -371,19 +371,7 @@ ProfilingProcessHost::Mode ProfilingProcessHost::GetCurrentMode() {
kOOPHeapProfilingFeature, kOOPHeapProfilingFeatureMode);
}
if (mode == switches::kMemlogModeAll)
return Mode::kAll;
if (mode == switches::kMemlogModeMinimal)
return Mode::kMinimal;
if (mode == switches::kMemlogModeBrowser)
return Mode::kBrowser;
if (mode == switches::kMemlogModeGpu)
return Mode::kGpu;
if (mode == switches::kMemlogModeRendererSampling)
return Mode::kRendererSampling;
DLOG(ERROR) << "Unsupported value: \"" << mode << "\" passed to --"
<< switches::kMemlog;
return ConvertStringToMode(mode);
}
return Mode::kNone;
#else
......@@ -395,6 +383,24 @@ ProfilingProcessHost::Mode ProfilingProcessHost::GetCurrentMode() {
#endif
}
// static
ProfilingProcessHost::Mode ProfilingProcessHost::ConvertStringToMode(
const std::string& mode) {
if (mode == switches::kMemlogModeAll)
return Mode::kAll;
if (mode == switches::kMemlogModeMinimal)
return Mode::kMinimal;
if (mode == switches::kMemlogModeBrowser)
return Mode::kBrowser;
if (mode == switches::kMemlogModeGpu)
return Mode::kGpu;
if (mode == switches::kMemlogModeRendererSampling)
return Mode::kRendererSampling;
DLOG(ERROR) << "Unsupported value: \"" << mode << "\" passed to --"
<< switches::kMemlog;
return Mode::kNone;
}
// static
ProfilingProcessHost* ProfilingProcessHost::Start(
content::ServiceManagerConnection* connection,
......
......@@ -89,6 +89,7 @@ class ProfilingProcessHost : public content::BrowserChildProcessObserver,
// Returns the mode set on the current process' command line.
static Mode GetCurrentMode();
static Mode ConvertStringToMode(const std::string& input);
bool ShouldProfileProcessType(int process_type);
// Launches the profiling process and returns a pointer to it.
......@@ -123,6 +124,7 @@ class ProfilingProcessHost : public content::BrowserChildProcessObserver,
friend struct base::DefaultSingletonTraits<ProfilingProcessHost>;
friend class BackgroundProfilingTriggersTest;
friend class MemlogBrowserTest;
friend class ProfilingTestDriver;
FRIEND_TEST_ALL_PREFIXES(ProfilingProcessHost, ShouldProfileNewRenderer);
ProfilingProcessHost();
......
This diff is collapsed.
// Copyright 2017 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 CHROME_BROWSER_PROFILING_HOST_PROFILING_TEST_DRIVER_H_
#define CHROME_BROWSER_PROFILING_HOST_PROFILING_TEST_DRIVER_H_
#include <vector>
#include "base/allocator/partition_allocator/partition_alloc.h"
#include "base/macros.h"
#include "base/memory/ref_counted_memory.h"
#include "base/synchronization/waitable_event.h"
#include "chrome/browser/profiling_host/profiling_process_host.h"
namespace base {
class Value;
} // namespace base
namespace profiling {
// This class runs tests for the profiling service, a cross-platform,
// multi-process component. Chrome on Android does not support browser_tests. It
// does support content_browsertests, but those are not multi-process tests. On
// Android, processes have to be started via the Activity mechanism, and the
// test infrastructure does not support this.
//
// To avoid test-code duplication, all tests are pulled into this class.
// browser_tests will directly call this class. The android
// chrome_public_test_apk will invoke this class via a JNI shim. Since the
// latter is not running within the gtest framework, this class cannot use
// EXPECT* and ASSERT* macros. Instead, this class will return a bool indicating
// success of the entire test. On failure, errors will be output via LOG(ERROR).
// These will show up in the browser_tests output stream, and will be captured
// by logcat [the Android logging facility]. The latter is already the canonical
// mechanism for investigating test failures.
//
// Note: Outputting to stderr will not have the desired effect, since that is
// not captured by logcat.
class ProfilingTestDriver {
public:
struct Options {
// The profiling mode to test.
ProfilingProcessHost::Mode mode;
// Whether the caller has already started profiling with the given mode.
// TODO(erikchen): Implement and test the case where this member is false.
// Starting profiling is an asynchronous operation, so this requires adding
// some more plumbing. https://crbug.com/753218.
bool profiling_already_started;
};
ProfilingTestDriver();
~ProfilingTestDriver();
// If this is called on the content::BrowserThread::UI thread, then the
// platform must support nested message loops. [This is currently not
// supported on Android].
//
// Returns whether the test run was successful. Expectation/Assertion failures
// will be printed via LOG(ERROR).
bool RunTest(const Options& options);
private:
// Populates |initialization_success_| with the result of
// |RunInitializationOnUIThread|, and then signals |wait_for_ui_thread_|.
void RunInitializationOnUIThreadAndSignal();
// Starts profiling. Makes allocations.
bool RunInitializationOnUIThread();
// If profiling is expected to already be started, confirm it.
// Otherwise, start profiling with the given mode.
bool CheckOrStartProfiling();
// Performs allocations. These are expected to be profiled.
void MakeTestAllocations();
// Collects a trace that contains a heap dump. The result is stored in
// |serialized_trace_|.
//
// When |synchronous| is true, this method spins a nested message loop. When
// |synchronous| is false, this method posts some tasks that will eventually
// signal |wait_for_ui_thread_|.
void CollectResults(bool synchronous);
bool ValidateBrowserAllocations(base::Value* dump_json);
bool ValidateRendererAllocations(base::Value* dump_json);
Options options_;
// Allocations made by this class. Intentionally leaked, since deallocating
// them would trigger a large number of IPCs, which is slow.
std::vector<char*> leaks_;
// Sum of size of all variadic allocations.
size_t total_variadic_allocations_ = 0;
// Use to make PA allocations, which should also be shimmed.
base::PartitionAllocatorGeneric partition_allocator_;
// Contains nothing until |CollectResults| has been called.
scoped_refptr<base::RefCountedString> serialized_trace_;
// Whether the test was invoked on the ui thread.
bool running_on_ui_thread_ = true;
// Whether an error has occurred.
bool initialization_success_ = false;
base::WaitableEvent wait_for_ui_thread_;
DISALLOW_COPY_AND_ASSIGN(ProfilingTestDriver);
};
} // namespace profiling
#endif // CHROME_BROWSER_PROFILING_HOST_PROFILING_TEST_DRIVER_H_
// Copyright 2017 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/browser/profiling_host/test_android_shim.h"
#include "base/android/jni_string.h"
#include "chrome/browser/profiling_host/profiling_process_host.h"
#include "chrome/browser/profiling_host/profiling_test_driver.h"
#include "jni/TestAndroidShim_jni.h"
using base::android::JavaParamRef;
using base::android::ScopedJavaLocalRef;
static jlong Init(JNIEnv* env, const JavaParamRef<jobject>& obj) {
TestAndroidShim* profiler = new TestAndroidShim(env, obj);
return reinterpret_cast<intptr_t>(profiler);
}
TestAndroidShim::TestAndroidShim(JNIEnv* env, jobject obj) {}
TestAndroidShim::~TestAndroidShim() {}
void TestAndroidShim::Destroy(JNIEnv* env, const JavaParamRef<jobject>& obj) {
delete this;
}
jboolean TestAndroidShim::RunTestForMode(
JNIEnv* env,
const base::android::JavaParamRef<jobject>& obj,
const base::android::JavaParamRef<jstring>& mode) {
profiling::ProfilingTestDriver driver;
profiling::ProfilingTestDriver::Options options;
options.mode = profiling::ProfilingProcessHost::ConvertStringToMode(
base::android::ConvertJavaStringToUTF8(mode));
options.profiling_already_started = true;
return driver.RunTest(options);
}
// Copyright 2017 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 CHROME_BROWSER_PROFILING_HOST_TEST_ANDROID_SHIM_H_
#define CHROME_BROWSER_PROFILING_HOST_TEST_ANDROID_SHIM_H_
#include "base/android/jni_android.h"
#include "base/android/scoped_java_ref.h"
#include "base/macros.h"
// This class implements the native methods of TestAndroidShim.java,
// and acts as a bridge to ProfilingProcessHost. Note that this class is only
// used for testing.
class TestAndroidShim {
public:
TestAndroidShim(JNIEnv* env, jobject obj);
void Destroy(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj);
jboolean RunTestForMode(JNIEnv* env,
const base::android::JavaParamRef<jobject>& obj,
const base::android::JavaParamRef<jstring>&);
private:
~TestAndroidShim();
DISALLOW_COPY_AND_ASSIGN(TestAndroidShim);
};
#endif // CHROME_BROWSER_PROFILING_HOST_TEST_ANDROID_SHIM_H_
......@@ -411,9 +411,11 @@ public class ChromeActivityTestRule<T extends ChromeActivity> extends ActivityTe
* Waits for the activity to fully finish it's native initialization.
*/
public void waitForActivityNativeInitializationComplete() {
CriteriaHelper.pollUiThread(() -> ChromeBrowserInitializer.getInstance(
getActivity()).hasNativeInitializationCompleted(),
"Native initialization never finished", 2 * CriteriaHelper.DEFAULT_MAX_TIME_TO_POLL,
CriteriaHelper.pollUiThread(()
-> ChromeBrowserInitializer.getInstance(getActivity())
.hasNativeInitializationCompleted(),
"Native initialization never finished",
20 * CriteriaHelper.DEFAULT_MAX_TIME_TO_POLL,
CriteriaHelper.DEFAULT_POLLING_INTERVAL);
CriteriaHelper.pollUiThread(() -> getActivity().didFinishNativeInitialization(),
......
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