Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(220)

Side by Side Diff: base/android/activity_status_unittest.cc

Issue 14373019: Add base/android/activity_status.cc (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: formatting Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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/android/jni_android.h"
7 #include "base/bind.h"
8 #include "base/callback_forward.h"
9 #include "base/logging.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "base/message_loop/message_loop_proxy.h"
12 #include "base/run_loop.h"
13 #include "base/synchronization/waitable_event.h"
14 #include "base/threading/thread.h"
15
16 #include "testing/gtest/include/gtest/gtest.h"
17
18 namespace base {
19 namespace android {
20
21 namespace {
22
23 using base::android::ScopedJavaLocalRef;
24
25 // Call org.chromium.base.ActivityStatus.onStateChange() from C++.
26 // |env| is the current JNI environment pointer.
27 // |activity| is a JNI reference to an activity object. Can be NULL
28 // during unit-testing.
29 // |newState| is the new state, as an integer.
30 //
31 // The code below is equivalent to what the JNI generator would output if
32 // ActivityStatus.onStateChange() was tagged with @CalledByNative.
33 // because this is only useful for unit-testing, there is no point in
34 // making this permanent for production code.
35 void Java_ActivityStatus_onStateChange(JNIEnv* env,
36 jobject activity,
37 jint newState) {
38 static const char kActivityStatusClassPath[] =
39 "org/chromium/base/ActivityStatus";
40 static jclass g_ActivityStatus_clazz = NULL;
41 static base::subtle::AtomicWord g_ActivityStatus_onStateChange = 0;
42
43 // Ensure g_ActivityStatus_clazz is initialized
44 if (g_ActivityStatus_clazz == NULL) {
45 g_ActivityStatus_clazz = reinterpret_cast<jclass>(env->NewGlobalRef(
46 base::android::GetClass(env, kActivityStatusClassPath).obj()));
47 DCHECK(g_ActivityStatus_clazz);
48 }
49 jmethodID method_id =
50 base::android::MethodID::LazyGet<base::android::MethodID::TYPE_STATIC>(
51 env,
52 g_ActivityStatus_clazz,
53 "onStateChange",
54 "("
55 "Landroid/app/Activity;"
56 "I"
57 ")"
58 "V",
59 &g_ActivityStatus_onStateChange);
60
61 env->CallStaticVoidMethod(
62 g_ActivityStatus_clazz, method_id, activity, newState);
63 base::android::CheckException(env);
64 }
65
66 // Change the activity state, return true on success, false otherwise.
67 bool ForceActivityStateTo(ActivityState state) {
68 JNIEnv* env = base::android::AttachCurrentThread();
69 if (!env)
70 return false;
71
72 RunLoop run_loop;
73 Java_ActivityStatus_onStateChange(env, NULL, static_cast<int>(state));
74 run_loop.RunUntilIdle();
75 return true;
76 }
77
78 // Used to generate a callback that stores the new state at a given
79 // location.
80 void StoreStateTo(ActivityState* target, ActivityState state) {
81 *target = state;
82 }
83
84 // An invalid ActivityState value.
85 const ActivityState kInvalidActivityState = static_cast<ActivityState>(100);
86
87 // Shared state for the multi-threaded test.
88 // This uses a thread to register for events and listen to them,
89 // while state changes are forced on the main thread.
90 class MultiThreadedTest {
91 public:
92 MultiThreadedTest()
93 : state_(kInvalidActivityState),
94 event_(false, false),
95 thread_("ActivityStatusTest thread"),
96 main_(),
97 listener_(NULL) {}
98
99 void Run() {
100 RunLoop loop;
101
102 // Start the thread and tell it to register for events.
103 thread_.Start();
104 thread_.message_loop()
105 ->PostTask(FROM_HERE,
106 base::Bind(&MultiThreadedTest::RegisterThreadForEvents,
107 base::Unretained(this)));
108
109 // Wait for its completion.
110 event_.Wait();
111
112 // Change state, then wait for the thread to modify state.
113 EXPECT_TRUE(ForceActivityStateTo(ACTIVITY_STATE_CREATED));
114 event_.Wait();
115 EXPECT_EQ(ACTIVITY_STATE_CREATED, state_);
116
117 // Again
118 EXPECT_TRUE(ForceActivityStateTo(ACTIVITY_STATE_DESTROYED));
119 event_.Wait();
120 EXPECT_EQ(ACTIVITY_STATE_DESTROYED, state_);
121 }
122
123 private:
124 void ExpectOnThread() {
125 EXPECT_EQ(thread_.message_loop(), base::MessageLoop::current());
126 }
127
128 void RegisterThreadForEvents() {
129 ExpectOnThread();
130 listener_.reset(new ActivityStatus::Listener(base::Bind(
131 &MultiThreadedTest::StoreStateAndSignal, base::Unretained(this))));
132 EXPECT_TRUE(listener_.get());
133 event_.Signal();
134 }
135
136 void StoreStateAndSignal(ActivityState state) {
137 ExpectOnThread();
138 state_ = state;
139 event_.Signal();
140 }
141
142 ActivityState state_;
143 base::WaitableEvent event_;
144 base::Thread thread_;
145 base::MessageLoop main_;
146 scoped_ptr<ActivityStatus::Listener> listener_;
147 };
148
149 } // namespace
150
151 TEST(ActivityStatusTest, SingleThread) {
152 MessageLoop message_loop;
153
154 ActivityState result = kInvalidActivityState;
155
156 // Create a new listener that stores the new state into |result|
157 // on every state change.
158 scoped_ptr<ActivityStatus::Listener> listener(new ActivityStatus::Listener(
159 base::Bind(&StoreStateTo, base::Unretained(&result))));
160 ASSERT_TRUE(listener.get());
161
162 EXPECT_EQ(kInvalidActivityState, result);
163
164 ASSERT_TRUE(ForceActivityStateTo(ACTIVITY_STATE_CREATED));
165 EXPECT_EQ(ACTIVITY_STATE_CREATED, result);
166
167 ASSERT_TRUE(ForceActivityStateTo(ACTIVITY_STATE_DESTROYED));
168 EXPECT_EQ(ACTIVITY_STATE_DESTROYED, result);
169 }
170
171 TEST(ActivityStatusTest, TwoThreads) {
172 MultiThreadedTest test;
173 test.Run();
174 }
175
176 } // namespace android
177 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698