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; |
} |
/** |