diff options
| author | 2012-03-15 16:27:14 -0700 | |
|---|---|---|
| committer | 2012-03-19 18:37:57 -0700 | |
| commit | 9ce685b934b36cc57631e10f7c1e3609e91e3f9c (patch) | |
| tree | 5ab0bc432f26889dcc2205e3e5c4c0ed11477424 | |
| parent | 179239bc6c2c7d09f226c6771735169d2bce98cd (diff) | |
Make immersive mode public & imply update locking
Activity.setImmersive(boolean) / android:immersive="bool" are now public.
In addition, if the foreground activity is immersive then an update lock
will be held on its behalf. This lets applications such as movie players
suppress the display of intrusive notifications, OTA-availability dialogs,
and the like while they are displaying content that ought not to be
rudely interrupted.
The update lock aspect of this mode is *advisory*, not binding -- the
update mechanism is not actually constrained; it simply uses this information
in deciding whether/when to prompt the user. It's more a guideline than
a rule.
Bug 6154438
Change-Id: Ibd3491fc437077f3fa0d9708ed91955121e8c877
| -rw-r--r-- | api/current.txt | 3 | ||||
| -rw-r--r-- | core/java/android/app/Activity.java | 2 | ||||
| -rw-r--r-- | core/java/android/content/pm/ActivityInfo.java | 1 | ||||
| -rw-r--r-- | services/java/com/android/server/am/ActivityManagerService.java | 38 |
4 files changed, 40 insertions, 4 deletions
diff --git a/api/current.txt b/api/current.txt index 3e88e1bd5b9e..e370e2b12d19 100644 --- a/api/current.txt +++ b/api/current.txt @@ -2557,6 +2557,7 @@ package android.app { method public boolean isChangingConfigurations(); method public final boolean isChild(); method public boolean isFinishing(); + method public boolean isImmersive(); method public boolean isTaskRoot(); method public final deprecated android.database.Cursor managedQuery(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String); method public boolean moveTaskToBack(boolean); @@ -2638,6 +2639,7 @@ package android.app { method public final void setFeatureDrawableResource(int, int); method public final void setFeatureDrawableUri(int, android.net.Uri); method public void setFinishOnTouchOutside(boolean); + method public void setImmersive(boolean); method public void setIntent(android.content.Intent); method public final void setProgress(int); method public final void setProgressBarIndeterminate(boolean); @@ -5952,6 +5954,7 @@ package android.content.pm { field public static final int FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS = 256; // 0x100 field public static final int FLAG_FINISH_ON_TASK_LAUNCH = 2; // 0x2 field public static final int FLAG_HARDWARE_ACCELERATED = 512; // 0x200 + field public static final int FLAG_IMMERSIVE = 1024; // 0x400 field public static final int FLAG_MULTIPROCESS = 1; // 0x1 field public static final int FLAG_NO_HISTORY = 128; // 0x80 field public static final int FLAG_STATE_NOT_NEEDED = 16; // 0x10 diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java index 8e8d37d645c9..d006a4807332 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -4318,7 +4318,6 @@ public class Activity extends ContextThemeWrapper * {@link #setImmersive}. * * @see android.content.pm.ActivityInfo#FLAG_IMMERSIVE - * @hide */ public boolean isImmersive() { try { @@ -4341,7 +4340,6 @@ public class Activity extends ContextThemeWrapper * * @see #isImmersive * @see android.content.pm.ActivityInfo#FLAG_IMMERSIVE - * @hide */ public void setImmersive(boolean i) { try { diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java index 0e6694deef2c..5506c7fd54a0 100644 --- a/core/java/android/content/pm/ActivityInfo.java +++ b/core/java/android/content/pm/ActivityInfo.java @@ -155,7 +155,6 @@ public class ActivityInfo extends ComponentInfo */ public static final int FLAG_HARDWARE_ACCELERATED = 0x0200; /** - * @hide * Bit in {@link #flags} corresponding to an immersive activity * that wishes not to be interrupted by notifications. * Applications that hide the system notification bar with diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index cd40cf1a7b96..c21ba965b9e1 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -104,6 +104,7 @@ import android.os.ServiceManager; import android.os.StrictMode; import android.os.SystemClock; import android.os.SystemProperties; +import android.os.UpdateLock; import android.provider.Settings; import android.text.format.Time; import android.util.EventLog; @@ -172,6 +173,7 @@ public final class ActivityManagerService extends ActivityManagerNative static final boolean DEBUG_CONFIGURATION = localLOGV || false; static final boolean DEBUG_POWER = localLOGV || false; static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; + static final boolean DEBUG_IMMERSIVE = localLOGV || true; static final boolean VALIDATE_TOKENS = false; static final boolean SHOW_ACTIVITY_START_TIME = true; @@ -812,6 +814,12 @@ public final class ActivityManagerService extends ActivityManagerNative long mLastWriteTime = 0; /** + * Used to retain an update lock when the foreground activity is in + * immersive mode. + */ + final UpdateLock mUpdateLock = new UpdateLock("immersive"); + + /** * Set to true after the system has finished booting. */ boolean mBooted = false; @@ -1710,6 +1718,21 @@ public final class ActivityManagerService extends ActivityManagerNative if (r != null) { mWindowManager.setFocusedApp(r.appToken, true); } + applyUpdateLockStateLocked(r); + } + } + + final void applyUpdateLockStateLocked(ActivityRecord r) { + final boolean nextState = r != null && r.immersive; + if (mUpdateLock.isHeld() != nextState) { + if (DEBUG_IMMERSIVE) { + Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); + } + if (nextState) { + mUpdateLock.acquire(); + } else { + mUpdateLock.release(); + } } } @@ -6667,11 +6690,24 @@ public final class ActivityManagerService extends ActivityManagerNative public void setImmersive(IBinder token, boolean immersive) { synchronized(this) { - ActivityRecord r = mMainStack.isInStackLocked(token); + final ActivityRecord r = mMainStack.isInStackLocked(token); if (r == null) { throw new IllegalArgumentException(); } r.immersive = immersive; + + // update associated state if we're frontmost + if (r == mMainStack.topRunningActivityLocked(null)) { + long oldId = Binder.clearCallingIdentity(); + try { + if (DEBUG_IMMERSIVE) { + Slog.d(TAG, "Frontmost changed immersion: "+ r); + } + applyUpdateLockStateLocked(r); + } finally { + Binder.restoreCallingIdentity(oldId); + } + } } } |