| Index: base/android/java/src/org/chromium/base/ApplicationStatus.java
|
| diff --git a/base/android/java/src/org/chromium/base/ApplicationStatus.java b/base/android/java/src/org/chromium/base/ApplicationStatus.java
|
| index 5035b9cabfb0f182d869d154ced60f290bdcccdc..4e89910d585bfa39b751755a1a7e4b22e4ac1803 100644
|
| --- a/base/android/java/src/org/chromium/base/ApplicationStatus.java
|
| +++ b/base/android/java/src/org/chromium/base/ApplicationStatus.java
|
| @@ -64,6 +64,18 @@ public class ApplicationStatus {
|
| private static ApplicationStateListener sNativeApplicationStateListener;
|
|
|
| /**
|
| + * If true means we are running in an activity lifecycle independent mode,
|
| + * see {@link #initializeActivityIndependent(Application, Context)} for more details.
|
| + */
|
| + private static boolean sActivityLifecycleIndependentMode = false;
|
| +
|
| + /**
|
| + * Context corresponding to sApplication. Note this context can be different from sApplication
|
| + * iself so use sApplicationContext instead of casting sApplication.
|
| + */
|
| + private static Context sApplicationContext;
|
| +
|
| + /**
|
| * A map of which observers listen to state changes from which {@link Activity}.
|
| */
|
| private static final Map<Activity, ActivityInfo> sActivityInfo =
|
| @@ -109,28 +121,13 @@ public class ApplicationStatus {
|
|
|
| /**
|
| * Initializes the activity status for a specified application.
|
| + * This method only registers for ActivityLifecycle changes.
|
| *
|
| * @param application The application whose status you wish to monitor.
|
| */
|
| - public static void initialize(BaseChromiumApplication application) {
|
| + private static void initializeLifecycleCallbacks(Application application) {
|
| sApplication = application;
|
|
|
| - application.registerWindowFocusChangedListener(
|
| - new BaseChromiumApplication.WindowFocusChangedListener() {
|
| - @Override
|
| - public void onWindowFocusChanged(Activity activity, boolean hasFocus) {
|
| - if (!hasFocus || activity == sActivity) return;
|
| -
|
| - int state = getStateForActivity(activity);
|
| -
|
| - if (state != ActivityState.DESTROYED && state != ActivityState.STOPPED) {
|
| - sActivity = activity;
|
| - }
|
| -
|
| - // TODO(dtrainor): Notify of active activity change?
|
| - }
|
| - });
|
| -
|
| application.registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
|
| @Override
|
| public void onActivityCreated(final Activity activity, Bundle savedInstanceState) {
|
| @@ -168,6 +165,57 @@ public class ApplicationStatus {
|
| }
|
|
|
| /**
|
| + * Initializes the activity status for a specified application.
|
| + * The initialization should happen before any activity is created.
|
| + *
|
| + * @param application The application whose status you wish to monitor.
|
| + */
|
| + public static void initialize(BaseChromiumApplication application) {
|
| + sApplicationContext = application.getApplicationContext();
|
| + initializeLifecycleCallbacks(application);
|
| +
|
| + application.registerWindowFocusChangedListener(
|
| + new BaseChromiumApplication.WindowFocusChangedListener() {
|
| + @Override
|
| + public void onWindowFocusChanged(Activity activity, boolean hasFocus) {
|
| + if (!hasFocus || activity == sActivity) return;
|
| +
|
| + int state = getStateForActivity(activity);
|
| +
|
| + if (state != ActivityState.DESTROYED && state != ActivityState.STOPPED) {
|
| + sActivity = activity;
|
| + }
|
| +
|
| + // TODO(dtrainor): Notify of active activity change?
|
| + }
|
| + });
|
| + }
|
| +
|
| +
|
| + /**
|
| + * Initializes ApplicationStatus in "ActivityLifecycleIndependentMode". This mode is
|
| + * different from the regular initialization (@see initialize) in the following ways:
|
| + * 1. Currently doesn't listen to focus changes (hence sActivity is always null).
|
| + * 2. Allows to specify a custom applicationContext and an android application object.
|
| + * 3. Allows to call this method at any time during lifetime of the application.
|
| + */
|
| + public static void initializeActivityIndependent(Application application,
|
| + Context applicationContext) {
|
| + sActivityLifecycleIndependentMode = true;
|
| + sApplicationContext = applicationContext;
|
| +
|
| + // Assume we have running activity (or activity that will be running very soon).
|
| + // This is to handle the case when "initializeActivityIndependent" is executed
|
| + // after the ActivityState.CREATED, ActivityState.STARTED and ActivityState.RESUMED
|
| + // have been dispatched.
|
| + synchronized (sCachedApplicationStateLock) {
|
| + sCachedApplicationState = ApplicationState.HAS_RUNNING_ACTIVITIES;
|
| + }
|
| +
|
| + initializeLifecycleCallbacks(application);
|
| + }
|
| +
|
| + /**
|
| * Must be called by the main activity when it changes state.
|
| *
|
| * @param activity Current activity.
|
| @@ -176,18 +224,25 @@ public class ApplicationStatus {
|
| private static void onStateChange(Activity activity, int newState) {
|
| if (activity == null) throw new IllegalArgumentException("null activity is not supported");
|
|
|
| - if (sActivity == null
|
| - || newState == ActivityState.CREATED
|
| - || newState == ActivityState.RESUMED
|
| - || newState == ActivityState.STARTED) {
|
| - sActivity = activity;
|
| - }
|
| -
|
| int oldApplicationState = getStateForApplication();
|
|
|
| - if (newState == ActivityState.CREATED) {
|
| - assert !sActivityInfo.containsKey(activity);
|
| - sActivityInfo.put(activity, new ActivityInfo());
|
| + if (sActivityLifecycleIndependentMode) {
|
| + assert sActivity == null;
|
| + if (!sActivityInfo.containsKey(activity)) {
|
| + sActivityInfo.put(activity, new ActivityInfo());
|
| + }
|
| + } else {
|
| + if (sActivity == null
|
| + || newState == ActivityState.CREATED
|
| + || newState == ActivityState.RESUMED
|
| + || newState == ActivityState.STARTED) {
|
| + sActivity = activity;
|
| + }
|
| +
|
| + if (newState == ActivityState.CREATED) {
|
| + assert !sActivityInfo.containsKey(activity);
|
| + sActivityInfo.put(activity, new ActivityInfo());
|
| + }
|
| }
|
|
|
| // Invalidate the cached application state.
|
| @@ -233,8 +288,12 @@ public class ApplicationStatus {
|
| /**
|
| * @return The most recent focused {@link Activity} tracked by this class. Being focused means
|
| * out of all the activities tracked here, it has most recently gained window focus.
|
| + * Note that in 'sActivityLifecycleIndependentMode' the returned Activity is currently
|
| + * always null (see crbug.com/538175).
|
| */
|
| public static Activity getLastTrackedFocusedActivity() {
|
| + // sActivityLifecycleIndependentMode implies sActivity == null
|
| + assert !sActivityLifecycleIndependentMode || sActivity == null;
|
| return sActivity;
|
| }
|
|
|
| @@ -253,7 +312,7 @@ public class ApplicationStatus {
|
| * @return The {@link Context} for the {@link Application}.
|
| */
|
| public static Context getApplicationContext() {
|
| - return sApplication != null ? sApplication.getApplicationContext() : null;
|
| + return sApplicationContext;
|
| }
|
|
|
| /**
|
|
|