test_support_android.cc revision 7d4cd473f85ac64c3747c96c277f9e506a0d2246
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdarg.h>
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string.h>
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/android/path_utils.h"
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/singleton.h"
127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/message_loop/message_loop.h"
137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/message_loop/message_pump_android.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/path_service.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/synchronization/waitable_event.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct RunState {
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunState(base::MessagePump::Delegate* delegate, int run_depth)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : delegate(delegate),
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        run_depth(run_depth),
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        should_quit(false) {
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::MessagePump::Delegate* delegate;
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Used to count how many Run() invocations are on the stack.
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int run_depth;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Used to flag that the current Run() invocation should return ASAP.
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool should_quit;
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)RunState* g_state = NULL;
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A singleton WaitableEvent wrapper so we avoid a busy loop in
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// MessagePumpForUIStub. Other platforms use the native event loop which blocks
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// when there are no pending messages.
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Waitable {
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   static Waitable* GetInstance() {
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     return Singleton<Waitable>::get();
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   }
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   // Signals that there are more work to do.
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   void Signal() {
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     waitable_event_.Signal();
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   }
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   // Blocks until more work is scheduled.
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   void Block() {
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     waitable_event_.Wait();
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   }
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   void Quit() {
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     g_state->should_quit = true;
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     Signal();
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   }
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend struct DefaultSingletonTraits<Waitable>;
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Waitable()
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : waitable_event_(false, false) {
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::WaitableEvent waitable_event_;
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(Waitable);
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The MessagePumpForUI implementation for test purpose.
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MessagePumpForUIStub : public base::MessagePumpForUI {
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Start(base::MessagePump::Delegate* delegate) OVERRIDE {
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED() << "The Start() method shouldn't be called in test, using"
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        " Run() method should be used.";
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Run(base::MessagePump::Delegate* delegate) OVERRIDE {
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The following was based on message_pump_glib.cc, except we're using a
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // WaitableEvent since there are no native message loop to use.
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RunState state(delegate, g_state ? g_state->run_depth + 1 : 1);
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RunState* previous_state = g_state;
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    g_state = &state;
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool more_work_is_plausible = true;
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (;;) {
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!more_work_is_plausible) {
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        Waitable::GetInstance()->Block();
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (g_state->should_quit)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          break;
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      more_work_is_plausible = g_state->delegate->DoWork();
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (g_state->should_quit)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::TimeTicks delayed_work_time;
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      more_work_is_plausible |=
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          g_state->delegate->DoDelayedWork(&delayed_work_time);
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (g_state->should_quit)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (more_work_is_plausible)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        continue;
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      more_work_is_plausible = g_state->delegate->DoIdleWork();
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (g_state->should_quit)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      more_work_is_plausible |= !delayed_work_time.is_null();
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    g_state = previous_state;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Quit() OVERRIDE {
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Waitable::GetInstance()->Quit();
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void ScheduleWork() OVERRIDE {
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Waitable::GetInstance()->Signal();
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void ScheduleDelayedWork(
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const base::TimeTicks& delayed_work_time) OVERRIDE {
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Waitable::GetInstance()->Signal();
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~MessagePumpForUIStub() {}
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::MessagePump* CreateMessagePumpForUIStub() {
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return new MessagePumpForUIStub();
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Provides the test path for DIR_MODULE and DIR_ANDROID_APP_DATA.
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GetTestProviderPath(int key, base::FilePath* result) {
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (key) {
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case base::DIR_MODULE: {
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return base::android::GetExternalStorageDirectory(result);
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case base::DIR_ANDROID_APP_DATA: {
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // For tests, app data is put in external storage.
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return base::android::GetExternalStorageDirectory(result);
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InitPathProvider(int key) {
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath path;
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If failed to override the key, that means the way has not been registered.
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (GetTestProviderPath(key, &path) && !PathService::Override(key, path))
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PathService::RegisterProvider(&GetTestProviderPath, key, key + 1);
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base {
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InitAndroidTestLogging() {
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  logging::InitLogging(NULL,
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       logging::LOG_ONLY_TO_SYSTEM_DEBUG_LOG,
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       logging::DONT_LOCK_LOG_FILE,
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       logging::DELETE_OLD_LOG_FILE,
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       logging::DISABLE_DCHECK_FOR_NON_OFFICIAL_RELEASE_BUILDS);
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // To view log output with IDs and timestamps use "adb logcat -v threadtime".
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  logging::SetLogItems(false,    // Process ID
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       false,    // Thread ID
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       false,    // Timestamp
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       false);   // Tick count
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InitAndroidTestPaths() {
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InitPathProvider(DIR_MODULE);
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InitPathProvider(DIR_ANDROID_APP_DATA);
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InitAndroidTestMessageLoop() {
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!MessageLoop::InitMessagePumpForUIFactory(&CreateMessagePumpForUIStub))
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LOG(INFO) << "MessagePumpForUIFactory already set, unable to override.";
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InitAndroidTest() {
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InitAndroidTestLogging();
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InitAndroidTestPaths();
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InitAndroidTestMessageLoop();
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace base
196