Home | History | Annotate | Download | only in android
      1 // Copyright 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "base/android/activity_status.h"
      6 #include "base/bind.h"
      7 #include "base/callback_forward.h"
      8 #include "base/logging.h"
      9 #include "base/memory/scoped_ptr.h"
     10 #include "base/message_loop/message_loop_proxy.h"
     11 #include "base/run_loop.h"
     12 #include "base/synchronization/waitable_event.h"
     13 #include "base/threading/thread.h"
     14 #include "testing/gtest/include/gtest/gtest.h"
     15 
     16 namespace base {
     17 namespace android {
     18 
     19 namespace {
     20 
     21 using base::android::ScopedJavaLocalRef;
     22 
     23 // An invalid ActivityState value.
     24 const ActivityState kInvalidActivityState = static_cast<ActivityState>(100);
     25 
     26 // Used to generate a callback that stores the new state at a given location.
     27 void StoreStateTo(ActivityState* target, ActivityState state) {
     28   *target = state;
     29 }
     30 
     31 void RunTasksUntilIdle() {
     32   RunLoop run_loop;
     33   run_loop.RunUntilIdle();
     34 }
     35 
     36 // Shared state for the multi-threaded test.
     37 // This uses a thread to register for events and listen to them, while state
     38 // changes are forced on the main thread.
     39 class MultiThreadedTest {
     40  public:
     41   MultiThreadedTest()
     42       : activity_status_(ActivityStatus::GetInstance()),
     43         state_(kInvalidActivityState),
     44         event_(false, false),
     45         thread_("ActivityStatusTest thread"),
     46         main_() {
     47   }
     48 
     49   void Run() {
     50     // Start the thread and tell it to register for events.
     51     thread_.Start();
     52     thread_.message_loop()
     53         ->PostTask(FROM_HERE,
     54                    base::Bind(&MultiThreadedTest::RegisterThreadForEvents,
     55                               base::Unretained(this)));
     56 
     57     // Wait for its completion.
     58     event_.Wait();
     59 
     60     // Change state, then wait for the thread to modify state.
     61     activity_status_->OnActivityStateChange(ACTIVITY_STATE_CREATED);
     62     event_.Wait();
     63     EXPECT_EQ(ACTIVITY_STATE_CREATED, state_);
     64 
     65     // Again
     66     activity_status_->OnActivityStateChange(ACTIVITY_STATE_DESTROYED);
     67     event_.Wait();
     68     EXPECT_EQ(ACTIVITY_STATE_DESTROYED, state_);
     69   }
     70 
     71  private:
     72   void ExpectOnThread() {
     73     EXPECT_EQ(thread_.message_loop(), base::MessageLoop::current());
     74   }
     75 
     76   void RegisterThreadForEvents() {
     77     ExpectOnThread();
     78     listener_.reset(new ActivityStatus::Listener(base::Bind(
     79         &MultiThreadedTest::StoreStateAndSignal, base::Unretained(this))));
     80     EXPECT_TRUE(listener_.get());
     81     event_.Signal();
     82   }
     83 
     84   void StoreStateAndSignal(ActivityState state) {
     85     ExpectOnThread();
     86     state_ = state;
     87     event_.Signal();
     88   }
     89 
     90   ActivityStatus* const activity_status_;
     91   ActivityState state_;
     92   base::WaitableEvent event_;
     93   base::Thread thread_;
     94   base::MessageLoop main_;
     95   scoped_ptr<ActivityStatus::Listener> listener_;
     96 };
     97 
     98 }  // namespace
     99 
    100 TEST(ActivityStatusTest, SingleThread) {
    101   MessageLoop message_loop;
    102 
    103   ActivityState result = kInvalidActivityState;
    104 
    105   // Create a new listener that stores the new state into |result| on every
    106   // state change.
    107   ActivityStatus::Listener listener(
    108       base::Bind(&StoreStateTo, base::Unretained(&result)));
    109 
    110   EXPECT_EQ(kInvalidActivityState, result);
    111 
    112   ActivityStatus* const activity_status = ActivityStatus::GetInstance();
    113   activity_status->OnActivityStateChange(ACTIVITY_STATE_CREATED);
    114   RunTasksUntilIdle();
    115   EXPECT_EQ(ACTIVITY_STATE_CREATED, result);
    116 
    117   activity_status->OnActivityStateChange(ACTIVITY_STATE_DESTROYED);
    118   RunTasksUntilIdle();
    119   EXPECT_EQ(ACTIVITY_STATE_DESTROYED, result);
    120 }
    121 
    122 TEST(ActivityStatusTest, TwoThreads) {
    123   MultiThreadedTest test;
    124   test.Run();
    125 }
    126 
    127 }  // namespace android
    128 }  // namespace base
    129