summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCraig Mautner <cmautner@google.com>2012-10-05 14:45:52 -0700
committerCraig Mautner <cmautner@google.com>2012-10-06 13:09:58 -0700
commit5962b12bedc4a1d0354816c1cd6b06ba04f6d807 (patch)
treeb9918fad07cf0e0ff84d510b6e17b31cf48394f9
parent88400d3a31139c40c4014faf86c243647087ef6c (diff)
downloadframeworks_base-5962b12bedc4a1d0354816c1cd6b06ba04f6d807.zip
frameworks_base-5962b12bedc4a1d0354816c1cd6b06ba04f6d807.tar.gz
frameworks_base-5962b12bedc4a1d0354816c1cd6b06ba04f6d807.tar.bz2
Adds showWhenLocked attribute to Activities.
The new attribute allows an Activity such as the alarm to appear on all users screens. Bug: 7213805 fixed. Change-Id: If7866b13d88c04af07debc69e0e875d0adc6050a
-rw-r--r--api/17.txt1
-rw-r--r--api/current.txt1
-rw-r--r--core/java/android/content/pm/ActivityInfo.java8
-rw-r--r--core/java/android/content/pm/PackageParser.java8
-rw-r--r--core/java/android/view/IWindowManager.aidl2
-rw-r--r--core/java/android/view/WindowManager.java3
-rw-r--r--core/res/res/values/attrs_manifest.xml5
-rw-r--r--core/res/res/values/public.xml12
-rw-r--r--services/java/com/android/server/am/ActivityManagerService.java1
-rwxr-xr-xservices/java/com/android/server/am/ActivityStack.java23
-rw-r--r--services/java/com/android/server/wm/AppWindowToken.java1
-rwxr-xr-xservices/java/com/android/server/wm/WindowManagerService.java5
-rw-r--r--services/java/com/android/server/wm/WindowState.java15
-rw-r--r--services/java/com/android/server/wm/WindowStateAnimator.java2
-rw-r--r--tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java2
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java3
16 files changed, 69 insertions, 23 deletions
diff --git a/api/17.txt b/api/17.txt
index e86de90..d7f7c3c 100644
--- a/api/17.txt
+++ b/api/17.txt
@@ -912,6 +912,7 @@ package android {
field public static final int showAsAction = 16843481; // 0x10102d9
field public static final int showDefault = 16843258; // 0x10101fa
field public static final int showDividers = 16843561; // 0x1010329
+ field public static final int showOnLockScreen = 16843721; // 0x10103c9
field public static final int showSilent = 16843259; // 0x10101fb
field public static final int showWeekNumber = 16843582; // 0x101033e
field public static final int shownWeekCount = 16843585; // 0x1010341
diff --git a/api/current.txt b/api/current.txt
index e86de90..d7f7c3c 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -912,6 +912,7 @@ package android {
field public static final int showAsAction = 16843481; // 0x10102d9
field public static final int showDefault = 16843258; // 0x10101fa
field public static final int showDividers = 16843561; // 0x1010329
+ field public static final int showOnLockScreen = 16843721; // 0x10103c9
field public static final int showSilent = 16843259; // 0x10101fb
field public static final int showWeekNumber = 16843582; // 0x101033e
field public static final int shownWeekCount = 16843585; // 0x1010341
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java
index b884b98..e2ca1dd 100644
--- a/core/java/android/content/pm/ActivityInfo.java
+++ b/core/java/android/content/pm/ActivityInfo.java
@@ -155,6 +155,12 @@ public class ActivityInfo extends ComponentInfo
*/
public static final int FLAG_HARDWARE_ACCELERATED = 0x0200;
/**
+ * Value for {@link #flags}: true when the application can be displayed over the lockscreen
+ * and consequently over all users' windows.
+ * @hide
+ */
+ public static final int FLAG_SHOW_ON_LOCK_SCREEN = 0x0400;
+ /**
* @hide
* Bit in {@link #flags} corresponding to an immersive activity
* that wishes not to be interrupted by notifications.
@@ -170,7 +176,7 @@ public class ActivityInfo extends ComponentInfo
* "toast" window).
* {@see android.app.Notification#FLAG_HIGH_PRIORITY}
*/
- public static final int FLAG_IMMERSIVE = 0x0400;
+ public static final int FLAG_IMMERSIVE = 0x0800;
/**
* @hide Bit in {@link #flags}: If set, this component will only be seen
* by the primary user. Only works with broadcast receivers. Set from the
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index c2b75f4..3e8c2a8 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -2160,11 +2160,17 @@ public class PackageParser {
}
if (sa.getBoolean(
+ com.android.internal.R.styleable.AndroidManifestActivity_showOnLockScreen,
+ false)) {
+ a.info.flags |= ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN;
+ }
+
+ if (sa.getBoolean(
com.android.internal.R.styleable.AndroidManifestActivity_immersive,
false)) {
a.info.flags |= ActivityInfo.FLAG_IMMERSIVE;
}
-
+
if (!receiver) {
if (sa.getBoolean(
com.android.internal.R.styleable.AndroidManifestActivity_hardwareAccelerated,
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index a64cbf7..97202b4 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -74,7 +74,7 @@ interface IWindowManager
void addWindowToken(IBinder token, int type);
void removeWindowToken(IBinder token);
void addAppToken(int addPos, IApplicationToken token,
- int groupId, int requestedOrientation, boolean fullscreen);
+ int groupId, int requestedOrientation, boolean fullscreen, boolean showWhenLocked);
void setAppGroupId(IBinder token, int groupId);
void setAppOrientation(IApplicationToken token, int requestedOrientation);
int getAppOrientation(IApplicationToken token);
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index eb3f72e..4c97414 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -219,12 +219,14 @@ public interface WindowManager extends ViewManager {
* Window type: an application window that serves as the "base" window
* of the overall application; all other application windows will
* appear on top of it.
+ * In multiuser systems shows only on the owning user's window.
*/
public static final int TYPE_BASE_APPLICATION = 1;
/**
* Window type: a normal application window. The {@link #token} must be
* an Activity token identifying who the window belongs to.
+ * In multiuser systems shows only on the owning user's window.
*/
public static final int TYPE_APPLICATION = 2;
@@ -233,6 +235,7 @@ public interface WindowManager extends ViewManager {
* application is starting. Not for use by applications themselves;
* this is used by the system to display something until the
* application can show its own windows.
+ * In multiuser systems shows on all users' windows.
*/
public static final int TYPE_APPLICATION_STARTING = 3;
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 58b6572..d899e9d 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -444,6 +444,10 @@
recently launched activities. -->
<attr name="excludeFromRecents" format="boolean" />
+ <!-- Specify that an Activity should be shown over the lock screen and,
+ in a multiuser environment, across all users' windows -->
+ <attr name="showOnLockScreen" format="boolean" />
+
<!-- Specify the authorities under which this content provider can be
found. Multiple authorities may be supplied by separating them
with a semicolon. Authority names should use a Java-style naming
@@ -1376,6 +1380,7 @@
<attr name="alwaysRetainTaskState" />
<attr name="stateNotNeeded" />
<attr name="excludeFromRecents" />
+ <attr name="showOnLockScreen" />
<!-- Specify whether the activity is enabled or not (that is, can be instantiated by the system).
It can also be specified for an application as a whole, in which case a value of "false"
will override any component specific values (a value of "true" will not override the
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index ffc09de..d7a480b 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2018,10 +2018,12 @@
<public type="attr" name="permissionGroupFlags" id="0x010103c5" />
<public type="attr" name="labelFor" id="0x010103c6" />
<public type="attr" name="permissionFlags" id="0x010103c7" />
- <public type="attr" name="checkedTextViewStyle" />
- <public type="style" name="Widget.Holo.CheckedTextView" />
- <public type="style" name="Widget.Holo.Light.CheckedTextView" />
- <public type="style" name="Widget.DeviceDefault.CheckedTextView" />
- <public type="style" name="Widget.DeviceDefault.Light.CheckedTextView" />
+ <public type="attr" name="checkedTextViewStyle" id="0x010103c8" />
+ <public type="attr" name="showOnLockScreen" id="0x010103c9" />
+
+ <public type="style" name="Widget.Holo.CheckedTextView" id="0x010301d9" />
+ <public type="style" name="Widget.Holo.Light.CheckedTextView" id="0x010301da" />
+ <public type="style" name="Widget.DeviceDefault.CheckedTextView" id="0x010301db" />
+ <public type="style" name="Widget.DeviceDefault.Light.CheckedTextView" id="0x010301dc" />
</resources>
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 3ef6767..dcdde76 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -7453,6 +7453,7 @@ public final class ActivityManagerService extends ActivityManagerNative
lp.format = v.getBackground().getOpacity();
lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
+ lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
((WindowManager)mContext.getSystemService(
Context.WINDOW_SERVICE)).addView(v, lp);
}
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index a6dc867..4bcb339 100755
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -420,12 +420,17 @@ final class ActivityStack {
mLaunchingActivity = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Launch");
mLaunchingActivity.setReferenceCounted(false);
}
-
+
+ private boolean okToShow(ActivityRecord r) {
+ return r.userId == mCurrentUser
+ || (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0;
+ }
+
final ActivityRecord topRunningActivityLocked(ActivityRecord notTop) {
int i = mHistory.size()-1;
while (i >= 0) {
ActivityRecord r = mHistory.get(i);
- if (!r.finishing && r != notTop && r.userId == mCurrentUser) {
+ if (!r.finishing && r != notTop && okToShow(r)) {
return r;
}
i--;
@@ -437,7 +442,7 @@ final class ActivityStack {
int i = mHistory.size()-1;
while (i >= 0) {
ActivityRecord r = mHistory.get(i);
- if (!r.finishing && !r.delayedResume && r != notTop && r.userId == mCurrentUser) {
+ if (!r.finishing && !r.delayedResume && r != notTop && okToShow(r)) {
return r;
}
i--;
@@ -460,7 +465,7 @@ final class ActivityStack {
ActivityRecord r = mHistory.get(i);
// Note: the taskId check depends on real taskId fields being non-zero
if (!r.finishing && (token != r.appToken) && (taskId != r.task.taskId)
- && r.userId == mCurrentUser) {
+ && okToShow(r)) {
return r;
}
i--;
@@ -1806,7 +1811,8 @@ final class ActivityStack {
mHistory.add(addPos, r);
r.putInHistory();
mService.mWindowManager.addAppToken(addPos, r.appToken, r.task.taskId,
- r.info.screenOrientation, r.fullscreen);
+ r.info.screenOrientation, r.fullscreen,
+ (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0);
if (VALIDATE_TOKENS) {
validateAppTokensLocked();
}
@@ -1870,7 +1876,8 @@ final class ActivityStack {
}
r.updateOptionsLocked(options);
mService.mWindowManager.addAppToken(
- addPos, r.appToken, r.task.taskId, r.info.screenOrientation, r.fullscreen);
+ addPos, r.appToken, r.task.taskId, r.info.screenOrientation, r.fullscreen,
+ (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0);
boolean doShow = true;
if (newTask) {
// Even though this activity is starting fresh, we still need
@@ -1908,7 +1915,8 @@ final class ActivityStack {
// If this is the first activity, don't do any fancy animations,
// because there is nothing for it to animate on top of.
mService.mWindowManager.addAppToken(addPos, r.appToken, r.task.taskId,
- r.info.screenOrientation, r.fullscreen);
+ r.info.screenOrientation, r.fullscreen,
+ (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0);
ActivityOptions.abort(options);
}
if (VALIDATE_TOKENS) {
@@ -2616,7 +2624,6 @@ final class ActivityStack {
Bundle options) {
final Intent intent = r.intent;
final int callingUid = r.launchedFromUid;
- final int userId = r.userId;
int launchFlags = intent.getFlags();
diff --git a/services/java/com/android/server/wm/AppWindowToken.java b/services/java/com/android/server/wm/AppWindowToken.java
index 13b072c..7efffe5 100644
--- a/services/java/com/android/server/wm/AppWindowToken.java
+++ b/services/java/com/android/server/wm/AppWindowToken.java
@@ -50,6 +50,7 @@ class AppWindowToken extends WindowToken {
int groupId = -1;
boolean appFullscreen;
int requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
+ boolean showWhenLocked;
// The input dispatching timeout for this application token in nanoseconds.
long inputDispatchingTimeoutNanos;
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 1b1d85b..e670028 100755
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -3703,7 +3703,7 @@ public class WindowManagerService extends IWindowManager.Stub
@Override
public void addAppToken(int addPos, IApplicationToken token,
- int groupId, int requestedOrientation, boolean fullscreen) {
+ int groupId, int requestedOrientation, boolean fullscreen, boolean showWhenLocked) {
if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
"addAppToken()")) {
throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
@@ -3733,6 +3733,7 @@ public class WindowManagerService extends IWindowManager.Stub
atoken.inputDispatchingTimeoutNanos = inputDispatchingTimeoutNanos;
atoken.groupId = groupId;
atoken.appFullscreen = fullscreen;
+ atoken.showWhenLocked = showWhenLocked;
atoken.requestedOrientation = requestedOrientation;
if (DEBUG_TOKEN_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG, "addAppToken: " + atoken
+ " at " + addPos);
@@ -5411,7 +5412,7 @@ public class WindowManagerService extends IWindowManager.Stub
final WindowList windows = iterator.next().getWindowList();
for (int i = 0; i < windows.size(); i++) {
final WindowState win = windows.get(i);
- if (win.isOtherUsersAppWindow()) {
+ if (win.isHiddenFromUserLocked()) {
Slog.w(TAG, "current user violation " + newUserId + " hiding "
+ win + ", attrs=" + win.mAttrs.type + ", belonging to "
+ win.mOwnerUid);
diff --git a/services/java/com/android/server/wm/WindowState.java b/services/java/com/android/server/wm/WindowState.java
index 6e388f2..dee66a6 100644
--- a/services/java/com/android/server/wm/WindowState.java
+++ b/services/java/com/android/server/wm/WindowState.java
@@ -940,7 +940,7 @@ final class WindowState implements WindowManagerPolicy.WindowState {
}
boolean showLw(boolean doAnimation, boolean requestAnim) {
- if (isOtherUsersAppWindow()) {
+ if (isHiddenFromUserLocked()) {
Slog.w(TAG, "current user violation " + mService.mCurrentUserId + " trying to display "
+ this + ", type " + mAttrs.type + ", belonging to " + mOwnerUid);
return false;
@@ -1030,7 +1030,18 @@ final class WindowState implements WindowManagerPolicy.WindowState {
mShowToOwnerOnly = showToOwnerOnly;
}
- boolean isOtherUsersAppWindow() {
+ boolean isHiddenFromUserLocked() {
+ // Save some cycles by not calling getDisplayInfo unless it is an application
+ // window intended for all users.
+ if (mAttrs.type < WindowManager.LayoutParams.FIRST_SYSTEM_WINDOW
+ && mAppToken != null && mAppToken.showWhenLocked) {
+ final DisplayInfo displayInfo = mDisplayContent.getDisplayInfo();
+ if (isFullscreen(displayInfo.appWidth, displayInfo.appHeight)) {
+ // Is a fullscreen window, like the clock alarm. Show to everyone.
+ return false;
+ }
+ }
+
return mShowToOwnerOnly && UserHandle.getUserId(mOwnerUid) != mService.mCurrentUserId;
}
diff --git a/services/java/com/android/server/wm/WindowStateAnimator.java b/services/java/com/android/server/wm/WindowStateAnimator.java
index 817a234..d63fb5a 100644
--- a/services/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/java/com/android/server/wm/WindowStateAnimator.java
@@ -1334,7 +1334,7 @@ class WindowStateAnimator {
// This must be called while inside a transaction.
boolean performShowLocked() {
- if (mWin.isOtherUsersAppWindow()) {
+ if (mWin.isHiddenFromUserLocked()) {
Slog.w(TAG, "current user violation " + mService.mCurrentUserId + " trying to display "
+ this + ", type " + mWin.mAttrs.type + ", belonging to " + mWin.mOwnerUid);
return false;
diff --git a/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java b/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
index 1f6279c..746ac06 100644
--- a/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
+++ b/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
@@ -93,7 +93,7 @@ public class WindowManagerPermissionTests extends TestCase {
}
try {
- mWm.addAppToken(0, null, 0, 0, false);
+ mWm.addAppToken(0, null, 0, 0, false, false);
fail("IWindowManager.addAppToken did not throw SecurityException as"
+ " expected");
} catch (SecurityException e) {
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java
index b8d21f3..ddb0665 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java
@@ -78,7 +78,8 @@ public class BridgeWindowManager implements IWindowManager {
}
@Override
- public void addAppToken(int arg0, IApplicationToken arg1, int arg2, int arg3, boolean arg4)
+ public void addAppToken(int arg0, IApplicationToken arg1, int arg2, int arg3, boolean arg4,
+ boolean arg5)
throws RemoteException {
// TODO Auto-generated method stub