diff options
author | wangxianzhu@chromium.org <wangxianzhu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-01 17:20:04 +0000 |
---|---|---|
committer | wangxianzhu@chromium.org <wangxianzhu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-01 17:20:04 +0000 |
commit | 7ed054dbdb861d45a06055483d18d739234efbb1 (patch) | |
tree | 9b384ffd0ebde8890350e1f24f01c491a1e37bab /base/test/test_support_android.cc | |
parent | 3b2b45c0276a8238d1f83e01764d32c5f56cba73 (diff) | |
download | chromium_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
Diffstat (limited to 'base/test/test_support_android.cc')
-rw-r--r-- | base/test/test_support_android.cc | 200 |
1 files changed, 200 insertions, 0 deletions
diff --git a/base/test/test_support_android.cc b/base/test/test_support_android.cc new file mode 100644 index 0000000..5e5a8ae --- /dev/null +++ b/base/test/test_support_android.cc @@ -0,0 +1,200 @@ +// 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 <stdarg.h> +#include <string.h> + +#include "base/file_path.h" +#include "base/logging.h" +#include "base/memory/singleton.h" +#include "base/message_pump_android.h" +#include "base/path_service.h" +#include "base/synchronization/waitable_event.h" + +namespace { + +// The test implementation of AndroidOS stores everything in the following +// directory. +const char* kAndroidTestTempDirectory = "/data/local/tmp"; + +struct RunState { + RunState(base::MessagePump::Delegate* delegate, int run_depth) + : delegate(delegate), + run_depth(run_depth), + should_quit(false) { + } + + base::MessagePump::Delegate* delegate; + + // Used to count how many Run() invocations are on the stack. + int run_depth; + + // Used to flag that the current Run() invocation should return ASAP. + bool should_quit; +}; + +RunState* g_state = NULL; + +// A singleton WaitableEvent wrapper so we avoid a busy loop in +// MessagePumpForUIStub. Other platforms use the native event loop which blocks +// when there are no pending messages. +class Waitable { + public: + static Waitable* GetInstance() { + return Singleton<Waitable>::get(); + } + + // Signals that there are more work to do. + void Signal() { + waitable_event_.Signal(); + } + + // Blocks until more work is scheduled. + void Block() { + waitable_event_.Wait(); + } + + void Quit() { + g_state->should_quit = true; + Signal(); + } + + private: + friend struct DefaultSingletonTraits<Waitable>; + + Waitable() + : waitable_event_(false, false) { + } + + base::WaitableEvent waitable_event_; + + DISALLOW_COPY_AND_ASSIGN(Waitable); +}; + +// The MessagePumpForUI implementation for test purpose. +class MessagePumpForUIStub : public base::MessagePumpForUI { + virtual void Start(base::MessagePump::Delegate* delegate) OVERRIDE { + NOTREACHED() << "The Start() method shouldn't be called in test, using" + " Run() method should be used."; + } + + 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); + + RunState* previous_state = g_state; + g_state = &state; + + bool more_work_is_plausible = true; + + for (;;) { + if (!more_work_is_plausible) { + Waitable::GetInstance()->Block(); + if (g_state->should_quit) + break; + } + + more_work_is_plausible = g_state->delegate->DoWork(); + if (g_state->should_quit) + break; + + base::TimeTicks delayed_work_time; + more_work_is_plausible |= + g_state->delegate->DoDelayedWork(&delayed_work_time); + if (g_state->should_quit) + break; + + if (more_work_is_plausible) + continue; + + more_work_is_plausible = g_state->delegate->DoIdleWork(); + if (g_state->should_quit) + break; + + more_work_is_plausible |= !delayed_work_time.is_null(); + } + + g_state = previous_state; + } + + virtual void Quit() OVERRIDE { + Waitable::GetInstance()->Quit(); + } + + virtual void ScheduleWork() OVERRIDE { + Waitable::GetInstance()->Signal(); + } + + 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 GetTestProviderPath(int key, FilePath* result) { + switch (key) { + case base::DIR_MODULE: { + *result = FilePath(kAndroidTestTempDirectory); + return true; + } +#if !defined(ANDROID_APK_TEST_TARGET) + // When running as executable we need to use /data/local/tmp as the + // cache directory. + case base::DIR_CACHE: { + *result = FilePath(kAndroidTestTempDirectory); + return true; + } +#endif // !defined(ANDROID_APK_TEST_TARGET) + case base::DIR_ANDROID_APP_DATA: { + *result = FilePath(kAndroidTestTempDirectory); + return true; + } + default: + return false; + } +} + +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 InitAndroidTestLogging() { + 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 +} + +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(); +} |