summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwangxianzhu@chromium.org <wangxianzhu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-01 17:20:04 +0000
committerwangxianzhu@chromium.org <wangxianzhu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-01 17:20:04 +0000
commit7ed054dbdb861d45a06055483d18d739234efbb1 (patch)
tree9b384ffd0ebde8890350e1f24f01c491a1e37bab
parent3b2b45c0276a8238d1f83e01764d32c5f56cba73 (diff)
downloadchromium_src-7ed054dbdb861d45a06055483d18d739234efbb1.zip
chromium_src-7ed054dbdb861d45a06055483d18d739234efbb1.tar.gz
chromium_src-7ed054dbdb861d45a06055483d18d739234efbb1.tar.bz2
Chromium support of running DumpRenderTree as an apk on Android
This is an upstream of chromium-android. The WebKit part is https://bugs.webkit.org/show_bug.cgi?id=86862. TBR=darin (for base/base.gyp) BUG=none TEST=build and run current native tests without error Review URL: https://chromiumcodereview.appspot.com/10408091 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@140046 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--base/base.gyp3
-rw-r--r--base/test/test_stub_android.h14
-rw-r--r--base/test/test_suite.cc17
-rw-r--r--base/test/test_support_android.cc (renamed from base/test/test_stub_android.cc)55
-rw-r--r--base/test/test_support_android.h20
-rwxr-xr-xtesting/android/generate_native_test.py29
-rw-r--r--testing/android/native_test.gyp10
-rw-r--r--testing/android/native_test_launcher.cc64
-rw-r--r--webkit/support/DEPS1
-rw-r--r--webkit/support/platform_support_android.cc31
-rw-r--r--webkit/support/webkit_support.cc13
11 files changed, 151 insertions, 106 deletions
diff --git a/base/base.gyp b/base/base.gyp
index 72bfdc6..4aa3de7 100644
--- a/base/base.gyp
+++ b/base/base.gyp
@@ -458,7 +458,8 @@
'test/test_reg_util_win.h',
'test/test_suite.cc',
'test/test_suite.h',
- 'test/test_stub_android.cc',
+ 'test/test_support_android.cc',
+ 'test/test_support_android.h',
'test/test_switches.cc',
'test/test_switches.h',
'test/test_timeouts.cc',
diff --git a/base/test/test_stub_android.h b/base/test/test_stub_android.h
deleted file mode 100644
index fa897d9..0000000
--- a/base/test/test_stub_android.h
+++ /dev/null
@@ -1,14 +0,0 @@
-// 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.
-
-#ifndef BASE_TEST_TEST_STUB_ANDROID_H_
-#define BASE_TEST_TEST_STUB_ANDROID_H_
-
-// Initialize the Android test environment.
-void InitAndroidTestStub();
-
-// Register path providers for tests.
-void InitAndroidOSPathStub();
-
-#endif // BASE_TEST_TEST_STUB_ANDROID_H_
diff --git a/base/test/test_suite.cc b/base/test/test_suite.cc
index 75e9ff5..83a2549 100644
--- a/base/test/test_suite.cc
+++ b/base/test/test_suite.cc
@@ -28,7 +28,7 @@
#endif
#if defined(OS_ANDROID)
-#include "base/test/test_stub_android.h"
+#include "base/test/test_support_android.h"
#endif
#if defined(TOOLKIT_GTK)
@@ -101,8 +101,13 @@ void TestSuite::PreInitialize(int argc, char** argv,
#elif defined(TOOLKIT_GTK)
gtk_init_check(&argc, &argv);
#endif // defined(TOOLKIT_GTK)
+
+ // On Android when building tests as apks, AtExitManager is created in
+ // testing/android/native_test_wrapper.cc before main() is called.
+#if !defined(ANDROID_APK_TEST_TARGET)
if (create_at_exit_manager)
at_exit_manager_.reset(new base::AtExitManager);
+#endif
// Don't add additional code to this function. Instead add it to
// Initialize(). See bug 6436.
@@ -237,9 +242,8 @@ void TestSuite::Initialize() {
#endif
#if defined(OS_ANDROID)
- InitAndroidTestStub();
-#endif
-
+ InitAndroidTest();
+#else
// Initialize logging.
FilePath exe;
PathService::Get(base::FILE_EXE, &exe);
@@ -253,6 +257,7 @@ void TestSuite::Initialize() {
// We want process and thread IDs because we may have multiple processes.
// Note: temporarily enabled timestamps in an effort to catch bug 6361.
logging::SetLogItems(true, true, true, true);
+#endif // else defined(OS_ANDROID)
CHECK(base::EnableInProcessStackDumping());
#if defined(OS_WIN)
@@ -269,11 +274,7 @@ void TestSuite::Initialize() {
logging::SetLogAssertHandler(UnitTestAssertHandler);
}
-#if !defined(OS_ANDROID)
- // TODO(michaelbai): The icu can not be compiled in Android now, this should
- // be enabled once icu is ready. http://b/5406077.
icu_util::Initialize();
-#endif
CatchMaybeTests();
ResetCommandLine();
diff --git a/base/test/test_stub_android.cc b/base/test/test_support_android.cc
index aaf952e..5e5a8ae 100644
--- a/base/test/test_stub_android.cc
+++ b/base/test/test_support_android.cc
@@ -68,16 +68,18 @@ class Waitable {
}
base::WaitableEvent waitable_event_;
+
+ DISALLOW_COPY_AND_ASSIGN(Waitable);
};
// The MessagePumpForUI implementation for test purpose.
class MessagePumpForUIStub : public base::MessagePumpForUI {
- void Start(base::MessagePump::Delegate* delegate) {
+ virtual void Start(base::MessagePump::Delegate* delegate) OVERRIDE {
NOTREACHED() << "The Start() method shouldn't be called in test, using"
" Run() method should be used.";
}
- void Run(base::MessagePump::Delegate* delegate) {
+ virtual void Run(base::MessagePump::Delegate* delegate) OVERRIDE {
// The following was based on message_pump_glib.cc, except we're using a
// WaitableEvent since there are no native message loop to use.
RunState state(delegate, g_state ? g_state->run_depth + 1 : 1);
@@ -117,21 +119,26 @@ class MessagePumpForUIStub : public base::MessagePumpForUI {
g_state = previous_state;
}
- void Quit() {
+ virtual void Quit() OVERRIDE {
Waitable::GetInstance()->Quit();
}
- void ScheduleWork() {
+ virtual void ScheduleWork() OVERRIDE {
Waitable::GetInstance()->Signal();
}
- void ScheduleDelayedWork(const base::TimeTicks& delayed_work_time) {
+ virtual void ScheduleDelayedWork(
+ const base::TimeTicks& delayed_work_time) OVERRIDE {
Waitable::GetInstance()->Signal();
}
};
+base::MessagePump* CreateMessagePumpForUIStub() {
+ return new MessagePumpForUIStub();
+};
+
// Provides the test path for DIR_MODULE, DIR_CACHE and DIR_ANDROID_APP_DATA.
-bool PathTestProviderAndroid(int key, FilePath* result) {
+bool GetTestProviderPath(int key, FilePath* result) {
switch (key) {
case base::DIR_MODULE: {
*result = FilePath(kAndroidTestTempDirectory);
@@ -154,21 +161,16 @@ bool PathTestProviderAndroid(int key, FilePath* result) {
}
}
-// The factory method to create a MessagePumpForUI.
-base::MessagePump* CreateMessagePumpForUIStub() {
- return new MessagePumpForUIStub();
+void InitPathProvider(int key) {
+ FilePath path;
+ // If failed to override the key, that means the way has not been registered.
+ if (GetTestProviderPath(key, &path) && !PathService::Override(key, path))
+ PathService::RegisterProvider(&GetTestProviderPath, key, key + 1);
}
} // namespace
-void InitAndroidOSPathStub() {
- PathService::Override(base::DIR_MODULE, FilePath(kAndroidTestTempDirectory));
- PathService::Override(base::DIR_CACHE, FilePath(kAndroidTestTempDirectory));
- PathService::Override(base::DIR_ANDROID_APP_DATA,
- FilePath(kAndroidTestTempDirectory));
-}
-
-void InitAndroidTestStub() {
+void InitAndroidTestLogging() {
logging::InitLogging(NULL,
logging::LOG_ONLY_TO_SYSTEM_DEBUG_LOG,
logging::DONT_LOCK_LOG_FILE,
@@ -179,13 +181,20 @@ void InitAndroidTestStub() {
false, // Thread ID
false, // Timestamp
false); // Tick count
+}
- PathService::RegisterProvider(&PathTestProviderAndroid, base::DIR_MODULE,
- base::DIR_MODULE + 1);
- PathService::RegisterProvider(&PathTestProviderAndroid, base::DIR_CACHE,
- base::DIR_CACHE + 1);
- PathService::RegisterProvider(&PathTestProviderAndroid,
- base::DIR_ANDROID_APP_DATA, base::DIR_ANDROID_APP_DATA + 1);
+void InitAndroidTestPaths() {
+ InitPathProvider(base::DIR_MODULE);
+ InitPathProvider(base::DIR_CACHE);
+ InitPathProvider(base::DIR_ANDROID_APP_DATA);
+}
+void InitAndroidTestMessageLoop() {
MessageLoop::InitMessagePumpForUIFactory(&CreateMessagePumpForUIStub);
}
+
+void InitAndroidTest() {
+ InitAndroidTestLogging();
+ InitAndroidTestPaths();
+ InitAndroidTestMessageLoop();
+}
diff --git a/base/test/test_support_android.h b/base/test/test_support_android.h
new file mode 100644
index 0000000..09b188c
--- /dev/null
+++ b/base/test/test_support_android.h
@@ -0,0 +1,20 @@
+// 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.
+
+#ifndef BASE_TEST_TEST_SUPPORT_ANDROID_H_
+#define BASE_TEST_TEST_SUPPORT_ANDROID_H_
+
+// Init logging for tests on Android. Logs will be output into Android's logcat.
+void InitAndroidTestLogging();
+
+// Init path providers for tests on Android.
+void InitAndroidTestPaths();
+
+// Init the message loop for tests on Android.
+void InitAndroidTestMessageLoop();
+
+// Do all of the initializations above.
+void InitAndroidTest();
+
+#endif // BASE_TEST_TEST_SUPPORT_ANDROID_H_
diff --git a/testing/android/generate_native_test.py b/testing/android/generate_native_test.py
index 5fe664a..658a13a 100755
--- a/testing/android/generate_native_test.py
+++ b/testing/android/generate_native_test.py
@@ -137,8 +137,11 @@ class NativeTestApkGenerator(object):
logging.warn('%s --> %s' % (jar, dest))
shutil.copyfile(jar, dest)
- def CreateBundle(self):
+ def CreateBundle(self, ant_compile):
"""Create the apk bundle source and assemble components."""
+ if not ant_compile:
+ self._SOURCE_FILES.append('Android.mk')
+ self._REPLACEME_FILES.append('Android.mk')
self._CopyTemplateFiles()
self._ReplaceStrings()
self._CopyLibraryAndJars()
@@ -162,6 +165,16 @@ class NativeTestApkGenerator(object):
logging.error('Ant return code %d' % p.returncode)
sys.exit(p.returncode)
+ def CompileAndroidMk(self):
+ """Build the generated apk within Android source tree using Android.mk."""
+ try:
+ import compile_android_mk # pylint: disable=F0401
+ except:
+ raise AssertionError('Not in Android source tree. '
+ 'Please use --ant-compile.')
+ compile_android_mk.CompileAndroidMk(self._native_library,
+ self._output_directory)
+
def main(argv):
parser = optparse.OptionParser()
@@ -176,7 +189,9 @@ def main(argv):
parser.add_option('--app_abi', default='armeabi',
help='ABI for native shared library')
parser.add_option('--ant-compile', action='store_true',
- help='If specified, build the generated apk with ant')
+ help='If specified, build the generated apk with ant. '
+ 'Otherwise assume compiling within the Android '
+ 'source tree using Android.mk.')
parser.add_option('--ant-args',
help='extra args for ant')
@@ -195,13 +210,21 @@ def main(argv):
jar_list = []
if options.jars:
jar_list = options.jars.replace('"', '').split()
+
+ # Ignore --ant-compile when building with Android source.
+ if 'ANDROID_BUILD_TOP' in os.environ:
+ options.ant_compile = False
+
ntag = NativeTestApkGenerator(native_library=options.native_library,
jars=jar_list,
output_directory=options.output,
target_abi=options.app_abi)
- ntag.CreateBundle()
+ ntag.CreateBundle(options.ant_compile)
+
if options.ant_compile:
ntag.Compile(options.ant_args)
+ else:
+ ntag.CompileAndroidMk()
logging.warn('COMPLETE.')
diff --git a/testing/android/native_test.gyp b/testing/android/native_test.gyp
index 4b25f7c..3718907 100644
--- a/testing/android/native_test.gyp
+++ b/testing/android/native_test.gyp
@@ -42,9 +42,9 @@
'target_name': 'native_test_native_code',
'message': 'building native pieces of native test package',
'type': 'static_library',
- 'sources': [
- 'native_test_launcher.cc',
- ],
+ 'sources': [
+ 'native_test_launcher.cc',
+ ],
'direct_dependent_settings': {
'ldflags!': [
# JNI_OnLoad is implemented in a .a and we need to
@@ -53,14 +53,14 @@
],
},
'dependencies': [
- 'jni_headers',
'../../base/base.gyp:base',
'../../base/base.gyp:test_support_base',
'../gtest.gyp:gtest',
+ 'native_test_jni_headers',
],
},
{
- 'target_name': 'jni_headers',
+ 'target_name': 'native_test_jni_headers',
'type': 'none',
'actions': [
{
diff --git a/testing/android/native_test_launcher.cc b/testing/android/native_test_launcher.cc
index d8caaaa..06ecd18 100644
--- a/testing/android/native_test_launcher.cc
+++ b/testing/android/native_test_launcher.cc
@@ -26,11 +26,11 @@
#include "base/stringprintf.h"
#include "base/string_tokenizer.h"
#include "base/string_util.h"
-#include "base/test/test_suite.h"
-#include "testing/android/jni/chrome_native_test_activity_jni.h"
+#include "base/test/test_support_android.h"
#include "gtest/gtest.h"
+#include "testing/android/jni/chrome_native_test_activity_jni.h"
-// GTest's main function.
+// The main function of the program to be wrapped as a test apk.
extern int main(int argc, char** argv);
namespace {
@@ -74,7 +74,8 @@ void ParseArgsFromString(const std::string& command_line,
}
void ParseArgsFromCommandLineFile(std::vector<std::string>* args) {
- // The test runner script can write to "/data/local/tmp".
+ // The test runner script writes the command line file in
+ // "/data/local/tmp".
static const char kCommandLineFilePath[] =
"/data/local/tmp/chrome-native-tests-command-line";
FilePath command_line(kCommandLineFilePath);
@@ -158,39 +159,6 @@ void AndroidLogPrinter::OnTestProgramEnd(
LOG(ERROR) << msg;
}
-void LibraryLoadedOnMainThread(JNIEnv* env) {
- static const char* const kInitialArgv[] = { "ChromeTestActivity" };
-
- {
- // We need a test suite to be created before we do any tracing or
- // logging: it creates a global at_exit_manager and initializes
- // internal gtest data structures based on the command line.
- // It needs to be scoped as it also resets the CommandLine.
- std::vector<std::string> args;
- ParseArgsFromCommandLineFile(&args);
- std::vector<char*> argv;
- ArgsToArgv(args, &argv);
- base::TestSuite test_suite(argv.size(), &argv[0]);
- }
-
- CommandLine::Init(arraysize(kInitialArgv), kInitialArgv);
-
- logging::InitLogging(NULL,
- logging::LOG_ONLY_TO_SYSTEM_DEBUG_LOG,
- logging::DONT_LOCK_LOG_FILE,
- logging::DELETE_OLD_LOG_FILE,
- logging::ENABLE_DCHECK_FOR_NON_OFFICIAL_RELEASE_BUILDS);
- // To view log output with IDs and timestamps use "adb logcat -v threadtime".
- logging::SetLogItems(false, // Process ID
- false, // Thread ID
- false, // Timestamp
- false); // Tick count
- VLOG(0) << "Chromium logging enabled: level = " << logging::GetMinLogLevel()
- << ", default verbosity = " << logging::GetVlogVerbosity();
- base::android::RegisterLocaleUtils(env);
- base::android::RegisterPathUtils(env);
-}
-
} // namespace
// This method is called on a separate java thread so that we won't trigger
@@ -199,6 +167,21 @@ static void RunTests(JNIEnv* env,
jobject obj,
jstring jfiles_dir,
jobject app_context) {
+ base::AtExitManager exit_manager;
+
+ static const char* const kInitialArgv[] = { "ChromeTestActivity" };
+ CommandLine::Init(arraysize(kInitialArgv), kInitialArgv);
+
+ // Set the application context in base.
+ base::android::ScopedJavaLocalRef<jobject> scoped_context(
+ env, env->NewLocalRef(app_context));
+ base::android::InitApplicationContext(scoped_context);
+
+ base::android::RegisterLocaleUtils(env);
+ base::android::RegisterPathUtils(env);
+
+ InitAndroidTest();
+
FilePath files_dir(base::android::ConvertJavaStringToUTF8(env, jfiles_dir));
// A few options, such "--gtest_list_tests", will just use printf directly
// and won't use the "AndroidLogPrinter". Redirect stdout to a known file.
@@ -217,17 +200,11 @@ static void RunTests(JNIEnv* env,
AndroidLogPrinter* log = new AndroidLogPrinter();
log->Init(&argc, &argv[0]);
- // Set the application context in base.
- base::android::ScopedJavaLocalRef<jobject> scoped_context(
- env, env->NewLocalRef(app_context));
- base::android::InitApplicationContext(scoped_context);
-
main(argc, &argv[0]);
}
// This is called by the VM when the shared library is first loaded.
JNI_EXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
-
// Install signal handlers to detect crashes.
InstallHandlers();
@@ -236,7 +213,6 @@ JNI_EXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
if (!RegisterNativesImpl(env)) {
return -1;
}
- LibraryLoadedOnMainThread(env);
return JNI_VERSION_1_4;
}
diff --git a/webkit/support/DEPS b/webkit/support/DEPS
index 29ea35e..c110041 100644
--- a/webkit/support/DEPS
+++ b/webkit/support/DEPS
@@ -1,5 +1,6 @@
include_rules = [
"+media",
+ "+net",
"+ui",
"+third_party/libpng",
"+third_party/zlib",
diff --git a/webkit/support/platform_support_android.cc b/webkit/support/platform_support_android.cc
index dd6c914..7298b81 100644
--- a/webkit/support/platform_support_android.cc
+++ b/webkit/support/platform_support_android.cc
@@ -4,34 +4,50 @@
#include "webkit/support/platform_support.h"
+#include "base/android/jni_android.h"
#include "base/file_path.h"
#include "base/file_util.h"
#include "base/logging.h"
#include "base/path_service.h"
#include "base/string16.h"
#include "base/string_piece.h"
-#include "base/test/test_stub_android.h"
+#include "base/test/test_support_android.h"
#include "googleurl/src/gurl.h"
#include "grit/webkit_resources.h"
+#include "net/android/network_library.h"
#include "ui/base/resource/resource_bundle.h"
#include "webkit/support/test_webkit_platform_support.h"
#include "webkit/tools/test_shell/simple_resource_loader_bridge.h"
+namespace {
+
+// The place where the Android layout test script will put the required tools
+// and resources. Must keep consistent with DEVICE_DRT_DIR in
+// WebKit/Tools/Scripts/webkitpy/layout_tests/port/chromium_android.py.
+// TODO(wangxianzhu): Allow running DRT on non-rooted device by putting
+// the tools and resources into the apk or under /data/local/tmp.
+const char kDumpRenderTreeDir[] = "/data/drt";
+
+}
+
namespace webkit_support {
void BeforeInitialize(bool unit_test_mode) {
- InitAndroidOSPathStub();
+ InitAndroidTestPaths();
+
// Set XML_CATALOG_FILES environment variable to blank to prevent libxml from
// loading and complaining the non-exsistent /etc/xml/catalog file.
setenv("XML_CATALOG_FILES", "", 0);
+
+ JNIEnv* env = base::android::AttachCurrentThread();
+ net::android::RegisterNetworkLibrary(env);
}
void AfterInitialize(bool unit_test_mode) {
if (unit_test_mode)
return; // We don't have a resource pack when running the unit-tests.
- FilePath data_path;
- PathService::Get(base::DIR_EXE, &data_path);
+ FilePath data_path(kDumpRenderTreeDir);
data_path = data_path.Append("DumpRenderTree.pak");
ResourceBundle::InitSharedInstanceWithPakFile(data_path);
@@ -64,12 +80,11 @@ string16 TestWebKitPlatformSupport::GetLocalizedString(int message_id) {
base::StringPiece TestWebKitPlatformSupport::GetDataResource(
int resource_id,
ui::ScaleFactor scale_factor) {
- FilePath resources_path;
- PathService::Get(base::DIR_EXE, &resources_path);
+ FilePath resources_path(kDumpRenderTreeDir);
resources_path = resources_path.Append("DumpRenderTree_resources");
switch (resource_id) {
case IDR_BROKENIMAGE: {
- static std::string broken_image_data;
+ CR_DEFINE_STATIC_LOCAL(std::string, broken_image_data, ());
if (broken_image_data.empty()) {
FilePath path = resources_path.Append("missingImage.gif");
bool success = file_util::ReadFileToString(path, &broken_image_data);
@@ -79,7 +94,7 @@ base::StringPiece TestWebKitPlatformSupport::GetDataResource(
return broken_image_data;
}
case IDR_TEXTAREA_RESIZER: {
- static std::string resize_corner_data;
+ CR_DEFINE_STATIC_LOCAL(std::string, resize_corner_data, ());
if (resize_corner_data.empty()) {
FilePath path = resources_path.Append("textAreaResizeCorner.png");
bool success = file_util::ReadFileToString(path, &resize_corner_data);
diff --git a/webkit/support/webkit_support.cc b/webkit/support/webkit_support.cc
index 282ac86..ff3fd40 100644
--- a/webkit/support/webkit_support.cc
+++ b/webkit/support/webkit_support.cc
@@ -71,6 +71,10 @@
#include "webkit/tools/test_shell/simple_file_system.h"
#include "webkit/tools/test_shell/simple_resource_loader_bridge.h"
+#if defined(OS_ANDROID)
+#include "base/test/test_support_android.h"
+#endif
+
using WebKit::WebCString;
using WebKit::WebDevToolsAgentClient;
using WebKit::WebFileSystem;
@@ -104,6 +108,10 @@ void InitLogging() {
}
#endif
+#if defined(OS_ANDROID)
+ // On Android we expect the log to appear in logcat.
+ InitAndroidTestLogging();
+#else
FilePath log_filename;
PathService::Get(base::DIR_EXE, &log_filename);
log_filename = log_filename.AppendASCII("DumpRenderTree.log");
@@ -123,6 +131,7 @@ void InitLogging() {
const bool kTimestamp = true;
const bool kTickcount = true;
logging::SetLogItems(kProcessId, kThreadId, !kTimestamp, kTickcount);
+#endif // else defined(OS_ANDROID)
}
class TestEnvironment {
@@ -272,11 +281,15 @@ void SetUpTestEnvironmentImpl(bool unit_test_mode) {
// at same time.
url_util::Initialize();
base::AtExitManager* at_exit_manager = NULL;
+ // In Android DumpRenderTree, AtExitManager is created in
+ // testing/android/native_test_wrapper.cc before main() is called.
+#if !defined(OS_ANDROID)
// Some initialization code may use a AtExitManager before initializing
// TestEnvironment, so we create a AtExitManager early and pass its ownership
// to TestEnvironment.
if (!unit_test_mode)
at_exit_manager = new base::AtExitManager;
+#endif
webkit_support::BeforeInitialize(unit_test_mode);
test_environment = new TestEnvironment(unit_test_mode, at_exit_manager);
webkit_support::AfterInitialize(unit_test_mode);