| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 package org.chromium.base; | 5 package org.chromium.base; |
| 6 | 6 |
| 7 import android.app.Activity; | 7 import android.app.Activity; |
| 8 import android.app.Application; | 8 import android.app.Application; |
| 9 import android.app.Application.ActivityLifecycleCallbacks; | 9 import android.app.Application.ActivityLifecycleCallbacks; |
| 10 import android.content.Context; | 10 import android.content.Context; |
| 11 import android.os.Bundle; | 11 import android.os.Bundle; |
| 12 | 12 |
| 13 import java.lang.ref.WeakReference; | 13 import java.lang.ref.WeakReference; |
| 14 import java.util.ArrayList; | 14 import java.util.ArrayList; |
| 15 import java.util.HashMap; | |
| 16 import java.util.List; | 15 import java.util.List; |
| 17 import java.util.Map; | 16 import java.util.Map; |
| 17 import java.util.concurrent.ConcurrentHashMap; |
| 18 | 18 |
| 19 /** | 19 /** |
| 20 * Provides information about the current activity's status, and a way | 20 * Provides information about the current activity's status, and a way |
| 21 * to register / unregister listeners for state changes. | 21 * to register / unregister listeners for state changes. |
| 22 */ | 22 */ |
| 23 @JNINamespace("base::android") | 23 @JNINamespace("base::android") |
| 24 public class ApplicationStatus { | 24 public class ApplicationStatus { |
| 25 private static class ActivityInfo { | 25 private static class ActivityInfo { |
| 26 private int mStatus = ActivityState.DESTROYED; | 26 private int mStatus = ActivityState.DESTROYED; |
| 27 private ObserverList<ActivityStateListener> mListeners = | 27 private ObserverList<ActivityStateListener> mListeners = |
| (...skipping 16 matching lines...) Expand all Loading... |
| 44 /** | 44 /** |
| 45 * @return A list of {@link ActivityStateListener}s listening to this ac
tivity. | 45 * @return A list of {@link ActivityStateListener}s listening to this ac
tivity. |
| 46 */ | 46 */ |
| 47 public ObserverList<ActivityStateListener> getListeners() { | 47 public ObserverList<ActivityStateListener> getListeners() { |
| 48 return mListeners; | 48 return mListeners; |
| 49 } | 49 } |
| 50 } | 50 } |
| 51 | 51 |
| 52 private static Application sApplication; | 52 private static Application sApplication; |
| 53 | 53 |
| 54 private static Object sCachedApplicationStateLock = new Object(); |
| 54 private static Integer sCachedApplicationState; | 55 private static Integer sCachedApplicationState; |
| 55 | 56 |
| 56 /** Last activity that was shown (or null if none or it was destroyed). */ | 57 /** Last activity that was shown (or null if none or it was destroyed). */ |
| 57 private static Activity sActivity; | 58 private static Activity sActivity; |
| 58 | 59 |
| 59 /** A lazily initialized listener that forwards application state changes to
native. */ | 60 /** A lazily initialized listener that forwards application state changes to
native. */ |
| 60 private static ApplicationStateListener sNativeApplicationStateListener; | 61 private static ApplicationStateListener sNativeApplicationStateListener; |
| 61 | 62 |
| 62 /** | 63 /** |
| 63 * A map of which observers listen to state changes from which {@link Activi
ty}. | 64 * A map of which observers listen to state changes from which {@link Activi
ty}. |
| 64 */ | 65 */ |
| 65 private static final Map<Activity, ActivityInfo> sActivityInfo = | 66 private static final Map<Activity, ActivityInfo> sActivityInfo = |
| 66 new HashMap<Activity, ActivityInfo>(); | 67 new ConcurrentHashMap<Activity, ActivityInfo>(); |
| 67 | 68 |
| 68 /** | 69 /** |
| 69 * A list of observers to be notified when any {@link Activity} has a state
change. | 70 * A list of observers to be notified when any {@link Activity} has a state
change. |
| 70 */ | 71 */ |
| 71 private static final ObserverList<ActivityStateListener> sGeneralActivitySta
teListeners = | 72 private static final ObserverList<ActivityStateListener> sGeneralActivitySta
teListeners = |
| 72 new ObserverList<ActivityStateListener>(); | 73 new ObserverList<ActivityStateListener>(); |
| 73 | 74 |
| 74 /** | 75 /** |
| 75 * A list of observers to be notified when the visibility state of this {@li
nk Application} | 76 * A list of observers to be notified when the visibility state of this {@li
nk Application} |
| 76 * changes. See {@link #getStateForApplication()}. | 77 * changes. See {@link #getStateForApplication()}. |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 180 } | 181 } |
| 181 | 182 |
| 182 int oldApplicationState = getStateForApplication(); | 183 int oldApplicationState = getStateForApplication(); |
| 183 | 184 |
| 184 if (newState == ActivityState.CREATED) { | 185 if (newState == ActivityState.CREATED) { |
| 185 assert !sActivityInfo.containsKey(activity); | 186 assert !sActivityInfo.containsKey(activity); |
| 186 sActivityInfo.put(activity, new ActivityInfo()); | 187 sActivityInfo.put(activity, new ActivityInfo()); |
| 187 } | 188 } |
| 188 | 189 |
| 189 // Invalidate the cached application state. | 190 // Invalidate the cached application state. |
| 190 sCachedApplicationState = null; | 191 synchronized (sCachedApplicationStateLock) { |
| 192 sCachedApplicationState = null; |
| 193 } |
| 191 | 194 |
| 192 ActivityInfo info = sActivityInfo.get(activity); | 195 ActivityInfo info = sActivityInfo.get(activity); |
| 193 info.setStatus(newState); | 196 info.setStatus(newState); |
| 194 | 197 |
| 195 // Notify all state observers that are specifically listening to this ac
tivity. | 198 // Notify all state observers that are specifically listening to this ac
tivity. |
| 196 for (ActivityStateListener listener : info.getListeners()) { | 199 for (ActivityStateListener listener : info.getListeners()) { |
| 197 listener.onActivityStateChange(activity, newState); | 200 listener.onActivityStateChange(activity, newState); |
| 198 } | 201 } |
| 199 | 202 |
| 200 // Notify all state observers that are listening globally for all activi
ty state | 203 // Notify all state observers that are listening globally for all activi
ty state |
| (...skipping 27 matching lines...) Expand all Loading... |
| 228 * out of all the activities tracked here, it has most recently gain
ed window focus. | 231 * out of all the activities tracked here, it has most recently gain
ed window focus. |
| 229 */ | 232 */ |
| 230 public static Activity getLastTrackedFocusedActivity() { | 233 public static Activity getLastTrackedFocusedActivity() { |
| 231 return sActivity; | 234 return sActivity; |
| 232 } | 235 } |
| 233 | 236 |
| 234 /** | 237 /** |
| 235 * @return A {@link List} of all non-destroyed {@link Activity}s. | 238 * @return A {@link List} of all non-destroyed {@link Activity}s. |
| 236 */ | 239 */ |
| 237 public static List<WeakReference<Activity>> getRunningActivities() { | 240 public static List<WeakReference<Activity>> getRunningActivities() { |
| 238 ThreadUtils.assertOnUiThread(); | |
| 239 List<WeakReference<Activity>> activities = new ArrayList<WeakReference<A
ctivity>>(); | 241 List<WeakReference<Activity>> activities = new ArrayList<WeakReference<A
ctivity>>(); |
| 240 for (Activity activity : sActivityInfo.keySet()) { | 242 for (Activity activity : sActivityInfo.keySet()) { |
| 241 activities.add(new WeakReference<Activity>(activity)); | 243 activities.add(new WeakReference<Activity>(activity)); |
| 242 } | 244 } |
| 243 return activities; | 245 return activities; |
| 244 } | 246 } |
| 245 | 247 |
| 246 /** | 248 /** |
| 247 * @return The {@link Context} for the {@link Application}. | 249 * @return The {@link Context} for the {@link Application}. |
| 248 */ | 250 */ |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 295 */ | 297 */ |
| 296 public static int getStateForActivity(Activity activity) { | 298 public static int getStateForActivity(Activity activity) { |
| 297 ActivityInfo info = sActivityInfo.get(activity); | 299 ActivityInfo info = sActivityInfo.get(activity); |
| 298 return info != null ? info.getStatus() : ActivityState.DESTROYED; | 300 return info != null ? info.getStatus() : ActivityState.DESTROYED; |
| 299 } | 301 } |
| 300 | 302 |
| 301 /** | 303 /** |
| 302 * @return The state of the application (see {@link ApplicationState}). | 304 * @return The state of the application (see {@link ApplicationState}). |
| 303 */ | 305 */ |
| 304 public static int getStateForApplication() { | 306 public static int getStateForApplication() { |
| 305 if (sCachedApplicationState == null) sCachedApplicationState = determine
ApplicationState(); | 307 synchronized (sCachedApplicationStateLock) { |
| 308 if (sCachedApplicationState == null) { |
| 309 sCachedApplicationState = determineApplicationState(); |
| 310 } |
| 311 } |
| 306 | 312 |
| 307 return sCachedApplicationState.intValue(); | 313 return sCachedApplicationState.intValue(); |
| 308 } | 314 } |
| 309 | 315 |
| 310 /** | 316 /** |
| 311 * Checks whether or not any Activity in this Application is visible to the
user. Note that | 317 * Checks whether or not any Activity in this Application is visible to the
user. Note that |
| 312 * this includes the PAUSED state, which can happen when the Activity is tem
porarily covered | 318 * this includes the PAUSED state, which can happen when the Activity is tem
porarily covered |
| 313 * by another Activity's Fragment (e.g.). | 319 * by another Activity's Fragment (e.g.). |
| 314 * @return Whether any Activity under this Application is visible. | 320 * @return Whether any Activity under this Application is visible. |
| 315 */ | 321 */ |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 433 | 439 |
| 434 if (hasPausedActivity) return ApplicationState.HAS_PAUSED_ACTIVITIES; | 440 if (hasPausedActivity) return ApplicationState.HAS_PAUSED_ACTIVITIES; |
| 435 if (hasStoppedActivity) return ApplicationState.HAS_STOPPED_ACTIVITIES; | 441 if (hasStoppedActivity) return ApplicationState.HAS_STOPPED_ACTIVITIES; |
| 436 return ApplicationState.HAS_DESTROYED_ACTIVITIES; | 442 return ApplicationState.HAS_DESTROYED_ACTIVITIES; |
| 437 } | 443 } |
| 438 | 444 |
| 439 // Called to notify the native side of state changes. | 445 // Called to notify the native side of state changes. |
| 440 // IMPORTANT: This is always called on the main thread! | 446 // IMPORTANT: This is always called on the main thread! |
| 441 private static native void nativeOnApplicationStateChange(int newState); | 447 private static native void nativeOnApplicationStateChange(int newState); |
| 442 } | 448 } |
| OLD | NEW |