summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/java/android/view/IWindowManager.aidl2
-rw-r--r--services/java/com/android/server/AttributeCache.java51
-rw-r--r--services/java/com/android/server/am/ActivityManagerService.java4
-rw-r--r--services/java/com/android/server/am/ActivityRecord.java2
-rwxr-xr-xservices/java/com/android/server/am/ActivityStack.java12
-rw-r--r--services/java/com/android/server/wm/AppWindowToken.java8
-rwxr-xr-xservices/java/com/android/server/wm/WindowManagerService.java28
-rw-r--r--services/java/com/android/server/wm/WindowStateAnimator.java4
-rw-r--r--tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java2
-rw-r--r--tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java2
10 files changed, 70 insertions, 45 deletions
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index 0fe2a8e..2b6cbcf 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -74,7 +74,7 @@ interface IWindowManager
void setEventDispatching(boolean enabled);
void addWindowToken(IBinder token, int type);
void removeWindowToken(IBinder token);
- void addAppToken(int addPos, IApplicationToken token,
+ void addAppToken(int addPos, int userId, IApplicationToken token,
int groupId, int requestedOrientation, boolean fullscreen, boolean showWhenLocked);
void setAppGroupId(IBinder token, int groupId);
void setAppOrientation(IApplicationToken token, int requestedOrientation);
diff --git a/services/java/com/android/server/AttributeCache.java b/services/java/com/android/server/AttributeCache.java
index 81378dc..81613c6 100644
--- a/services/java/com/android/server/AttributeCache.java
+++ b/services/java/com/android/server/AttributeCache.java
@@ -23,6 +23,7 @@ import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.content.res.TypedArray;
+import android.os.UserHandle;
import android.util.SparseArray;
import java.util.HashMap;
@@ -34,52 +35,54 @@ import java.util.WeakHashMap;
*/
public final class AttributeCache {
private static AttributeCache sInstance = null;
-
+
private final Context mContext;
- private final WeakHashMap<String, Package> mPackages =
- new WeakHashMap<String, Package>();
+ private final SparseArray<WeakHashMap<String, Package>> mPackages =
+ new SparseArray<WeakHashMap<String, Package>>();
private final Configuration mConfiguration = new Configuration();
-
+
public final static class Package {
public final Context context;
private final SparseArray<HashMap<int[], Entry>> mMap
= new SparseArray<HashMap<int[], Entry>>();
-
+
public Package(Context c) {
context = c;
}
}
-
+
public final static class Entry {
public final Context context;
public final TypedArray array;
-
+
public Entry(Context c, TypedArray ta) {
context = c;
array = ta;
}
}
-
+
public static void init(Context context) {
if (sInstance == null) {
sInstance = new AttributeCache(context);
}
}
-
+
public static AttributeCache instance() {
return sInstance;
}
-
+
public AttributeCache(Context context) {
mContext = context;
}
-
+
public void removePackage(String packageName) {
synchronized (this) {
- mPackages.remove(packageName);
+ for (int i=0; i<mPackages.size(); i++) {
+ mPackages.valueAt(i).remove(packageName);
+ }
}
}
-
+
public void updateConfiguration(Configuration config) {
synchronized (this) {
int changes = mConfiguration.updateFrom(config);
@@ -93,10 +96,21 @@ public final class AttributeCache {
}
}
}
-
- public Entry get(String packageName, int resId, int[] styleable) {
+
+ public void removeUser(int userId) {
+ synchronized (this) {
+ mPackages.remove(userId);
+ }
+ }
+
+ public Entry get(int userId, String packageName, int resId, int[] styleable) {
synchronized (this) {
- Package pkg = mPackages.get(packageName);
+ WeakHashMap<String, Package> packages = mPackages.get(userId);
+ if (packages == null) {
+ packages = new WeakHashMap<String, Package>();
+ mPackages.put(userId, packages);
+ }
+ Package pkg = packages.get(packageName);
HashMap<int[], Entry> map = null;
Entry ent = null;
if (pkg != null) {
@@ -110,7 +124,8 @@ public final class AttributeCache {
} else {
Context context;
try {
- context = mContext.createPackageContext(packageName, 0);
+ context = mContext.createPackageContextAsUser(packageName, 0,
+ new UserHandle(userId));
if (context == null) {
return null;
}
@@ -118,7 +133,7 @@ public final class AttributeCache {
return null;
}
pkg = new Package(context);
- mPackages.put(packageName, pkg);
+ packages.put(packageName, pkg);
}
if (map == null) {
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index d15b854..409480f 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -14551,6 +14551,10 @@ public final class ActivityManagerService extends ActivityManagerNative
// Clean up all state and processes associated with the user.
// Kill all the processes for the user.
forceStopUserLocked(userId);
+ AttributeCache ac = AttributeCache.instance();
+ if (ac != null) {
+ ac.removeUser(userId);
+ }
}
}
diff --git a/services/java/com/android/server/am/ActivityRecord.java b/services/java/com/android/server/am/ActivityRecord.java
index 749dc66..de0f9ca 100644
--- a/services/java/com/android/server/am/ActivityRecord.java
+++ b/services/java/com/android/server/am/ActivityRecord.java
@@ -407,7 +407,7 @@ final class ActivityRecord {
packageName = aInfo.applicationInfo.packageName;
launchMode = aInfo.launchMode;
- AttributeCache.Entry ent = AttributeCache.instance().get(packageName,
+ AttributeCache.Entry ent = AttributeCache.instance().get(userId, packageName,
realTheme, com.android.internal.R.styleable.Window);
fullscreen = ent != null && !ent.array.getBoolean(
com.android.internal.R.styleable.Window_windowIsFloating, false)
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index 4546dc3..27dd732 100755
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -1810,8 +1810,8 @@ final class ActivityStack {
}
mHistory.add(addPos, r);
r.putInHistory();
- mService.mWindowManager.addAppToken(addPos, r.appToken, r.task.taskId,
- r.info.screenOrientation, r.fullscreen,
+ mService.mWindowManager.addAppToken(addPos, r.userId, r.appToken,
+ r.task.taskId, r.info.screenOrientation, r.fullscreen,
(r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0);
if (VALIDATE_TOKENS) {
validateAppTokensLocked();
@@ -1875,8 +1875,8 @@ final class ActivityStack {
mNoAnimActivities.remove(r);
}
r.updateOptionsLocked(options);
- mService.mWindowManager.addAppToken(
- addPos, r.appToken, r.task.taskId, r.info.screenOrientation, r.fullscreen,
+ mService.mWindowManager.addAppToken(addPos, r.userId, 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) {
@@ -1914,8 +1914,8 @@ final class ActivityStack {
} else {
// 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,
+ mService.mWindowManager.addAppToken(addPos, r.userId, r.appToken,
+ r.task.taskId, r.info.screenOrientation, r.fullscreen,
(r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0);
ActivityOptions.abort(options);
}
diff --git a/services/java/com/android/server/wm/AppWindowToken.java b/services/java/com/android/server/wm/AppWindowToken.java
index 7efffe5..2802ad7 100644
--- a/services/java/com/android/server/wm/AppWindowToken.java
+++ b/services/java/com/android/server/wm/AppWindowToken.java
@@ -37,6 +37,8 @@ import java.util.ArrayList;
* really activity) that is displaying windows.
*/
class AppWindowToken extends WindowToken {
+ // The user who owns this app window token.
+ final int userId;
// Non-null only for application tokens.
final IApplicationToken appToken;
@@ -98,9 +100,10 @@ class AppWindowToken extends WindowToken {
// Input application handle used by the input dispatcher.
final InputApplicationHandle mInputApplicationHandle;
- AppWindowToken(WindowManagerService _service, IApplicationToken _token) {
+ AppWindowToken(WindowManagerService _service, int _userId, IApplicationToken _token) {
super(_service, _token.asBinder(),
WindowManager.LayoutParams.TYPE_APPLICATION, true);
+ userId = _userId;
appWindowToken = this;
appToken = _token;
mInputApplicationHandle = new InputApplicationHandle(this);
@@ -225,7 +228,8 @@ class AppWindowToken extends WindowToken {
void dump(PrintWriter pw, String prefix) {
super.dump(pw, prefix);
if (appToken != null) {
- pw.print(prefix); pw.println("app=true");
+ pw.print(prefix); pw.print("app=true");
+ pw.print(" userId="); pw.println(userId);
}
if (allAppWindows.size() > 0) {
pw.print(prefix); pw.print("allAppWindows="); pw.println(allAppWindows);
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 9ba83d0..003f4db 100755
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -3200,7 +3200,7 @@ public class WindowManagerService extends IWindowManager.Stub
return info;
}
- private AttributeCache.Entry getCachedAnimations(WindowManager.LayoutParams lp) {
+ private AttributeCache.Entry getCachedAnimations(int userId, WindowManager.LayoutParams lp) {
if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: layout params pkg="
+ (lp != null ? lp.packageName : null)
+ " resId=0x" + (lp != null ? Integer.toHexString(lp.windowAnimations) : null));
@@ -3215,13 +3215,13 @@ public class WindowManagerService extends IWindowManager.Stub
}
if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: picked package="
+ packageName);
- return AttributeCache.instance().get(packageName, resId,
+ return AttributeCache.instance().get(userId, packageName, resId,
com.android.internal.R.styleable.WindowAnimation);
}
return null;
}
- private AttributeCache.Entry getCachedAnimations(String packageName, int resId) {
+ private AttributeCache.Entry getCachedAnimations(int userId, String packageName, int resId) {
if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: package="
+ packageName + " resId=0x" + Integer.toHexString(resId));
if (packageName != null) {
@@ -3230,17 +3230,17 @@ public class WindowManagerService extends IWindowManager.Stub
}
if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: picked package="
+ packageName);
- return AttributeCache.instance().get(packageName, resId,
+ return AttributeCache.instance().get(userId, packageName, resId,
com.android.internal.R.styleable.WindowAnimation);
}
return null;
}
- Animation loadAnimation(WindowManager.LayoutParams lp, int animAttr) {
+ Animation loadAnimation(int userId, WindowManager.LayoutParams lp, int animAttr) {
int anim = 0;
Context context = mContext;
if (animAttr >= 0) {
- AttributeCache.Entry ent = getCachedAnimations(lp);
+ AttributeCache.Entry ent = getCachedAnimations(userId, lp);
if (ent != null) {
context = ent.context;
anim = ent.array.getResourceId(animAttr, 0);
@@ -3252,11 +3252,11 @@ public class WindowManagerService extends IWindowManager.Stub
return null;
}
- private Animation loadAnimation(String packageName, int resId) {
+ private Animation loadAnimation(int userId, String packageName, int resId) {
int anim = 0;
Context context = mContext;
if (resId >= 0) {
- AttributeCache.Entry ent = getCachedAnimations(packageName, resId);
+ AttributeCache.Entry ent = getCachedAnimations(userId, packageName, resId);
if (ent != null) {
context = ent.context;
anim = resId;
@@ -3484,7 +3484,7 @@ public class WindowManagerService extends IWindowManager.Stub
Animation a;
boolean initialized = false;
if (mNextAppTransitionType == ActivityOptions.ANIM_CUSTOM) {
- a = loadAnimation(mNextAppTransitionPackage, enter ?
+ a = loadAnimation(atoken.userId, mNextAppTransitionPackage, enter ?
mNextAppTransitionEnter : mNextAppTransitionExit);
if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
"applyAnimation: atoken=" + atoken
@@ -3565,7 +3565,7 @@ public class WindowManagerService extends IWindowManager.Stub
: com.android.internal.R.styleable.WindowAnimation_wallpaperIntraCloseExitAnimation;
break;
}
- a = animAttr != 0 ? loadAnimation(lp, animAttr) : null;
+ a = animAttr != 0 ? loadAnimation(atoken.userId, lp, animAttr) : null;
if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
"applyAnimation: atoken=" + atoken
+ " anim=" + a
@@ -3752,7 +3752,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
@Override
- public void addAppToken(int addPos, IApplicationToken token,
+ public void addAppToken(int addPos, int userId, IApplicationToken token,
int groupId, int requestedOrientation, boolean fullscreen, boolean showWhenLocked) {
if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
"addAppToken()")) {
@@ -3779,7 +3779,7 @@ public class WindowManagerService extends IWindowManager.Stub
Slog.w(TAG, "Attempted to add existing app token: " + token);
return;
}
- atoken = new AppWindowToken(this, token);
+ atoken = new AppWindowToken(this, userId, token);
atoken.inputDispatchingTimeoutNanos = inputDispatchingTimeoutNanos;
atoken.groupId = groupId;
atoken.appFullscreen = fullscreen;
@@ -4396,8 +4396,8 @@ public class WindowManagerService extends IWindowManager.Stub
if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Checking theme of starting window: 0x"
+ Integer.toHexString(theme));
if (theme != 0) {
- AttributeCache.Entry ent = AttributeCache.instance().get(pkg, theme,
- com.android.internal.R.styleable.Window);
+ AttributeCache.Entry ent = AttributeCache.instance().get(wtoken.userId,
+ pkg, theme, com.android.internal.R.styleable.Window);
if (ent == null) {
// Whoops! App doesn't exist. Um. Okay. We'll just
// pretend like we didn't see that.
diff --git a/services/java/com/android/server/wm/WindowStateAnimator.java b/services/java/com/android/server/wm/WindowStateAnimator.java
index d7fcc67..10784fe 100644
--- a/services/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/java/com/android/server/wm/WindowStateAnimator.java
@@ -14,6 +14,7 @@ import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.Region;
import android.os.Debug;
+import android.os.UserHandle;
import android.util.Slog;
import android.view.DisplayInfo;
import android.view.Surface;
@@ -1533,7 +1534,8 @@ class WindowStateAnimator {
break;
}
if (attr >= 0) {
- a = mService.loadAnimation(mWin.mAttrs, attr);
+ a = mService.loadAnimation(UserHandle.getUserId(mWin.mOwnerUid),
+ mWin.mAttrs, attr);
}
}
if (WindowManagerService.DEBUG_ANIM) Slog.v(TAG,
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 746ac06..596f722 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, false);
+ mWm.addAppToken(0, 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/android/view/IWindowManagerImpl.java b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
index 3e625f9..091c6e5 100644
--- a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
+++ b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
@@ -87,7 +87,7 @@ public class IWindowManagerImpl implements IWindowManager {
// ---- unused implementation of IWindowManager ----
@Override
- public void addAppToken(int arg0, IApplicationToken arg1, int arg2, int arg3, boolean arg4,
+ public void addAppToken(int arg0, int arg1p5, IApplicationToken arg1, int arg2, int arg3, boolean arg4,
boolean arg5)
throws RemoteException {
// TODO Auto-generated method stub