Index: base/android/java/src/org/chromium/base/ActivityStatus.java |
diff --git a/base/android/java/src/org/chromium/base/ActivityStatus.java b/base/android/java/src/org/chromium/base/ActivityStatus.java |
index 47472342b20946466c13268558b9616c12d1d625..05ce197187c5b02c2d85532bb1ab197a3ae6a9d4 100644 |
--- a/base/android/java/src/org/chromium/base/ActivityStatus.java |
+++ b/base/android/java/src/org/chromium/base/ActivityStatus.java |
@@ -5,8 +5,14 @@ |
package org.chromium.base; |
import android.app.Activity; |
-import android.os.Handler; |
-import android.os.Looper; |
+import android.app.Application; |
+import android.app.Application.ActivityLifecycleCallbacks; |
+import android.os.Bundle; |
+ |
+import com.google.common.annotations.VisibleForTesting; |
+ |
+import java.util.HashMap; |
+import java.util.Map; |
/** |
* Provides information about the current activity's status, and a way |
@@ -28,9 +34,7 @@ public class ActivityStatus { |
// Current main activity, or null if none. |
private static Activity sActivity; |
- // Current main activity's state. This can be set even if sActivity is null, to simplify unit |
- // testing. |
- private static int sActivityState; |
+ private static Map<Activity, Integer> sActivityStates = new HashMap<Activity, Integer>(); |
private static final ObserverList<StateListener> sStateListeners = |
new ObserverList<StateListener>(); |
@@ -49,25 +53,86 @@ public class ActivityStatus { |
private ActivityStatus() {} |
/** |
+ * Initializes the activity status for a specified application. |
+ * |
+ * @param application The application whose status you wish to monitor. |
+ */ |
+ public static void initialize(Application application) { |
+ application.registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() { |
+ @Override |
+ public void onActivityCreated(Activity activity, Bundle savedInstanceState) { |
+ onStateChange(activity, CREATED); |
+ } |
+ |
+ @Override |
+ public void onActivityDestroyed(Activity activity) { |
+ onStateChange(activity, DESTROYED); |
+ } |
+ |
+ @Override |
+ public void onActivityPaused(Activity activity) { |
+ onStateChange(activity, PAUSED); |
+ } |
+ |
+ @Override |
+ public void onActivityResumed(Activity activity) { |
+ onStateChange(activity, RESUMED); |
+ } |
+ |
+ @Override |
+ public void onActivitySaveInstanceState(Activity activity, Bundle outState) {} |
+ |
+ @Override |
+ public void onActivityStarted(Activity activity) { |
+ onStateChange(activity, STARTED); |
+ } |
+ |
+ @Override |
+ public void onActivityStopped(Activity activity) { |
+ onStateChange(activity, STOPPED); |
+ } |
+ }); |
+ } |
+ |
+ /** |
* Must be called by the main activity when it changes state. |
+ * |
+ * <p> |
+ * This is exposed purely for testing as normal usage should rely on the internal behavior |
+ * setup during {@link #initialize(Application)} |
+ * |
* @param activity Current activity. |
* @param newState New state value. |
*/ |
+ @VisibleForTesting |
public static void onStateChange(Activity activity, int newState) { |
+ if (activity == null) throw new IllegalArgumentException("null activity is not supported"); |
+ |
if (sActivity != activity) { |
// ActivityStatus is notified with the CREATED event very late during the main activity |
// creation to avoid making startup performance worse than it is by notifying observers |
// that could do some expensive work. This can lead to non-CREATED events being fired |
// before the CREATED event which is problematic. |
// TODO(pliard): fix http://crbug.com/176837. |
- sActivity = activity; |
+ if (sActivity == null |
+ || newState == CREATED || newState == RESUMED || newState == STARTED) { |
+ sActivity = activity; |
+ } |
} |
- sActivityState = newState; |
- for (StateListener listener : sStateListeners) { |
- listener.onActivityStateChange(newState); |
+ |
+ if (newState != DESTROYED) { |
+ sActivityStates.put(activity, newState); |
+ } else { |
+ sActivityStates.remove(activity); |
} |
- if (newState == DESTROYED) { |
- sActivity = null; |
+ |
+ if (sActivity == activity) { |
+ for (StateListener listener : sStateListeners) { |
+ listener.onActivityStateChange(newState); |
+ } |
+ if (newState == DESTROYED) { |
+ sActivity = null; |
+ } |
} |
} |
@@ -75,7 +140,9 @@ public class ActivityStatus { |
* Indicates that the parent activity is currently paused. |
*/ |
public static boolean isPaused() { |
- return sActivityState == PAUSED; |
+ if (sActivity == null) return false; |
+ Integer currentStatus = sActivityStates.get(sActivity); |
+ return currentStatus != null && currentStatus.intValue() == PAUSED; |
} |
/** |
@@ -86,10 +153,13 @@ public class ActivityStatus { |
} |
/** |
- * Returns the current main application activity's state. |
+ * Returns the current main application activity's state (if no activity is registered, |
+ * then DESTROYED will be returned). |
*/ |
public static int getState() { |
- return sActivityState; |
+ if (sActivity == null) return DESTROYED; |
David Trainor- moved to gerrit
2013/09/12 22:12:32
Can an Activity be considered to be not paused and
Ted C
2013/09/12 23:14:54
Chatted a bit about this an somewhat conflicted.
|
+ Integer currentStatus = sActivityStates.get(sActivity); |
+ return currentStatus != null ? currentStatus.intValue() : DESTROYED; |
} |
/** |