| 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..e449b38d829f182bc25e8b948f36f08c5bc51d48 100644
|
| --- a/base/android/java/src/org/chromium/base/ActivityStatus.java
|
| +++ b/base/android/java/src/org/chromium/base/ActivityStatus.java
|
| @@ -5,8 +5,12 @@
|
| 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 java.util.HashMap;
|
| +import java.util.Map;
|
|
|
| /**
|
| * Provides information about the current activity's status, and a way
|
| @@ -25,15 +29,14 @@ public class ActivityStatus {
|
| public static final int STOPPED = ActivityState.STOPPED;
|
| public static final int DESTROYED = ActivityState.DESTROYED;
|
|
|
| - // Current main activity, or null if none.
|
| + // Last activity that was shown (or null if none or it was destroyed).
|
| 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 final Map<Activity, Integer> sActivityStates
|
| + = new HashMap<Activity, Integer>();
|
|
|
| - private static final ObserverList<StateListener> sStateListeners =
|
| - new ObserverList<StateListener>();
|
| + private static final ObserverList<StateListener> sStateListeners
|
| + = new ObserverList<StateListener>();
|
|
|
| /**
|
| * Interface to be implemented by listeners.
|
| @@ -49,47 +52,163 @@ 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.
|
| + *
|
| * @param activity Current activity.
|
| * @param newState New state value.
|
| */
|
| + // TODO(tedchoc): Make this method private (and remove @Deprecated) once all downstream usages
|
| + // move to the initialize method.
|
| + @Deprecated
|
| 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;
|
| + }
|
| }
|
| }
|
|
|
| /**
|
| - * Indicates that the parent activity is currently paused.
|
| + * Testing method to update the state of the specified activity.
|
| + */
|
| + public static void onStateChangeForTesting(Activity activity, int newState) {
|
| + onStateChange(activity, newState);
|
| + }
|
| +
|
| + /**
|
| + * Indicates that the current activity is paused.
|
| + *
|
| + * Use explicit state checking instead.
|
| */
|
| + @Deprecated
|
| public static boolean isPaused() {
|
| - return sActivityState == PAUSED;
|
| + if (sActivity == null) return false;
|
| + Integer currentStatus = sActivityStates.get(sActivity);
|
| + return currentStatus != null && currentStatus.intValue() == PAUSED;
|
| }
|
|
|
| /**
|
| - * Returns the current main application activity.
|
| + * @return The current activity.
|
| */
|
| public static Activity getActivity() {
|
| return sActivity;
|
| }
|
|
|
| /**
|
| - * Returns the current main application activity's state.
|
| + * @return The current activity's state (if no activity is registered, then DESTROYED will
|
| + * be returned).
|
| */
|
| public static int getState() {
|
| - return sActivityState;
|
| + return getStateForActivity(sActivity);
|
| + }
|
| +
|
| + /**
|
| + * Query the state for a given activity. If the activity is not being tracked, this will
|
| + * return {@link #DESTROYED}.
|
| + *
|
| + * <p>
|
| + * When relying on this method, be familiar with the expected life cycle state
|
| + * transitions:
|
| + * <a href="http://developer.android.com/guide/components/activities.html#Lifecycle">
|
| + * Activity Lifecycle
|
| + * </a>
|
| + *
|
| + * <p>
|
| + * During activity transitions (activity B launching in front of activity A), A will completely
|
| + * paused before the creation of activity B begins.
|
| + *
|
| + * <p>
|
| + * A basic flow for activity A starting, followed by activity B being opened and then closed:
|
| + * <ul>
|
| + * <li> -- Starting Activity A --
|
| + * <li> Activity A - CREATED
|
| + * <li> Activity A - STARTED
|
| + * <li> Activity A - RESUMED
|
| + * <li> -- Staring Activity B --
|
| + * <li> Activity A - PAUSED
|
| + * <li> Activity B - CREATED
|
| + * <li> Activity B - STARTED
|
| + * <li> Activity B - RESUMED
|
| + * <li> Activity A - STOPPED
|
| + * <li> -- Closing Activity B, Activity A regaining focus --
|
| + * <li> Activity B - PAUSED
|
| + * <li> Activity A - STARTED
|
| + * <li> Activity A - RESUMED
|
| + * <li> Activity B - STOPPED
|
| + * <li> Activity B - DESTROYED
|
| + * </ul>
|
| + *
|
| + * @param activity The activity whose state is to be returned.
|
| + * @return The state of the specified activity.
|
| + */
|
| + public static int getStateForActivity(Activity activity) {
|
| + Integer currentStatus = sActivityStates.get(activity);
|
| + return currentStatus != null ? currentStatus.intValue() : DESTROYED;
|
| }
|
|
|
| /**
|
|
|