Chromium Code Reviews| 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..9e80d28e0779782d6046bb442a90108dcc73c5e1 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,49 @@ 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; |
| + |
| + initializeLifecycleCallbacks(application); |
| + } |
| + |
| + /** |
| * Must be called by the main activity when it changes state. |
| * |
| * @param activity Current activity. |
| @@ -176,18 +216,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) { |
|
boliu
2015/10/02 15:51:32
since my non-inline comment were ignored twice, in
timvolodine
2015/10/08 16:13:55
Bo, I didn't ignore your comments and I thought I
boliu
2015/10/08 18:01:30
This doesn't really answer whether this patch is s
timvolodine
2015/10/09 15:46:36
yeah, I have a list of classes using it, need to h
boliu
2015/10/09 15:58:57
Ahh ok. That can definitely happen with real apps
timvolodine
2015/10/09 16:50:36
Right, I was actually trying to avoid this scenari
timvolodine
2015/10/09 16:52:38
Actually, regarding your earlier comment about inc
boliu
2015/10/09 19:29:11
Good point. Which means that deserves a huge comme
boliu
2015/10/09 19:29:11
I skimmed through the bug and still don't quite un
timvolodine
2015/10/12 12:35:43
Yeah, it's a long story I'll try to summarize. The
timvolodine
2015/10/12 12:35:43
It's even stronger than that, what I meant by inva
|
| + 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 +280,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 +304,7 @@ public class ApplicationStatus { |
| * @return The {@link Context} for the {@link Application}. |
| */ |
| public static Context getApplicationContext() { |
| - return sApplication != null ? sApplication.getApplicationContext() : null; |
| + return sApplicationContext; |
| } |
| /** |