diff options
author | tedchoc@chromium.org <tedchoc@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-03 18:27:07 +0000 |
---|---|---|
committer | tedchoc@chromium.org <tedchoc@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-03 18:27:07 +0000 |
commit | 00e0dd70af0ebd8e4d7f85fbb5e1c4df23f19418 (patch) | |
tree | 39cf06f9500be5e4f9495b8f9766f4375fe4d32b /base/android | |
parent | dba9eb05de97710caf483f8c3f6358a25f1ed8e2 (diff) | |
download | chromium_src-00e0dd70af0ebd8e4d7f85fbb5e1c4df23f19418.zip chromium_src-00e0dd70af0ebd8e4d7f85fbb5e1c4df23f19418.tar.gz chromium_src-00e0dd70af0ebd8e4d7f85fbb5e1c4df23f19418.tar.bz2 |
Revert 198124 "Add base/android/activity_status.cc"
> Add base/android/activity_status.cc
>
> This patch adds a small thread-safe wrapper around the Java
> org.chromium.base.ActivityStatus that can be used to listen to activity state
> changes from native code.
>
> This uses a base::ObserverListThreadSafe to guarantee that listeners can be
> registered on any threads, and that their OnActivityStateChange() method will
> always be called on the thread that created them.
>
> + Ensure both C++ and Java always use the same constants when it comes to
> ActivityState values.
>
> TBR=digit@chromium.org
> BUG=233536
>
> Review URL: https://codereview.chromium.org/14767011
TBR=pliard@chromium.org
Review URL: https://codereview.chromium.org/14596005
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@198141 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base/android')
-rw-r--r-- | base/android/activity_state_list.h | 16 | ||||
-rw-r--r-- | base/android/activity_status.cc | 66 | ||||
-rw-r--r-- | base/android/activity_status.h | 97 | ||||
-rw-r--r-- | base/android/activity_status_unittest.cc | 129 | ||||
-rw-r--r-- | base/android/base_jni_registrar.cc | 4 | ||||
-rw-r--r-- | base/android/java/src/org/chromium/base/ActivityState.template | 14 | ||||
-rw-r--r-- | base/android/java/src/org/chromium/base/ActivityStatus.java | 45 |
7 files changed, 8 insertions, 363 deletions
diff --git a/base/android/activity_state_list.h b/base/android/activity_state_list.h deleted file mode 100644 index d2a84dc..0000000 --- a/base/android/activity_state_list.h +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) 2013 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. - -// This file intentionally does not have header guards, it's included -// inside a macro to generate enum. - -#ifndef DEFINE_ACTIVITY_STATE -#error "DEFINE_ACTIVITY_STATE should be defined before including this file" -#endif -DEFINE_ACTIVITY_STATE(CREATED, 1) -DEFINE_ACTIVITY_STATE(STARTED, 2) -DEFINE_ACTIVITY_STATE(RESUMED, 3) -DEFINE_ACTIVITY_STATE(PAUSED, 4) -DEFINE_ACTIVITY_STATE(STOPPED, 5) -DEFINE_ACTIVITY_STATE(DESTROYED, 6) diff --git a/base/android/activity_status.cc b/base/android/activity_status.cc deleted file mode 100644 index 4d0be32..0000000 --- a/base/android/activity_status.cc +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright 2013 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 "base/android/activity_status.h" - -#include <jni.h> - -#include "base/memory/singleton.h" -#include "jni/ActivityStatus_jni.h" - -namespace base { -namespace android { - -ActivityStatus::Listener::Listener( - const ActivityStatus::StateChangeCallback& callback) - : callback_(callback) { - ActivityStatus::GetInstance()->RegisterListener(this); -} - -ActivityStatus::Listener::~Listener() { - ActivityStatus::GetInstance()->UnregisterListener(this); -} - -void ActivityStatus::Listener::Notify(ActivityState state) { - callback_.Run(state); -} - -// static -ActivityStatus* ActivityStatus::GetInstance() { - return Singleton<ActivityStatus, - LeakySingletonTraits<ActivityStatus> >::get(); -} - -static void OnActivityStateChange(JNIEnv* env, jclass clazz, int new_state) { - ActivityStatus* activity_status = ActivityStatus::GetInstance(); - ActivityState activity_state = static_cast<ActivityState>(new_state); - activity_status->OnActivityStateChange(activity_state); -} - -bool ActivityStatus::RegisterBindings(JNIEnv* env) { - return RegisterNativesImpl(env); -} - -ActivityStatus::ActivityStatus() - : observers_(new ObserverListThreadSafe<Listener>()) { - Java_ActivityStatus_registerThreadSafeNativeStateListener( - base::android::AttachCurrentThread()); -} - -ActivityStatus::~ActivityStatus() {} - -void ActivityStatus::RegisterListener(Listener* listener) { - observers_->AddObserver(listener); -} - -void ActivityStatus::UnregisterListener(Listener* listener) { - observers_->RemoveObserver(listener); -} - -void ActivityStatus::OnActivityStateChange(ActivityState new_state) { - observers_->Notify(&ActivityStatus::Listener::Notify, new_state); -} - -} // namespace android -} // namespace base diff --git a/base/android/activity_status.h b/base/android/activity_status.h deleted file mode 100644 index 554340c..0000000 --- a/base/android/activity_status.h +++ /dev/null @@ -1,97 +0,0 @@ -// Copyright 2013 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_ANDROID_ACTIVITY_STATUS_H_ -#define BASE_ANDROID_ACTIVITY_STATUS_H_ - -#include <jni.h> - -#include "base/android/jni_android.h" -#include "base/basictypes.h" -#include "base/memory/ref_counted.h" -#include "base/memory/singleton.h" -#include "base/observer_list_threadsafe.h" - -namespace base { -namespace android { - -// Define activity state values like ACTIVITY_STATE_CREATED in a -// way that ensures they're always the same than their Java counterpart. -enum ActivityState { -#define DEFINE_ACTIVITY_STATE(x, y) ACTIVITY_STATE_##x = y, -#include "base/android/activity_state_list.h" -#undef DEFINE_ACTIVITY_STATE -}; - -// A native helper class to listen to state changes of the current -// Android Activity. This mirrors org.chromium.base.ActivityStatus. -// any thread. -// -// To start listening, create a new instance, passing a callback to a -// function that takes an ActivityState parameter. To stop listening, -// simply delete the listener object. The implementation guarantees -// that the callback will always be called on the thread that created -// the listener. -// -// Example: -// -// void OnActivityStateChange(ActivityState state) { -// ... -// } -// -// // Start listening. -// ActivityStatus::Listener* my_listener = -// new ActivityStatus::Listener(base::Bind(&OnActivityStateChange)); -// -// ... -// -// // Stop listening. -// delete my_listener -// -BASE_EXPORT class ActivityStatus { - public: - typedef base::Callback<void(ActivityState)> StateChangeCallback; - - class Listener { - public: - explicit Listener(const StateChangeCallback& callback); - ~Listener(); - - private: - friend class ActivityStatus; - - void Notify(ActivityState state); - - StateChangeCallback callback_; - - DISALLOW_COPY_AND_ASSIGN(Listener); - }; - - // NOTE: The Java ActivityStatus is a singleton too. - static ActivityStatus* GetInstance(); - - // Internal use: must be public to be called from base_jni_registrar.cc - static bool RegisterBindings(JNIEnv* env); - - // Internal use only: must be public to be called from JNI and unit tests. - void OnActivityStateChange(ActivityState new_state); - - private: - friend struct DefaultSingletonTraits<ActivityStatus>; - - ActivityStatus(); - ~ActivityStatus(); - - void RegisterListener(Listener* listener); - void UnregisterListener(Listener* listener); - - scoped_refptr<ObserverListThreadSafe<Listener> > observers_; - - DISALLOW_COPY_AND_ASSIGN(ActivityStatus); -}; - -} // namespace android -} // namespace base - -#endif // BASE_ANDROID_ACTIVITY_STATUS_H_ diff --git a/base/android/activity_status_unittest.cc b/base/android/activity_status_unittest.cc deleted file mode 100644 index aa6a69f..0000000 --- a/base/android/activity_status_unittest.cc +++ /dev/null @@ -1,129 +0,0 @@ -// Copyright 2013 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 "base/android/activity_status.h" -#include "base/bind.h" -#include "base/callback_forward.h" -#include "base/logging.h" -#include "base/memory/scoped_ptr.h" -#include "base/message_loop/message_loop_proxy.h" -#include "base/run_loop.h" -#include "base/synchronization/waitable_event.h" -#include "base/threading/thread.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace base { -namespace android { - -namespace { - -using base::android::ScopedJavaLocalRef; - -// An invalid ActivityState value. -const ActivityState kInvalidActivityState = static_cast<ActivityState>(100); - -// Used to generate a callback that stores the new state at a given location. -void StoreStateTo(ActivityState* target, ActivityState state) { - *target = state; -} - -void RunTasksUntilIdle() { - RunLoop run_loop; - run_loop.RunUntilIdle(); -} - -// Shared state for the multi-threaded test. -// This uses a thread to register for events and listen to them, while state -// changes are forced on the main thread. -class MultiThreadedTest { - public: - MultiThreadedTest() - : activity_status_(ActivityStatus::GetInstance()), - state_(kInvalidActivityState), - event_(false, false), - thread_("ActivityStatusTest thread"), - main_(), - listener_(NULL) { - } - - void Run() { - // Start the thread and tell it to register for events. - thread_.Start(); - thread_.message_loop() - ->PostTask(FROM_HERE, - base::Bind(&MultiThreadedTest::RegisterThreadForEvents, - base::Unretained(this))); - - // Wait for its completion. - event_.Wait(); - - // Change state, then wait for the thread to modify state. - activity_status_->OnActivityStateChange(ACTIVITY_STATE_CREATED); - event_.Wait(); - EXPECT_EQ(ACTIVITY_STATE_CREATED, state_); - - // Again - activity_status_->OnActivityStateChange(ACTIVITY_STATE_DESTROYED); - event_.Wait(); - EXPECT_EQ(ACTIVITY_STATE_DESTROYED, state_); - } - - private: - void ExpectOnThread() { - EXPECT_EQ(thread_.message_loop(), base::MessageLoop::current()); - } - - void RegisterThreadForEvents() { - ExpectOnThread(); - listener_.reset(new ActivityStatus::Listener(base::Bind( - &MultiThreadedTest::StoreStateAndSignal, base::Unretained(this)))); - EXPECT_TRUE(listener_.get()); - event_.Signal(); - } - - void StoreStateAndSignal(ActivityState state) { - ExpectOnThread(); - state_ = state; - event_.Signal(); - } - - ActivityStatus* const activity_status_; - ActivityState state_; - base::WaitableEvent event_; - base::Thread thread_; - base::MessageLoop main_; - scoped_ptr<ActivityStatus::Listener> listener_; -}; - -} // namespace - -TEST(ActivityStatusTest, SingleThread) { - MessageLoop message_loop; - - ActivityState result = kInvalidActivityState; - - // Create a new listener that stores the new state into |result| on every - // state change. - ActivityStatus::Listener listener( - base::Bind(&StoreStateTo, base::Unretained(&result))); - - EXPECT_EQ(kInvalidActivityState, result); - - ActivityStatus* const activity_status = ActivityStatus::GetInstance(); - activity_status->OnActivityStateChange(ACTIVITY_STATE_CREATED); - RunTasksUntilIdle(); - EXPECT_EQ(ACTIVITY_STATE_CREATED, result); - - activity_status->OnActivityStateChange(ACTIVITY_STATE_DESTROYED); - RunTasksUntilIdle(); - EXPECT_EQ(ACTIVITY_STATE_DESTROYED, result); -} - -TEST(ActivityStatusTest, TwoThreads) { - MultiThreadedTest test; - test.Run(); -} - -} // namespace android -} // namespace base diff --git a/base/android/base_jni_registrar.cc b/base/android/base_jni_registrar.cc index 606ab38..882938b 100644 --- a/base/android/base_jni_registrar.cc +++ b/base/android/base_jni_registrar.cc @@ -4,7 +4,7 @@ #include "base/android/base_jni_registrar.h" -#include "base/android/activity_status.h" +#include "base/basictypes.h" #include "base/android/build_info.h" #include "base/android/cpu_features.h" #include "base/android/important_file_writer_android.h" @@ -13,7 +13,6 @@ #include "base/android/path_service_android.h" #include "base/android/path_utils.h" #include "base/android/thread_utils.h" -#include "base/basictypes.h" #include "base/debug/trace_event.h" #include "base/message_pump_android.h" #include "base/power_monitor/power_monitor_android.h" @@ -22,7 +21,6 @@ namespace base { namespace android { static RegistrationMethod kBaseRegisteredMethods[] = { - { "ActivityStatus", base::android::ActivityStatus::RegisterBindings }, { "BuildInfo", base::android::BuildInfo::RegisterBindings }, { "CpuFeatures", base::android::RegisterCpuFeatures }, { "ImportantFileWriterAndroid", diff --git a/base/android/java/src/org/chromium/base/ActivityState.template b/base/android/java/src/org/chromium/base/ActivityState.template deleted file mode 100644 index adf990a..0000000 --- a/base/android/java/src/org/chromium/base/ActivityState.template +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) 2013 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. - -package org.chromium.base; - -// A simple auto-generated interface used to list the various -// states of an activity as used by both org.chromium.base.ActivityStatus -// and base/android/activity_status.h -interface ActivityState { -#define DEFINE_ACTIVITY_STATE(x,y) public final int x = y; -#include "base/android/activity_state_list.h" -#undef DEFINE_ACTIVITY_STATE -} diff --git a/base/android/java/src/org/chromium/base/ActivityStatus.java b/base/android/java/src/org/chromium/base/ActivityStatus.java index 4747234..7d0ee94 100644 --- a/base/android/java/src/org/chromium/base/ActivityStatus.java +++ b/base/android/java/src/org/chromium/base/ActivityStatus.java @@ -5,25 +5,20 @@ package org.chromium.base; import android.app.Activity; -import android.os.Handler; import android.os.Looper; /** - * Provides information about the current activity's status, and a way - * to register / unregister listeners for state changes. + * Provides information about the parent activity's status. */ -@JNINamespace("base::android") public class ActivityStatus { // Constants matching activity states reported to StateListener.onStateChange - // As an implementation detail, these are now defined in the auto-generated - // ActivityState interface, to be shared with C++. - public static final int CREATED = ActivityState.CREATED; - public static final int STARTED = ActivityState.STARTED; - public static final int RESUMED = ActivityState.RESUMED; - public static final int PAUSED = ActivityState.PAUSED; - public static final int STOPPED = ActivityState.STOPPED; - public static final int DESTROYED = ActivityState.DESTROYED; + public static final int CREATED = 1; + public static final int STARTED = 2; + public static final int RESUMED = 3; + public static final int PAUSED = 4; + public static final int STOPPED = 5; + public static final int DESTROYED = 6; // Current main activity, or null if none. private static Activity sActivity; @@ -107,30 +102,4 @@ public class ActivityStatus { public static void unregisterStateListener(StateListener listener) { sStateListeners.removeObserver(listener); } - - /** - * Registers the single thread-safe native activity status listener. - * This handles the case where the caller is not on the main thread. - * Note that this is used by a leaky singleton object from the native - * side, hence lifecycle management is greatly simplified. - */ - @CalledByNative - private static void registerThreadSafeNativeStateListener() { - ThreadUtils.runOnUiThread(new Runnable () { - @Override - public void run() { - // Register a new listener that calls nativeOnActivityStateChange. - sStateListeners.addObserver(new StateListener() { - @Override - public void onActivityStateChange(int newState) { - nativeOnActivityStateChange(newState); - } - }); - } - }); - } - - // Called to notify the native side of state changes. - // IMPORTANT: This is always called on the main thread! - private static native void nativeOnActivityStateChange(int newState); } |