diff options
Diffstat (limited to 'services/java')
7 files changed, 67 insertions, 42 deletions
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, |