summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
Diffstat (limited to 'services')
-rw-r--r--services/java/com/android/server/AppWidgetService.java33
-rw-r--r--services/java/com/android/server/AppWidgetServiceImpl.java16
-rw-r--r--services/java/com/android/server/BackupManagerService.java220
-rw-r--r--services/java/com/android/server/ClipboardService.java3
-rw-r--r--services/java/com/android/server/WallpaperManagerService.java52
-rw-r--r--services/java/com/android/server/WiredAccessoryObserver.java23
-rw-r--r--services/java/com/android/server/am/ActivityManagerService.java96
-rw-r--r--services/java/com/android/server/pm/PackageManagerService.java294
-rw-r--r--services/java/com/android/server/pm/PackageSetting.java6
-rw-r--r--services/java/com/android/server/pm/PackageSettingBase.java9
-rw-r--r--services/java/com/android/server/pm/Settings.java63
-rw-r--r--services/java/com/android/server/pm/UserManager.java107
-rw-r--r--services/java/com/android/server/wm/AppWindowToken.java18
-rw-r--r--services/java/com/android/server/wm/DimAnimator.java8
-rw-r--r--services/java/com/android/server/wm/WindowAnimator.java27
-rw-r--r--services/java/com/android/server/wm/WindowManagerService.java54
-rw-r--r--services/java/com/android/server/wm/WindowState.java332
-rw-r--r--services/java/com/android/server/wm/WindowStateAnimator.java298
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java8
19 files changed, 945 insertions, 722 deletions
diff --git a/services/java/com/android/server/AppWidgetService.java b/services/java/com/android/server/AppWidgetService.java
index a85b605..eb024e9 100644
--- a/services/java/com/android/server/AppWidgetService.java
+++ b/services/java/com/android/server/AppWidgetService.java
@@ -170,6 +170,15 @@ class AppWidgetService extends IAppWidgetService.Stub
sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);
sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
mContext.registerReceiver(mBroadcastReceiver, sdFilter);
+
+ IntentFilter userFilter = new IntentFilter();
+ userFilter.addAction(Intent.ACTION_USER_REMOVED);
+ mContext.registerReceiver(new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ onUserRemoved(intent.getIntExtra(Intent.EXTRA_USERID, -1));
+ }
+ }, userFilter);
}
@Override
@@ -192,19 +201,6 @@ class AppWidgetService extends IAppWidgetService.Stub
getImplForUser().deleteAllHosts();
}
- void cancelBroadcasts(Provider p) {
- if (p.broadcast != null) {
- mAlarmManager.cancel(p.broadcast);
- long token = Binder.clearCallingIdentity();
- try {
- p.broadcast.cancel();
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- p.broadcast = null;
- }
- }
-
@Override
public void bindAppWidgetId(int appWidgetId, ComponentName provider) throws RemoteException {
getImplForUser().bindAppWidgetId(appWidgetId, provider);
@@ -222,8 +218,15 @@ class AppWidgetService extends IAppWidgetService.Stub
return getImplForUser().startListening(host, packageName, hostId, updatedViews);
}
- // TODO: Call this from PackageManagerService when a user is removed
- public void removeUser(int userId) {
+ public void onUserRemoved(int userId) {
+ AppWidgetServiceImpl impl = mAppWidgetServices.get(userId);
+ if (userId < 1) return;
+
+ if (impl == null) {
+ AppWidgetServiceImpl.getSettingsFile(userId).delete();
+ } else {
+ impl.onUserRemoved();
+ }
}
private AppWidgetServiceImpl getImplForUser() {
diff --git a/services/java/com/android/server/AppWidgetServiceImpl.java b/services/java/com/android/server/AppWidgetServiceImpl.java
index 182a884..b24823e 100644
--- a/services/java/com/android/server/AppWidgetServiceImpl.java
+++ b/services/java/com/android/server/AppWidgetServiceImpl.java
@@ -1484,9 +1484,13 @@ class AppWidgetServiceImpl {
}
}
+ static File getSettingsFile(int userId) {
+ return new File("/data/system/users/" + userId + "/" + SETTINGS_FILENAME);
+ }
+
AtomicFile savedStateFile() {
File dir = new File("/data/system/users/" + mUserId);
- File settingsFile = new File(dir, SETTINGS_FILENAME);
+ File settingsFile = getSettingsFile(mUserId);
if (!dir.exists()) {
dir.mkdirs();
if (mUserId == 0) {
@@ -1500,6 +1504,16 @@ class AppWidgetServiceImpl {
return new AtomicFile(settingsFile);
}
+ void onUserRemoved() {
+ // prune the ones we don't want to keep
+ int N = mInstalledProviders.size();
+ for (int i = N - 1; i >= 0; i--) {
+ Provider p = mInstalledProviders.get(i);
+ cancelBroadcasts(p);
+ }
+ getSettingsFile(mUserId).delete();
+ }
+
void addProvidersForPackageLocked(String pkgName) {
Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
intent.setPackage(pkgName);
diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java
index bd8ae17..a0d5beb 100644
--- a/services/java/com/android/server/BackupManagerService.java
+++ b/services/java/com/android/server/BackupManagerService.java
@@ -201,9 +201,9 @@ class BackupManagerService extends IBackupManager.Stub {
BackupHandler mBackupHandler;
PendingIntent mRunBackupIntent, mRunInitIntent;
BroadcastReceiver mRunBackupReceiver, mRunInitReceiver;
- // map UIDs to the set of backup client services within that UID's app set
- final SparseArray<HashSet<ApplicationInfo>> mBackupParticipants
- = new SparseArray<HashSet<ApplicationInfo>>();
+ // map UIDs to the set of participating packages under that UID
+ final SparseArray<HashSet<String>> mBackupParticipants
+ = new SparseArray<HashSet<String>>();
// set of backup services that have pending changes
class BackupRequest {
public String packageName;
@@ -960,7 +960,6 @@ class BackupManagerService extends IBackupManager.Stub {
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_PACKAGE_ADDED);
filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
- filter.addAction(Intent.ACTION_PACKAGE_REPLACED);
filter.addDataScheme("package");
mContext.registerReceiver(mBroadcastReceiver, filter);
// Register for events related to sdcard installation.
@@ -1239,12 +1238,13 @@ class BackupManagerService extends IBackupManager.Stub {
// Enqueue a new backup of every participant
synchronized (mBackupParticipants) {
- int N = mBackupParticipants.size();
+ final int N = mBackupParticipants.size();
for (int i=0; i<N; i++) {
- int uid = mBackupParticipants.keyAt(i);
- HashSet<ApplicationInfo> participants = mBackupParticipants.valueAt(i);
- for (ApplicationInfo app: participants) {
- dataChangedImpl(app.packageName);
+ HashSet<String> participants = mBackupParticipants.valueAt(i);
+ if (participants != null) {
+ for (String packageName : participants) {
+ dataChangedImpl(packageName);
+ }
}
}
}
@@ -1302,8 +1302,7 @@ class BackupManagerService extends IBackupManager.Stub {
Bundle extras = intent.getExtras();
String pkgList[] = null;
if (Intent.ACTION_PACKAGE_ADDED.equals(action) ||
- Intent.ACTION_PACKAGE_REMOVED.equals(action) ||
- Intent.ACTION_PACKAGE_REPLACED.equals(action)) {
+ Intent.ACTION_PACKAGE_REMOVED.equals(action)) {
Uri uri = intent.getData();
if (uri == null) {
return;
@@ -1312,14 +1311,8 @@ class BackupManagerService extends IBackupManager.Stub {
if (pkgName != null) {
pkgList = new String[] { pkgName };
}
- if (Intent.ACTION_PACKAGE_REPLACED.equals(action)) {
- // use the existing "add with replacement" logic
- if (MORE_DEBUG) Slog.d(TAG, "PACKAGE_REPLACED, updating package " + pkgName);
- added = replacing = true;
- } else {
- added = Intent.ACTION_PACKAGE_ADDED.equals(action);
- replacing = extras.getBoolean(Intent.EXTRA_REPLACING, false);
- }
+ added = Intent.ACTION_PACKAGE_ADDED.equals(action);
+ replacing = extras.getBoolean(Intent.EXTRA_REPLACING, false);
} else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(action)) {
added = true;
pkgList = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
@@ -1331,20 +1324,23 @@ class BackupManagerService extends IBackupManager.Stub {
if (pkgList == null || pkgList.length == 0) {
return;
}
+
+ final int uid = extras.getInt(Intent.EXTRA_UID);
if (added) {
synchronized (mBackupParticipants) {
if (replacing) {
- updatePackageParticipantsLocked(pkgList);
- } else {
- addPackageParticipantsLocked(pkgList);
+ // This is the package-replaced case; we just remove the entry
+ // under the old uid and fall through to re-add.
+ removePackageParticipantsLocked(pkgList, uid);
}
+ addPackageParticipantsLocked(pkgList);
}
} else {
if (replacing) {
// The package is being updated. We'll receive a PACKAGE_ADDED shortly.
} else {
synchronized (mBackupParticipants) {
- removePackageParticipantsLocked(pkgList);
+ removePackageParticipantsLocked(pkgList, uid);
}
}
}
@@ -1391,12 +1387,12 @@ class BackupManagerService extends IBackupManager.Stub {
for (PackageInfo pkg : targetPkgs) {
if (packageName == null || pkg.packageName.equals(packageName)) {
int uid = pkg.applicationInfo.uid;
- HashSet<ApplicationInfo> set = mBackupParticipants.get(uid);
+ HashSet<String> set = mBackupParticipants.get(uid);
if (set == null) {
- set = new HashSet<ApplicationInfo>();
+ set = new HashSet<String>();
mBackupParticipants.put(uid, set);
}
- set.add(pkg.applicationInfo);
+ set.add(pkg.packageName);
if (MORE_DEBUG) Slog.v(TAG, "Agent found; added");
// If we've never seen this app before, schedule a backup for it
@@ -1410,63 +1406,36 @@ class BackupManagerService extends IBackupManager.Stub {
}
// Remove the given packages' entries from our known active set.
- void removePackageParticipantsLocked(String[] packageNames) {
+ void removePackageParticipantsLocked(String[] packageNames, int oldUid) {
if (packageNames == null) {
Slog.w(TAG, "removePackageParticipants with null list");
return;
}
- if (DEBUG) Slog.v(TAG, "removePackageParticipantsLocked: #" + packageNames.length);
- List<PackageInfo> knownPackages = allAgentPackages();
+ if (DEBUG) Slog.v(TAG, "removePackageParticipantsLocked: uid=" + oldUid
+ + " #" + packageNames.length);
for (String pkg : packageNames) {
- removePackageParticipantsLockedInner(pkg, knownPackages);
+ // Known previous UID, so we know which package set to check
+ HashSet<String> set = mBackupParticipants.get(oldUid);
+ if (set != null && set.contains(pkg)) {
+ removePackageFromSetLocked(set, pkg);
+ if (set.isEmpty()) {
+ if (MORE_DEBUG) Slog.v(TAG, " last one of this uid; purging set");
+ mBackupParticipants.remove(oldUid);
+ }
+ }
}
}
- private void removePackageParticipantsLockedInner(String packageName,
- List<PackageInfo> allPackages) {
- if (MORE_DEBUG) {
- Slog.v(TAG, "removePackageParticipantsLockedInner (" + packageName
- + ") removing from " + allPackages.size() + " entries");
- for (PackageInfo p : allPackages) {
- Slog.v(TAG, " - " + p.packageName);
- }
- }
- for (PackageInfo pkg : allPackages) {
- if (packageName == null || pkg.packageName.equals(packageName)) {
- /*
- int uid = -1;
- try {
- PackageInfo info = mPackageManager.getPackageInfo(packageName, 0);
- uid = info.applicationInfo.uid;
- } catch (NameNotFoundException e) {
- // we don't know this package name, so just skip it for now
- continue;
- }
- */
- final int uid = pkg.applicationInfo.uid;
- if (MORE_DEBUG) Slog.i(TAG, " found pkg " + packageName + " uid=" + uid);
-
- HashSet<ApplicationInfo> set = mBackupParticipants.get(uid);
- if (set != null) {
- // Find the existing entry with the same package name, and remove it.
- // We can't just remove(app) because the instances are different.
- for (ApplicationInfo entry: set) {
- if (MORE_DEBUG) Slog.i(TAG, " checking against " + entry.packageName);
- if (entry.packageName.equals(pkg)) {
- if (MORE_DEBUG) Slog.v(TAG, " removing participant " + pkg);
- set.remove(entry);
- removeEverBackedUp(pkg.packageName);
- break;
- }
- }
- if (set.size() == 0) {
- mBackupParticipants.delete(uid);
- }
- } else {
- if (MORE_DEBUG) Slog.i(TAG, " ... not found in uid mapping");
- }
- }
+ private void removePackageFromSetLocked(final HashSet<String> set,
+ final String packageName) {
+ if (set.contains(packageName)) {
+ // Found it. Remove this one package from the bookkeeping, and
+ // if it's the last participating app under this uid we drop the
+ // (now-empty) set as well.
+ if (MORE_DEBUG) Slog.v(TAG, " removing participant " + packageName);
+ removeEverBackedUp(packageName);
+ set.remove(packageName);
}
}
@@ -1497,24 +1466,6 @@ class BackupManagerService extends IBackupManager.Stub {
return packages;
}
- // Reset the given package's known backup participants. Unlike add/remove, the update
- // action cannot be passed a null package name.
- void updatePackageParticipantsLocked(String[] packageNames) {
- if (packageNames == null) {
- Slog.e(TAG, "updatePackageParticipants called with null package list");
- return;
- }
- if (DEBUG) Slog.v(TAG, "updatePackageParticipantsLocked: #" + packageNames.length);
-
- if (packageNames.length > 0) {
- List<PackageInfo> allApps = allAgentPackages();
- for (String packageName : packageNames) {
- removePackageParticipantsLockedInner(packageName, allApps);
- addPackageParticipantsLockedInner(packageName, allApps);
- }
- }
- }
-
// Called from the backup task: record that the given app has been successfully
// backed up at least once
void logBackupComplete(String packageName) {
@@ -4772,11 +4723,11 @@ class BackupManagerService extends IBackupManager.Stub {
}
private void dataChangedImpl(String packageName) {
- HashSet<ApplicationInfo> targets = dataChangedTargets(packageName);
+ HashSet<String> targets = dataChangedTargets(packageName);
dataChangedImpl(packageName, targets);
}
- private void dataChangedImpl(String packageName, HashSet<ApplicationInfo> targets) {
+ private void dataChangedImpl(String packageName, HashSet<String> targets) {
// Record that we need a backup pass for the caller. Since multiple callers
// may share a uid, we need to note all candidates within that uid and schedule
// a backup pass for each of them.
@@ -4790,27 +4741,23 @@ class BackupManagerService extends IBackupManager.Stub {
synchronized (mQueueLock) {
// Note that this client has made data changes that need to be backed up
- for (ApplicationInfo app : targets) {
- // validate the caller-supplied package name against the known set of
- // packages associated with this uid
- if (app.packageName.equals(packageName)) {
- // Add the caller to the set of pending backups. If there is
- // one already there, then overwrite it, but no harm done.
- BackupRequest req = new BackupRequest(packageName);
- if (mPendingBackups.put(app.packageName, req) == null) {
- if (DEBUG) Slog.d(TAG, "Now staging backup of " + packageName);
-
- // Journal this request in case of crash. The put()
- // operation returned null when this package was not already
- // in the set; we want to avoid touching the disk redundantly.
- writeToJournalLocked(packageName);
+ if (targets.contains(packageName)) {
+ // Add the caller to the set of pending backups. If there is
+ // one already there, then overwrite it, but no harm done.
+ BackupRequest req = new BackupRequest(packageName);
+ if (mPendingBackups.put(packageName, req) == null) {
+ if (DEBUG) Slog.d(TAG, "Now staging backup of " + packageName);
+
+ // Journal this request in case of crash. The put()
+ // operation returned null when this package was not already
+ // in the set; we want to avoid touching the disk redundantly.
+ writeToJournalLocked(packageName);
- if (MORE_DEBUG) {
- int numKeys = mPendingBackups.size();
- Slog.d(TAG, "Now awaiting backup for " + numKeys + " participants:");
- for (BackupRequest b : mPendingBackups.values()) {
- Slog.d(TAG, " + " + b);
- }
+ if (MORE_DEBUG) {
+ int numKeys = mPendingBackups.size();
+ Slog.d(TAG, "Now awaiting backup for " + numKeys + " participants:");
+ for (BackupRequest b : mPendingBackups.values()) {
+ Slog.d(TAG, " + " + b);
}
}
}
@@ -4819,7 +4766,7 @@ class BackupManagerService extends IBackupManager.Stub {
}
// Note: packageName is currently unused, but may be in the future
- private HashSet<ApplicationInfo> dataChangedTargets(String packageName) {
+ private HashSet<String> dataChangedTargets(String packageName) {
// If the caller does not hold the BACKUP permission, it can only request a
// backup of its own data.
if ((mContext.checkPermission(android.Manifest.permission.BACKUP, Binder.getCallingPid(),
@@ -4831,11 +4778,11 @@ class BackupManagerService extends IBackupManager.Stub {
// a caller with full permission can ask to back up any participating app
// !!! TODO: allow backup of ANY app?
- HashSet<ApplicationInfo> targets = new HashSet<ApplicationInfo>();
+ HashSet<String> targets = new HashSet<String>();
synchronized (mBackupParticipants) {
int N = mBackupParticipants.size();
for (int i = 0; i < N; i++) {
- HashSet<ApplicationInfo> s = mBackupParticipants.valueAt(i);
+ HashSet<String> s = mBackupParticipants.valueAt(i);
if (s != null) {
targets.addAll(s);
}
@@ -4862,7 +4809,7 @@ class BackupManagerService extends IBackupManager.Stub {
// ----- IBackupManager binder interface -----
public void dataChanged(final String packageName) {
- final HashSet<ApplicationInfo> targets = dataChangedTargets(packageName);
+ final HashSet<String> targets = dataChangedTargets(packageName);
if (targets == null) {
Slog.w(TAG, "dataChanged but no participant pkg='" + packageName + "'"
+ " uid=" + Binder.getCallingUid());
@@ -4889,7 +4836,7 @@ class BackupManagerService extends IBackupManager.Stub {
// If the caller does not hold the BACKUP permission, it can only request a
// wipe of its own backed-up data.
- HashSet<ApplicationInfo> apps;
+ HashSet<String> apps;
if ((mContext.checkPermission(android.Manifest.permission.BACKUP, Binder.getCallingPid(),
Binder.getCallingUid())) == PackageManager.PERMISSION_DENIED) {
apps = mBackupParticipants.get(Binder.getCallingUid());
@@ -4897,30 +4844,27 @@ class BackupManagerService extends IBackupManager.Stub {
// a caller with full permission can ask to back up any participating app
// !!! TODO: allow data-clear of ANY app?
if (DEBUG) Slog.v(TAG, "Privileged caller, allowing clear of other apps");
- apps = new HashSet<ApplicationInfo>();
+ apps = new HashSet<String>();
int N = mBackupParticipants.size();
for (int i = 0; i < N; i++) {
- HashSet<ApplicationInfo> s = mBackupParticipants.valueAt(i);
+ HashSet<String> s = mBackupParticipants.valueAt(i);
if (s != null) {
apps.addAll(s);
}
}
}
- // now find the given package in the set of candidate apps
- for (ApplicationInfo app : apps) {
- if (app.packageName.equals(packageName)) {
- if (DEBUG) Slog.v(TAG, "Found the app - running clear process");
- // found it; fire off the clear request
- synchronized (mQueueLock) {
- long oldId = Binder.clearCallingIdentity();
- mWakelock.acquire();
- Message msg = mBackupHandler.obtainMessage(MSG_RUN_CLEAR,
- new ClearParams(getTransport(mCurrentTransport), info));
- mBackupHandler.sendMessage(msg);
- Binder.restoreCallingIdentity(oldId);
- }
- break;
+ // Is the given app an available participant?
+ if (apps.contains(packageName)) {
+ if (DEBUG) Slog.v(TAG, "Found the app - running clear process");
+ // found it; fire off the clear request
+ synchronized (mQueueLock) {
+ long oldId = Binder.clearCallingIdentity();
+ mWakelock.acquire();
+ Message msg = mBackupHandler.obtainMessage(MSG_RUN_CLEAR,
+ new ClearParams(getTransport(mCurrentTransport), info));
+ mBackupHandler.sendMessage(msg);
+ Binder.restoreCallingIdentity(oldId);
}
}
}
@@ -5838,9 +5782,9 @@ class BackupManagerService extends IBackupManager.Stub {
int uid = mBackupParticipants.keyAt(i);
pw.print(" uid: ");
pw.println(uid);
- HashSet<ApplicationInfo> participants = mBackupParticipants.valueAt(i);
- for (ApplicationInfo app: participants) {
- pw.println(" " + app.packageName);
+ HashSet<String> participants = mBackupParticipants.valueAt(i);
+ for (String app: participants) {
+ pw.println(" " + app);
}
}
diff --git a/services/java/com/android/server/ClipboardService.java b/services/java/com/android/server/ClipboardService.java
index 062ab74..2e2a278 100644
--- a/services/java/com/android/server/ClipboardService.java
+++ b/services/java/com/android/server/ClipboardService.java
@@ -34,6 +34,7 @@ import android.os.Parcel;
import android.os.Process;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
+import android.os.UserId;
import android.util.Pair;
import android.util.Slog;
@@ -204,7 +205,7 @@ public class ClipboardService extends IClipboard.Stub {
PackageInfo pi;
try {
pi = mPm.getPackageInfo(pkg, 0);
- if (pi.applicationInfo.uid != uid) {
+ if (!UserId.isSameApp(pi.applicationInfo.uid, uid)) {
throw new SecurityException("Calling uid " + uid
+ " does not own package " + pkg);
}
diff --git a/services/java/com/android/server/WallpaperManagerService.java b/services/java/com/android/server/WallpaperManagerService.java
index 8ee12bc..6d83f30 100644
--- a/services/java/com/android/server/WallpaperManagerService.java
+++ b/services/java/com/android/server/WallpaperManagerService.java
@@ -25,9 +25,11 @@ import android.app.PendingIntent;
import android.app.WallpaperInfo;
import android.app.backup.BackupManager;
import android.app.backup.WallpaperBackupHelper;
+import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
@@ -36,6 +38,7 @@ import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Resources;
import android.os.Binder;
import android.os.Bundle;
+import android.os.Environment;
import android.os.FileUtils;
import android.os.IBinder;
import android.os.RemoteException;
@@ -401,41 +404,48 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
wallpaper.wallpaperObserver.stopWatching();
}
}
-
+
public void systemReady() {
if (DEBUG) Slog.v(TAG, "systemReady");
WallpaperData wallpaper = mWallpaperMap.get(0);
switchWallpaper(wallpaper);
wallpaper.wallpaperObserver = new WallpaperObserver(wallpaper);
wallpaper.wallpaperObserver.startWatching();
- ActivityManagerService ams = (ActivityManagerService) ServiceManager
- .getService(Context.ACTIVITY_SERVICE);
- ams.addUserListener(new ActivityManagerService.UserListener() {
-
- @Override
- public void onUserChanged(int userId) {
- switchUser(userId);
- }
+ IntentFilter userFilter = new IntentFilter();
+ userFilter.addAction(Intent.ACTION_USER_SWITCHED);
+ userFilter.addAction(Intent.ACTION_USER_REMOVED);
+ mContext.registerReceiver(new BroadcastReceiver() {
@Override
- public void onUserAdded(int userId) {
- }
-
- @Override
- public void onUserRemoved(int userId) {
- }
-
- @Override
- public void onUserLoggedOut(int userId) {
+ public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+ if (Intent.ACTION_USER_SWITCHED.equals(action)) {
+ switchUser(intent.getIntExtra(Intent.EXTRA_USERID, 0));
+ } else if (Intent.ACTION_USER_REMOVED.equals(action)) {
+ removeUser(intent.getIntExtra(Intent.EXTRA_USERID, 0));
+ }
}
-
- });
+ }, userFilter);
}
String getName() {
return mWallpaperMap.get(0).name;
}
+ void removeUser(int userId) {
+ synchronized (mLock) {
+ WallpaperData wallpaper = mWallpaperMap.get(userId);
+ if (wallpaper != null) {
+ wallpaper.wallpaperObserver.stopWatching();
+ mWallpaperMap.remove(userId);
+ }
+ File wallpaperFile = new File(getWallpaperDir(userId), WALLPAPER);
+ wallpaperFile.delete();
+ File wallpaperInfoFile = new File(getWallpaperDir(userId), WALLPAPER_INFO);
+ wallpaperInfoFile.delete();
+ }
+ }
+
void switchUser(int userId) {
synchronized (mLock) {
mCurrentUserId = userId;
@@ -861,7 +871,7 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
}
private static JournaledFile makeJournaledFile(int userId) {
- final String base = "/data/system/users/" + userId + "/" + WALLPAPER_INFO;
+ final String base = getWallpaperDir(userId) + "/" + WALLPAPER_INFO;
return new JournaledFile(new File(base), new File(base + ".tmp"));
}
diff --git a/services/java/com/android/server/WiredAccessoryObserver.java b/services/java/com/android/server/WiredAccessoryObserver.java
index a7a46dd..9b4eddc 100644
--- a/services/java/com/android/server/WiredAccessoryObserver.java
+++ b/services/java/com/android/server/WiredAccessoryObserver.java
@@ -66,7 +66,7 @@ class WiredAccessoryObserver extends UEventObserver {
public String getDevName() { return mDevName; }
public String getDevPath() {
- return String.format("DEVPATH=/devices/virtual/switch/%s", mDevName);
+ return String.format("/devices/virtual/switch/%s", mDevName);
}
public String getSwitchStatePath() {
@@ -158,7 +158,7 @@ class WiredAccessoryObserver extends UEventObserver {
init(); // set initial status
for (int i = 0; i < uEventInfo.size(); ++i) {
UEventInfo uei = uEventInfo.get(i);
- startObserving(uei.getDevPath());
+ startObserving("DEVPATH="+uei.getDevPath());
}
}
}
@@ -168,29 +168,20 @@ class WiredAccessoryObserver extends UEventObserver {
if (LOG) Slog.v(TAG, "Headset UEVENT: " + event.toString());
try {
+ String devPath = event.get("DEVPATH");
String name = event.get("SWITCH_NAME");
int state = Integer.parseInt(event.get("SWITCH_STATE"));
- updateState(name, state);
+ updateState(devPath, name, state);
} catch (NumberFormatException e) {
Slog.e(TAG, "Could not parse switch state from event " + event);
}
}
- private synchronized final void updateState(String name, int state)
+ private synchronized final void updateState(String devPath, String name, int state)
{
- // FIXME: When ueventd informs of a change in state for a switch, it does not have to be
- // the case that the name reported by /sys/class/switch/<device>/name is the same as
- // <device>. For normal users of the linux switch class driver, it will be. But it is
- // technically possible to hook the print_name method in the class driver and return a
- // different name each and every time the name sysfs entry is queried.
- //
- // Right now this is not the case for any of the switch implementations used here. I'm not
- // certain anyone would ever choose to implement such a dynamic name, or what it would mean
- // for the implementation at this level, but if it ever happens, we will need to revisit
- // this code.
for (int i = 0; i < uEventInfo.size(); ++i) {
UEventInfo uei = uEventInfo.get(i);
- if (name.equals(uei.getDevName())) {
+ if (devPath.equals(uei.getDevPath())) {
update(name, uei.computeNewHeadsetState(mHeadsetState, state));
return;
}
@@ -213,7 +204,7 @@ class WiredAccessoryObserver extends UEventObserver {
curState = Integer.valueOf((new String(buffer, 0, len)).trim());
if (curState > 0) {
- updateState(uei.getDevName(), curState);
+ updateState(uei.getDevPath(), uei.getDevName(), curState);
}
} catch (FileNotFoundException e) {
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 60749b3..78f17bc 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -152,6 +152,7 @@ import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
+import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;
@@ -3038,7 +3039,7 @@ public final class ActivityManagerService extends ActivityManagerNative
}
final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
- if (IS_USER_BUILD) {
+ if (true || IS_USER_BUILD) {
return;
}
String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
@@ -3582,9 +3583,14 @@ public final class ActivityManagerService extends ActivityManagerNative
if (doit) {
procs.add(app);
}
- } else if ((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
- || app.processName.equals(packageName)
- || app.processName.startsWith(procNamePrefix)) {
+ // If uid is specified and the uid and process name match
+ // Or, the uid is not specified and the process name matches
+ } else if (((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
+ && (app.processName.equals(packageName)
+ || app.processName.startsWith(procNamePrefix)))
+ || (uid < 0
+ && (app.processName.equals(packageName)
+ || app.processName.startsWith(procNamePrefix)))) {
if (app.setAdj >= minOomAdj) {
if (!doit) {
return true;
@@ -3635,7 +3641,8 @@ public final class ActivityManagerService extends ActivityManagerNative
for (i=0; i<mMainStack.mHistory.size(); i++) {
ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
final boolean samePackage = r.packageName.equals(name);
- if ((samePackage || r.task == lastTask)
+ if (r.userId == userId
+ && (samePackage || r.task == lastTask)
&& (r.app == null || evenPersistent || !r.app.persistent)) {
if (!doit) {
if (r.finishing) {
@@ -3685,7 +3692,7 @@ public final class ActivityManagerService extends ActivityManagerNative
}
ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
- for (ContentProviderRecord provider : mProviderMap.getProvidersByClass(-1).values()) {
+ for (ContentProviderRecord provider : mProviderMap.getProvidersByClass(userId).values()) {
if (provider.info.packageName.equals(name)
&& (provider.proc == null || evenPersistent || !provider.proc.persistent)) {
if (!doit) {
@@ -4118,7 +4125,16 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
}, pkgFilter);
-
+
+ IntentFilter userFilter = new IntentFilter();
+ userFilter.addAction(Intent.ACTION_USER_REMOVED);
+ mContext.registerReceiver(new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ onUserRemoved(intent);
+ }
+ }, userFilter);
+
synchronized (this) {
// Ensure that any processes we had put on hold are now started
// up.
@@ -12469,7 +12485,7 @@ public final class ActivityManagerService extends ActivityManagerNative
if (DEBUG_BROADCAST_LIGHT) Slog.v(
TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
- + " ordered=" + ordered);
+ + " ordered=" + ordered + " userid=" + userId);
if ((resultTo != null) && !ordered) {
Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
}
@@ -14593,25 +14609,6 @@ public final class ActivityManagerService extends ActivityManagerNative
private int mCurrentUserId;
private SparseIntArray mLoggedInUsers = new SparseIntArray(5);
- private ArrayList<UserListener> mUserListeners = new ArrayList<UserListener>(3);
-
- public interface UserListener {
- public void onUserChanged(int userId);
-
- public void onUserAdded(int userId);
-
- public void onUserRemoved(int userId);
-
- public void onUserLoggedOut(int userId);
- }
-
- public void addUserListener(UserListener listener) {
- synchronized (this) {
- if (!mUserListeners.contains(listener)) {
- mUserListeners.add(listener);
- }
- }
- }
public boolean switchUser(int userId) {
final int callingUid = Binder.getCallingUid();
@@ -14622,8 +14619,6 @@ public final class ActivityManagerService extends ActivityManagerNative
if (mCurrentUserId == userId)
return true;
- ArrayList<UserListener> listeners;
-
synchronized (this) {
// Check if user is already logged in, otherwise check if user exists first before
// adding to the list of logged in users.
@@ -14640,23 +14635,44 @@ public final class ActivityManagerService extends ActivityManagerNative
startHomeActivityLocked(userId);
}
- listeners = (ArrayList<UserListener>) mUserListeners.clone();
- }
- // Inform the listeners
- for (UserListener listener : listeners) {
- listener.onUserChanged(userId);
}
+
+ // Inform of user switch
+ Intent addedIntent = new Intent(Intent.ACTION_USER_SWITCHED);
+ addedIntent.putExtra(Intent.EXTRA_USERID, userId);
+ mContext.sendBroadcast(addedIntent, android.Manifest.permission.MANAGE_ACCOUNTS);
+
return true;
}
- private boolean userExists(int userId) {
- try {
- List<UserInfo> users = AppGlobals.getPackageManager().getUsers();
- for (UserInfo user : users) {
- if (user.id == userId) {
- return true;
+ private void onUserRemoved(Intent intent) {
+ int extraUserId = intent.getIntExtra(Intent.EXTRA_USERID, -1);
+ if (extraUserId < 1) return;
+
+ // Kill all the processes for the user
+ ArrayList<Pair<String, Integer>> pkgAndUids = new ArrayList<Pair<String,Integer>>();
+ synchronized (this) {
+ HashMap<String,SparseArray<ProcessRecord>> map = mProcessNames.getMap();
+ for (Entry<String, SparseArray<ProcessRecord>> uidMap : map.entrySet()) {
+ SparseArray<ProcessRecord> uids = uidMap.getValue();
+ for (int i = 0; i < uids.size(); i++) {
+ if (UserId.getUserId(uids.keyAt(i)) == extraUserId) {
+ pkgAndUids.add(new Pair<String,Integer>(uidMap.getKey(), uids.keyAt(i)));
+ }
}
}
+
+ for (Pair<String,Integer> pkgAndUid : pkgAndUids) {
+ forceStopPackageLocked(pkgAndUid.first, pkgAndUid.second,
+ false, false, true, true, extraUserId);
+ }
+ }
+ }
+
+ private boolean userExists(int userId) {
+ try {
+ UserInfo user = AppGlobals.getPackageManager().getUser(userId);
+ return user != null;
} catch (RemoteException re) {
// Won't happen, in same process
}
diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java
index 067bf28..1593707 100644
--- a/services/java/com/android/server/pm/PackageManagerService.java
+++ b/services/java/com/android/server/pm/PackageManagerService.java
@@ -134,6 +134,7 @@ import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Map.Entry;
import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
@@ -404,7 +405,7 @@ public class PackageManagerService extends IPackageManager.Stub {
// Delay time in millisecs
static final int BROADCAST_DELAY = 10 * 1000;
- final UserManager mUserManager;
+ static UserManager sUserManager;
// Stores a list of users whose package restrictions file needs to be updated
private HashSet<Integer> mDirtyUsers = new HashSet<Integer>();
@@ -632,7 +633,7 @@ public class PackageManagerService extends IPackageManager.Stub {
packages[i] = ent.getKey();
components[i] = ent.getValue();
PackageSetting ps = mSettings.mPackages.get(ent.getKey());
- uids[i] = (ps != null) ? ps.uid : -1;
+ uids[i] = (ps != null) ? ps.appId : -1;
i++;
}
size = i;
@@ -676,14 +677,15 @@ public class PackageManagerService extends IPackageManager.Stub {
}
sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
res.pkg.applicationInfo.packageName,
- extras, null, null);
+ extras, null, null, UserId.USER_ALL);
if (update) {
sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
res.pkg.applicationInfo.packageName,
- extras, null, null);
+ extras, null, null, UserId.USER_ALL);
sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
null, null,
- res.pkg.applicationInfo.packageName, null);
+ res.pkg.applicationInfo.packageName, null,
+ UserId.USER_ALL);
}
if (res.removedInfo.args != null) {
// Remove the replaced package's older resources safely now
@@ -820,6 +822,7 @@ public class PackageManagerService extends IPackageManager.Stub {
}
void scheduleWritePackageRestrictionsLocked(int userId) {
+ if (!sUserManager.exists(userId)) return;
mDirtyUsers.add(userId);
if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {
mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY);
@@ -920,7 +923,7 @@ public class PackageManagerService extends IPackageManager.Stub {
mUserAppDataDir = new File(dataDir, "user");
mDrmAppPrivateInstallDir = new File(dataDir, "app-private");
- mUserManager = new UserManager(mInstaller, mUserAppDataDir);
+ sUserManager = new UserManager(mInstaller, mUserAppDataDir);
readPermissions();
@@ -1086,7 +1089,7 @@ public class PackageManagerService extends IPackageManager.Stub {
+ " no longer exists; wiping its data";
reportSettingsProblem(Log.WARN, msg);
mInstaller.remove(ps.name, 0);
- mUserManager.removePackageForAllUsers(ps.name);
+ sUserManager.removePackageForAllUsers(ps.name);
}
}
}
@@ -1242,7 +1245,7 @@ public class PackageManagerService extends IPackageManager.Stub {
Slog.w(TAG, "Couldn't remove app data directory for package: "
+ ps.name + ", retcode=" + retCode);
} else {
- mUserManager.removePackageForAllUsers(ps.name);
+ sUserManager.removePackageForAllUsers(ps.name);
}
if (ps.codePath != null) {
if (!ps.codePath.delete()) {
@@ -1506,29 +1509,39 @@ public class PackageManagerService extends IPackageManager.Stub {
return cur;
}
- PackageInfo generatePackageInfo(PackageParser.Package p, int flags) {
+ PackageInfo generatePackageInfo(PackageParser.Package p, int flags, int userId) {
+ if (!sUserManager.exists(userId)) return null;
+ PackageInfo pi;
if ((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) {
// The package has been uninstalled but has retained data and resources.
- return PackageParser.generatePackageInfo(p, null, flags, 0, 0, null);
- }
- final PackageSetting ps = (PackageSetting)p.mExtras;
- if (ps == null) {
- return null;
+ pi = PackageParser.generatePackageInfo(p, null, flags, 0, 0, null, false, 0, userId);
+ } else {
+ final PackageSetting ps = (PackageSetting) p.mExtras;
+ if (ps == null) {
+ return null;
+ }
+ final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
+ pi = PackageParser.generatePackageInfo(p, gp.gids, flags,
+ ps.firstInstallTime, ps.lastUpdateTime, gp.grantedPermissions,
+ ps.getStopped(userId), ps.getEnabled(userId), userId);
+ pi.applicationInfo.enabledSetting = ps.getEnabled(userId);
+ pi.applicationInfo.enabled =
+ pi.applicationInfo.enabledSetting == COMPONENT_ENABLED_STATE_DEFAULT
+ || pi.applicationInfo.enabledSetting == COMPONENT_ENABLED_STATE_ENABLED;
}
- final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
- return PackageParser.generatePackageInfo(p, gp.gids, flags,
- ps.firstInstallTime, ps.lastUpdateTime, gp.grantedPermissions);
+ return pi;
}
@Override
public PackageInfo getPackageInfo(String packageName, int flags, int userId) {
+ if (!sUserManager.exists(userId)) return null;
// reader
synchronized (mPackages) {
PackageParser.Package p = mPackages.get(packageName);
if (DEBUG_PACKAGE_INFO)
Log.v(TAG, "getPackageInfo " + packageName + ": " + p);
if (p != null) {
- return generatePackageInfo(p, flags);
+ return generatePackageInfo(p, flags, userId);
}
if((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) {
return generatePackageInfoFromSettingsLPw(packageName, flags, userId);
@@ -1563,6 +1576,7 @@ public class PackageManagerService extends IPackageManager.Stub {
@Override
public int getPackageUid(String packageName, int userId) {
+ if (!sUserManager.exists(userId)) return -1;
// reader
synchronized (mPackages) {
PackageParser.Package p = mPackages.get(packageName);
@@ -1673,6 +1687,7 @@ public class PackageManagerService extends IPackageManager.Stub {
private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags,
int userId) {
+ if (!sUserManager.exists(userId)) return null;
PackageSetting ps = mSettings.mPackages.get(packageName);
if (ps != null) {
if (ps.pkg == null) {
@@ -1682,15 +1697,18 @@ public class PackageManagerService extends IPackageManager.Stub {
}
return null;
}
- return PackageParser.generateApplicationInfo(ps.pkg, flags);
+ return PackageParser.generateApplicationInfo(ps.pkg, flags, ps.getStopped(userId),
+ ps.getEnabled(userId), userId);
}
return null;
}
private PackageInfo generatePackageInfoFromSettingsLPw(String packageName, int flags,
int userId) {
+ if (!sUserManager.exists(userId)) return null;
PackageSetting ps = mSettings.mPackages.get(packageName);
if (ps != null) {
+ PackageParser.Package pkg = new PackageParser.Package(packageName);
if (ps.pkg == null) {
ps.pkg = new PackageParser.Package(packageName);
ps.pkg.applicationInfo.packageName = packageName;
@@ -1701,15 +1719,16 @@ public class PackageManagerService extends IPackageManager.Stub {
getDataPathForPackage(ps.pkg.packageName, 0).getPath();
ps.pkg.applicationInfo.nativeLibraryDir = ps.nativeLibraryPathString;
}
- ps.pkg.mSetEnabled = ps.getEnabled(userId);
- ps.pkg.mSetStopped = ps.getStopped(userId);
- return generatePackageInfo(ps.pkg, flags);
+ // ps.pkg.mSetEnabled = ps.getEnabled(userId);
+ // ps.pkg.mSetStopped = ps.getStopped(userId);
+ return generatePackageInfo(ps.pkg, flags, userId);
}
return null;
}
@Override
public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
+ if (!sUserManager.exists(userId)) return null;
// writer
synchronized (mPackages) {
PackageParser.Package p = mPackages.get(packageName);
@@ -1717,8 +1736,11 @@ public class PackageManagerService extends IPackageManager.Stub {
TAG, "getApplicationInfo " + packageName
+ ": " + p);
if (p != null) {
+ PackageSetting ps = mSettings.mPackages.get(packageName);
+ if (ps == null) return null;
// Note: isEnabledLP() does not apply here - always return info
- return PackageParser.generateApplicationInfo(p, flags);
+ return PackageParser.generateApplicationInfo(p, flags, ps.getStopped(userId),
+ ps.getEnabled(userId));
}
if ("android".equals(packageName)||"system".equals(packageName)) {
return mAndroidApplication;
@@ -1782,12 +1804,16 @@ public class PackageManagerService extends IPackageManager.Stub {
@Override
public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
+ if (!sUserManager.exists(userId)) return null;
synchronized (mPackages) {
PackageParser.Activity a = mActivities.mActivities.get(component);
if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a);
if (a != null && mSettings.isEnabledLPr(a.info, flags, userId)) {
- return PackageParser.generateActivityInfo(a, flags, userId);
+ PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
+ if (ps == null) return null;
+ return PackageParser.generateActivityInfo(a, flags, ps.getStopped(userId),
+ ps.getEnabled(userId), userId);
}
if (mResolveComponentName.equals(component)) {
return mResolveActivity;
@@ -1798,12 +1824,16 @@ public class PackageManagerService extends IPackageManager.Stub {
@Override
public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) {
+ if (!sUserManager.exists(userId)) return null;
synchronized (mPackages) {
PackageParser.Activity a = mReceivers.mActivities.get(component);
if (DEBUG_PACKAGE_INFO) Log.v(
TAG, "getReceiverInfo " + component + ": " + a);
if (a != null && mSettings.isEnabledLPr(a.info, flags, userId)) {
- return PackageParser.generateActivityInfo(a, flags, userId);
+ PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
+ if (ps == null) return null;
+ return PackageParser.generateActivityInfo(a, flags, ps.getStopped(userId),
+ ps.getEnabled(userId), userId);
}
}
return null;
@@ -1811,12 +1841,16 @@ public class PackageManagerService extends IPackageManager.Stub {
@Override
public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) {
+ if (!sUserManager.exists(userId)) return null;
synchronized (mPackages) {
PackageParser.Service s = mServices.mServices.get(component);
if (DEBUG_PACKAGE_INFO) Log.v(
TAG, "getServiceInfo " + component + ": " + s);
if (s != null && mSettings.isEnabledLPr(s.info, flags, userId)) {
- return PackageParser.generateServiceInfo(s, flags, userId);
+ PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
+ if (ps == null) return null;
+ return PackageParser.generateServiceInfo(s, flags, ps.getStopped(userId),
+ ps.getEnabled(userId), userId);
}
}
return null;
@@ -1824,12 +1858,16 @@ public class PackageManagerService extends IPackageManager.Stub {
@Override
public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) {
+ if (!sUserManager.exists(userId)) return null;
synchronized (mPackages) {
PackageParser.Provider p = mProvidersByComponent.get(component);
if (DEBUG_PACKAGE_INFO) Log.v(
TAG, "getProviderInfo " + component + ": " + p);
if (p != null && mSettings.isEnabledLPr(p.info, flags, userId)) {
- return PackageParser.generateProviderInfo(p, flags, userId);
+ PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
+ if (ps == null) return null;
+ return PackageParser.generateProviderInfo(p, flags, ps.getStopped(userId),
+ ps.getEnabled(userId), userId);
}
}
return null;
@@ -2253,6 +2291,7 @@ public class PackageManagerService extends IPackageManager.Stub {
@Override
public ResolveInfo resolveIntent(Intent intent, String resolvedType,
int flags, int userId) {
+ if (!sUserManager.exists(userId)) return null;
List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId);
return chooseBestActivity(intent, resolvedType, flags, query, userId);
}
@@ -2294,6 +2333,7 @@ public class PackageManagerService extends IPackageManager.Stub {
ResolveInfo findPreferredActivity(Intent intent, String resolvedType,
int flags, List<ResolveInfo> query, int priority, int userId) {
+ if (!sUserManager.exists(userId)) return null;
// writer
synchronized (mPackages) {
if (intent.getSelector() != null) {
@@ -2389,6 +2429,7 @@ public class PackageManagerService extends IPackageManager.Stub {
@Override
public List<ResolveInfo> queryIntentActivities(Intent intent,
String resolvedType, int flags, int userId) {
+ if (!sUserManager.exists(userId)) return null;
ComponentName comp = intent.getComponent();
if (comp == null) {
if (intent.getSelector() != null) {
@@ -2427,6 +2468,7 @@ public class PackageManagerService extends IPackageManager.Stub {
public List<ResolveInfo> queryIntentActivityOptions(ComponentName caller,
Intent[] specifics, String[] specificTypes, Intent intent,
String resolvedType, int flags, int userId) {
+ if (!sUserManager.exists(userId)) return null;
final String resultsAction = intent.getAction();
List<ResolveInfo> results = queryIntentActivities(intent, resolvedType, flags
@@ -2596,6 +2638,7 @@ public class PackageManagerService extends IPackageManager.Stub {
@Override
public List<ResolveInfo> queryIntentReceivers(Intent intent, String resolvedType, int flags,
int userId) {
+ if (!sUserManager.exists(userId)) return null;
ComponentName comp = intent.getComponent();
if (comp == null) {
if (intent.getSelector() != null) {
@@ -2632,6 +2675,7 @@ public class PackageManagerService extends IPackageManager.Stub {
@Override
public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) {
List<ResolveInfo> query = queryIntentServices(intent, resolvedType, flags, userId);
+ if (!sUserManager.exists(userId)) return null;
if (query != null) {
if (query.size() >= 1) {
// If there is more than one service with the same priority,
@@ -2645,6 +2689,7 @@ public class PackageManagerService extends IPackageManager.Stub {
@Override
public List<ResolveInfo> queryIntentServices(Intent intent, String resolvedType, int flags,
int userId) {
+ if (!sUserManager.exists(userId)) return null;
ComponentName comp = intent.getComponent();
if (comp == null) {
if (intent.getSelector() != null) {
@@ -2723,7 +2768,7 @@ public class PackageManagerService extends IPackageManager.Stub {
} else {
final PackageParser.Package p = mPackages.get(packageName);
if (p != null) {
- pi = generatePackageInfo(p, flags);
+ pi = generatePackageInfo(p, flags, userId);
}
}
@@ -2743,6 +2788,7 @@ public class PackageManagerService extends IPackageManager.Stub {
@Override
public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags,
String lastRead, int userId) {
+ if (!sUserManager.exists(userId)) return null;
final ParceledListSlice<ApplicationInfo> list = new ParceledListSlice<ApplicationInfo>();
final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0;
final String[] keys;
@@ -2763,15 +2809,16 @@ public class PackageManagerService extends IPackageManager.Stub {
final String packageName = keys[i++];
ApplicationInfo ai = null;
+ final PackageSetting ps = mSettings.mPackages.get(packageName);
if (listUninstalled) {
- final PackageSetting ps = mSettings.mPackages.get(packageName);
if (ps != null) {
ai = generateApplicationInfoFromSettingsLPw(ps.name, flags, userId);
}
} else {
final PackageParser.Package p = mPackages.get(packageName);
- if (p != null) {
- ai = PackageParser.generateApplicationInfo(p, flags, userId);
+ if (p != null && ps != null) {
+ ai = PackageParser.generateApplicationInfo(p, flags, ps.getStopped(userId),
+ ps.getEnabled(userId), userId);
}
}
@@ -2794,13 +2841,17 @@ public class PackageManagerService extends IPackageManager.Stub {
// reader
synchronized (mPackages) {
final Iterator<PackageParser.Package> i = mPackages.values().iterator();
- final int userId = UserId.getUserId(Binder.getCallingUid());
+ final int userId = UserId.getCallingUserId();
while (i.hasNext()) {
final PackageParser.Package p = i.next();
if (p.applicationInfo != null
&& (p.applicationInfo.flags&ApplicationInfo.FLAG_PERSISTENT) != 0
&& (!mSafeMode || isSystemApp(p))) {
- finalList.add(PackageParser.generateApplicationInfo(p, flags, userId));
+ PackageSetting ps = mSettings.mPackages.get(p.packageName);
+ finalList.add(PackageParser.generateApplicationInfo(p, flags,
+ ps != null ? ps.getStopped(userId) : false,
+ ps != null ? ps.getEnabled(userId) : COMPONENT_ENABLED_STATE_DEFAULT,
+ userId));
}
}
}
@@ -2810,14 +2861,21 @@ public class PackageManagerService extends IPackageManager.Stub {
@Override
public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
+ if (!sUserManager.exists(userId)) return null;
// reader
synchronized (mPackages) {
final PackageParser.Provider provider = mProviders.get(name);
+ PackageSetting ps = provider != null
+ ? mSettings.mPackages.get(provider.owner.packageName)
+ : null;
return provider != null
&& mSettings.isEnabledLPr(provider.info, flags, userId)
&& (!mSafeMode || (provider.info.applicationInfo.flags
&ApplicationInfo.FLAG_SYSTEM) != 0)
- ? PackageParser.generateProviderInfo(provider, flags, userId)
+ ? PackageParser.generateProviderInfo(provider, flags,
+ ps != null ? ps.getStopped(userId) : false,
+ ps != null ? ps.getEnabled(userId) : COMPONENT_ENABLED_STATE_DEFAULT,
+ userId)
: null;
}
}
@@ -2831,16 +2889,20 @@ public class PackageManagerService extends IPackageManager.Stub {
synchronized (mPackages) {
final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProviders.entrySet()
.iterator();
- final int userId = UserId.getUserId(Binder.getCallingUid());
+ final int userId = UserId.getCallingUserId();
while (i.hasNext()) {
Map.Entry<String, PackageParser.Provider> entry = i.next();
PackageParser.Provider p = entry.getValue();
+ PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
if (p.syncable
&& (!mSafeMode || (p.info.applicationInfo.flags
&ApplicationInfo.FLAG_SYSTEM) != 0)) {
outNames.add(entry.getKey());
- outInfo.add(PackageParser.generateProviderInfo(p, 0, userId));
+ outInfo.add(PackageParser.generateProviderInfo(p, 0,
+ ps != null ? ps.getStopped(userId) : false,
+ ps != null ? ps.getEnabled(userId) : COMPONENT_ENABLED_STATE_DEFAULT,
+ userId));
}
}
}
@@ -2857,6 +2919,7 @@ public class PackageManagerService extends IPackageManager.Stub {
UserId.getUserId(uid) : UserId.getCallingUserId();
while (i.hasNext()) {
final PackageParser.Provider p = i.next();
+ PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
if (p.info.authority != null
&& (processName == null
|| (p.info.processName.equals(processName)
@@ -2867,7 +2930,10 @@ public class PackageManagerService extends IPackageManager.Stub {
if (finalList == null) {
finalList = new ArrayList<ProviderInfo>(3);
}
- finalList.add(PackageParser.generateProviderInfo(p, flags, userId));
+ finalList.add(PackageParser.generateProviderInfo(p, flags,
+ ps != null ? ps.getStopped(userId) : false,
+ ps != null ? ps.getEnabled(userId) : COMPONENT_ENABLED_STATE_DEFAULT,
+ userId));
}
}
}
@@ -3511,7 +3577,7 @@ public class PackageManagerService extends IPackageManager.Stub {
pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
}
- pkg.applicationInfo.uid = pkgSetting.uid;
+ pkg.applicationInfo.uid = pkgSetting.appId;
pkg.mExtras = pkgSetting;
if (!verifySignaturesLP(pkgSetting, pkg)) {
@@ -3618,7 +3684,7 @@ public class PackageManagerService extends IPackageManager.Stub {
if (ret >= 0) {
// TODO: Kill the processes first
// Remove the data directories for all users
- mUserManager.removePackageForAllUsers(pkgName);
+ sUserManager.removePackageForAllUsers(pkgName);
// Old data gone!
String msg = "System package " + pkg.packageName
+ " has changed from uid: "
@@ -3639,7 +3705,7 @@ public class PackageManagerService extends IPackageManager.Stub {
return null;
}
// Create data directories for all users
- mUserManager.installPackageForAllUsers(pkgName,
+ sUserManager.installPackageForAllUsers(pkgName,
pkg.applicationInfo.uid);
}
if (!recovered) {
@@ -3681,7 +3747,7 @@ public class PackageManagerService extends IPackageManager.Stub {
return null;
}
// Create data directories for all users
- mUserManager.installPackageForAllUsers(pkgName, pkg.applicationInfo.uid);
+ sUserManager.installPackageForAllUsers(pkgName, pkg.applicationInfo.uid);
if (dataPath.exists()) {
pkg.applicationInfo.dataDir = dataPath.getPath();
@@ -4510,12 +4576,14 @@ public class PackageManagerService extends IPackageManager.Stub {
extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> {
public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
boolean defaultOnly, int userId) {
+ if (!sUserManager.exists(userId)) return null;
mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
return super.queryIntent(intent, resolvedType, defaultOnly, userId);
}
public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
int userId) {
+ if (!sUserManager.exists(userId)) return null;
mFlags = flags;
return super.queryIntent(intent, resolvedType,
(flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
@@ -4523,6 +4591,7 @@ public class PackageManagerService extends IPackageManager.Stub {
public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) {
+ if (!sUserManager.exists(userId)) return null;
if (packageActivities == null) {
return null;
}
@@ -4605,6 +4674,7 @@ public class PackageManagerService extends IPackageManager.Stub {
@Override
protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) {
+ if (!sUserManager.exists(userId)) return true;
PackageParser.Package p = filter.activity.owner;
if (p != null) {
PackageSetting ps = (PackageSetting)p.mExtras;
@@ -4626,6 +4696,7 @@ public class PackageManagerService extends IPackageManager.Stub {
@Override
protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info,
int match, int userId) {
+ if (!sUserManager.exists(userId)) return null;
if (!mSettings.isEnabledLPr(info.activity.info, mFlags, userId)) {
return null;
}
@@ -4635,7 +4706,11 @@ public class PackageManagerService extends IPackageManager.Stub {
return null;
}
final ResolveInfo res = new ResolveInfo();
- res.activityInfo = PackageParser.generateActivityInfo(activity, mFlags, userId);
+ PackageSetting ps = (PackageSetting) activity.owner.mExtras;
+ res.activityInfo = PackageParser.generateActivityInfo(activity, mFlags,
+ ps != null ? ps.getStopped(userId) : false,
+ ps != null ? ps.getEnabled(userId) : COMPONENT_ENABLED_STATE_DEFAULT,
+ userId);
if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
res.filter = info;
}
@@ -4696,6 +4771,7 @@ public class PackageManagerService extends IPackageManager.Stub {
public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
int userId) {
+ if (!sUserManager.exists(userId)) return null;
mFlags = flags;
return super.queryIntent(intent, resolvedType,
(flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
@@ -4703,6 +4779,7 @@ public class PackageManagerService extends IPackageManager.Stub {
public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
int flags, ArrayList<PackageParser.Service> packageServices, int userId) {
+ if (!sUserManager.exists(userId)) return null;
if (packageServices == null) {
return null;
}
@@ -4780,6 +4857,7 @@ public class PackageManagerService extends IPackageManager.Stub {
@Override
protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) {
+ if (!sUserManager.exists(userId)) return true;
PackageParser.Package p = filter.service.owner;
if (p != null) {
PackageSetting ps = (PackageSetting)p.mExtras;
@@ -4802,6 +4880,7 @@ public class PackageManagerService extends IPackageManager.Stub {
@Override
protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter,
int match, int userId) {
+ if (!sUserManager.exists(userId)) return null;
final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter;
if (!mSettings.isEnabledLPr(info.service.info, mFlags, userId)) {
return null;
@@ -4812,7 +4891,11 @@ public class PackageManagerService extends IPackageManager.Stub {
return null;
}
final ResolveInfo res = new ResolveInfo();
- res.serviceInfo = PackageParser.generateServiceInfo(service, mFlags, userId);
+ PackageSetting ps = (PackageSetting) service.owner.mExtras;
+ res.serviceInfo = PackageParser.generateServiceInfo(service, mFlags,
+ ps != null ? ps.getStopped(userId) : false,
+ ps != null ? ps.getEnabled(userId) : COMPONENT_ENABLED_STATE_DEFAULT,
+ userId);
if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
res.filter = filter;
}
@@ -4903,23 +4986,32 @@ public class PackageManagerService extends IPackageManager.Stub {
};
static final void sendPackageBroadcast(String action, String pkg,
- Bundle extras, String targetPkg, IIntentReceiver finishedReceiver) {
+ Bundle extras, String targetPkg, IIntentReceiver finishedReceiver, int userId) {
IActivityManager am = ActivityManagerNative.getDefault();
if (am != null) {
try {
- final Intent intent = new Intent(action,
- pkg != null ? Uri.fromParts("package", pkg, null) : null);
- if (extras != null) {
- intent.putExtras(extras);
- }
- if (targetPkg != null) {
- intent.setPackage(targetPkg);
- }
- intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
- // TODO: Fix the userId argument
- am.broadcastIntent(null, intent, null, finishedReceiver,
- 0, null, null, null, finishedReceiver != null, false,
- Binder.getOrigCallingUser());
+ int[] userIds = userId == UserId.USER_ALL
+ ? sUserManager.getUserIds()
+ : new int[] {userId};
+ for (int id : userIds) {
+ final Intent intent = new Intent(action,
+ pkg != null ? Uri.fromParts("package", pkg, null) : null);
+ if (extras != null) {
+ intent.putExtras(extras);
+ }
+ if (targetPkg != null) {
+ intent.setPackage(targetPkg);
+ }
+ // Modify the UID when posting to other users
+ int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
+ if (uid > 0 && id > 0) {
+ uid = UserId.getUid(id, UserId.getAppId(uid));
+ intent.putExtra(Intent.EXTRA_UID, uid);
+ }
+ intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
+ am.broadcastIntent(null, intent, null, finishedReceiver,
+ 0, null, null, null, finishedReceiver != null, false, id);
+ }
} catch (RemoteException ex) {
}
}
@@ -5062,13 +5154,13 @@ public class PackageManagerService extends IPackageManager.Stub {
extras.putInt(Intent.EXTRA_UID, removedUid);
extras.putBoolean(Intent.EXTRA_DATA_REMOVED, false);
sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage,
- extras, null, null);
+ extras, null, null, UserId.USER_ALL);
}
if (addedPackage != null) {
Bundle extras = new Bundle(1);
extras.putInt(Intent.EXTRA_UID, addedUid);
sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, addedPackage,
- extras, null, null);
+ extras, null, null, UserId.USER_ALL);
}
}
@@ -7092,11 +7184,11 @@ public class PackageManagerService extends IPackageManager.Stub {
extras.putBoolean(Intent.EXTRA_REPLACING, true);
sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
- extras, null, null);
+ extras, null, null, UserId.USER_ALL);
sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
- extras, null, null);
+ extras, null, null, UserId.USER_ALL);
sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, null,
- null, packageName, null);
+ null, packageName, null, UserId.USER_ALL);
}
}
// Force a gc here.
@@ -7129,14 +7221,15 @@ public class PackageManagerService extends IPackageManager.Stub {
}
if (removedPackage != null) {
sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage,
- extras, null, null);
+ extras, null, null, UserId.USER_ALL);
if (fullRemove && !replacing) {
sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED, removedPackage,
- extras, null, null);
+ extras, null, null, UserId.USER_ALL);
}
}
if (removedUid >= 0) {
- sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, extras, null, null);
+ sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, extras, null, null,
+ UserId.getUserId(removedUid));
}
}
}
@@ -7168,7 +7261,7 @@ public class PackageManagerService extends IPackageManager.Stub {
// we don't consider this to be a failure of the core package deletion
} else {
// TODO: Kill the processes first
- mUserManager.removePackageForAllUsers(packageName);
+ sUserManager.removePackageForAllUsers(packageName);
}
schedulePackageCleaning(packageName);
}
@@ -7732,12 +7825,14 @@ public class PackageManagerService extends IPackageManager.Stub {
@Override
public void setApplicationEnabledSetting(String appPackageName,
int newState, int flags, int userId) {
+ if (!sUserManager.exists(userId)) return;
setEnabledSetting(appPackageName, null, newState, flags, userId);
}
@Override
public void setComponentEnabledSetting(ComponentName componentName,
int newState, int flags, int userId) {
+ if (!sUserManager.exists(userId)) return;
setEnabledSetting(componentName.getPackageName(),
componentName.getClassName(), newState, flags, userId);
}
@@ -7776,11 +7871,11 @@ public class PackageManagerService extends IPackageManager.Stub {
+ "/" + className);
}
// Allow root and verify that userId is not being specified by a different user
- if (!allowedByPermission && !UserId.isSameApp(uid, pkgSetting.uid)) {
+ if (!allowedByPermission && !UserId.isSameApp(uid, pkgSetting.appId)) {
throw new SecurityException(
"Permission Denial: attempt to change component state from pid="
+ Binder.getCallingPid()
- + ", uid=" + uid + ", package uid=" + pkgSetting.uid);
+ + ", uid=" + uid + ", package uid=" + pkgSetting.appId);
}
if (className == null) {
// We're dealing with an application/package level state change
@@ -7789,7 +7884,7 @@ public class PackageManagerService extends IPackageManager.Stub {
return;
}
pkgSetting.setEnabled(newState, userId);
- pkgSetting.pkg.mSetEnabled = newState;
+ // pkgSetting.pkg.mSetEnabled = newState;
} else {
// We're dealing with a component level state change
// First, verify that this is a valid class name.
@@ -7825,7 +7920,7 @@ public class PackageManagerService extends IPackageManager.Stub {
}
}
mSettings.writePackageRestrictionsLPr(userId);
- packageUid = pkgSetting.uid;
+ packageUid = UserId.getUid(userId, pkgSetting.appId);
components = mPendingBroadcasts.get(packageName);
final boolean newPackage = components == null;
if (newPackage) {
@@ -7873,10 +7968,12 @@ public class PackageManagerService extends IPackageManager.Stub {
extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList);
extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag);
extras.putInt(Intent.EXTRA_UID, packageUid);
- sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED, packageName, extras, null, null);
+ sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED, packageName, extras, null, null,
+ UserId.getUserId(packageUid));
}
public void setPackageStoppedState(String packageName, boolean stopped, int userId) {
+ if (!sUserManager.exists(userId)) return;
final int uid = Binder.getCallingUid();
final int permission = mContext.checkCallingOrSelfPermission(
android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
@@ -7900,6 +7997,7 @@ public class PackageManagerService extends IPackageManager.Stub {
@Override
public int getApplicationEnabledSetting(String packageName, int userId) {
+ if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
int uid = Binder.getCallingUid();
checkValidCaller(uid, userId);
// reader
@@ -7910,6 +8008,7 @@ public class PackageManagerService extends IPackageManager.Stub {
@Override
public int getComponentEnabledSetting(ComponentName componentName, int userId) {
+ if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
int uid = Binder.getCallingUid();
checkValidCaller(uid, userId);
// reader
@@ -8383,7 +8482,7 @@ public class PackageManagerService extends IPackageManager.Stub {
+ " at code path: " + ps.codePathString);
// We do have a valid package installed on sdcard
processCids.put(args, ps.codePathString);
- int uid = ps.uid;
+ int uid = ps.appId;
if (uid != -1) {
uidList[num++] = uid;
}
@@ -8436,7 +8535,7 @@ public class PackageManagerService extends IPackageManager.Stub {
}
String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
: Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE;
- sendPackageBroadcast(action, null, extras, null, finishedReceiver);
+ sendPackageBroadcast(action, null, extras, null, finishedReceiver, UserId.USER_ALL);
}
}
@@ -8860,8 +8959,12 @@ public class PackageManagerService extends IPackageManager.Stub {
// TODO(kroot): Add a real permission for creating users
enforceSystemOrRoot("Only the system can create users");
- // TODO(kroot): fix this API
- UserInfo userInfo = mUserManager.createUser(name, flags, new ArrayList<ApplicationInfo>());
+ UserInfo userInfo = sUserManager.createUser(name, flags);
+ if (userInfo != null) {
+ Intent addedIntent = new Intent(Intent.ACTION_USER_ADDED);
+ addedIntent.putExtra(Intent.EXTRA_USERID, userInfo.id);
+ mContext.sendBroadcast(addedIntent, android.Manifest.permission.MANAGE_ACCOUNTS);
+ }
return userInfo;
}
@@ -8869,13 +8972,34 @@ public class PackageManagerService extends IPackageManager.Stub {
// TODO(kroot): Add a real permission for removing users
enforceSystemOrRoot("Only the system can remove users");
- if (userId == 0) {
+ if (userId == 0 || !sUserManager.exists(userId)) {
return false;
}
- mUserManager.removeUser(userId);
+
+ cleanUpUser(userId);
+
+ if (sUserManager.removeUser(userId)) {
+ // Let other services shutdown any activity
+ Intent addedIntent = new Intent(Intent.ACTION_USER_REMOVED);
+ addedIntent.putExtra(Intent.EXTRA_USERID, userId);
+ mContext.sendBroadcast(addedIntent, android.Manifest.permission.MANAGE_ACCOUNTS);
+ }
+ sUserManager.removePackageFolders(userId);
return true;
}
+ private void cleanUpUser(int userId) {
+ // Disable all the packages for the user first
+ synchronized (mPackages) {
+ Set<Entry<String, PackageSetting>> entries = mSettings.mPackages.entrySet();
+ for (Entry<String, PackageSetting> entry : entries) {
+ entry.getValue().removeUser(userId);
+ }
+ if (mDirtyUsers.remove(userId));
+ mSettings.removeUserLPr(userId);
+ }
+ }
+
@Override
public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException {
mContext.enforceCallingOrSelfPermission(
@@ -8887,8 +9011,22 @@ public class PackageManagerService extends IPackageManager.Stub {
}
}
+ @Override
public List<UserInfo> getUsers() {
- return mUserManager.getUsers();
+ enforceSystemOrRoot("Only the system can query users");
+ return sUserManager.getUsers();
+ }
+
+ @Override
+ public UserInfo getUser(int userId) {
+ enforceSystemOrRoot("Only the system can remove users");
+ return sUserManager.getUser(userId);
+ }
+
+ @Override
+ public void updateUserName(int userId, String name) {
+ enforceSystemOrRoot("Only the system can rename users");
+ sUserManager.updateUserName(userId, name);
}
@Override
diff --git a/services/java/com/android/server/pm/PackageSetting.java b/services/java/com/android/server/pm/PackageSetting.java
index 48ed9bf..f7f0870 100644
--- a/services/java/com/android/server/pm/PackageSetting.java
+++ b/services/java/com/android/server/pm/PackageSetting.java
@@ -24,7 +24,7 @@ import java.io.File;
* Settings data for a particular package we know about.
*/
final class PackageSetting extends PackageSettingBase {
- int uid;
+ int appId;
PackageParser.Package pkg;
SharedUserSetting sharedUser;
@@ -41,7 +41,7 @@ final class PackageSetting extends PackageSettingBase {
PackageSetting(PackageSetting orig) {
super(orig);
- uid = orig.uid;
+ appId = orig.appId;
pkg = orig.pkg;
sharedUser = orig.sharedUser;
}
@@ -50,6 +50,6 @@ final class PackageSetting extends PackageSettingBase {
public String toString() {
return "PackageSetting{"
+ Integer.toHexString(System.identityHashCode(this))
- + " " + name + "/" + uid + "}";
+ + " " + name + "/" + appId + "}";
}
} \ No newline at end of file
diff --git a/services/java/com/android/server/pm/PackageSettingBase.java b/services/java/com/android/server/pm/PackageSettingBase.java
index b7cf8d6..56f2166 100644
--- a/services/java/com/android/server/pm/PackageSettingBase.java
+++ b/services/java/com/android/server/pm/PackageSettingBase.java
@@ -273,4 +273,13 @@ class PackageSettingBase extends GrantedPermissions {
return COMPONENT_ENABLED_STATE_DEFAULT;
}
}
+
+ void removeUser(int userId) {
+ enabled.delete(userId);
+ stopped.delete(userId);
+ enabledComponents.delete(userId);
+ disabledComponents.delete(userId);
+ notLaunched.delete(userId);
+ }
+
}
diff --git a/services/java/com/android/server/pm/Settings.java b/services/java/com/android/server/pm/Settings.java
index b541c8c..bb7f4fc 100644
--- a/services/java/com/android/server/pm/Settings.java
+++ b/services/java/com/android/server/pm/Settings.java
@@ -275,7 +275,7 @@ final class Settings {
p.pkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
}
PackageSetting ret = addPackageLPw(name, p.realName, p.codePath, p.resourcePath,
- p.nativeLibraryPathString, p.uid, p.versionCode, p.pkgFlags);
+ p.nativeLibraryPathString, p.appId, p.versionCode, p.pkgFlags);
mDisabledSysPackages.remove(name);
return ret;
}
@@ -284,7 +284,7 @@ final class Settings {
String nativeLibraryPathString, int uid, int vc, int pkgFlags) {
PackageSetting p = mPackages.get(name);
if (p != null) {
- if (p.uid == uid) {
+ if (p.appId == uid) {
return p;
}
PackageManagerService.reportSettingsProblem(Log.ERROR,
@@ -293,7 +293,7 @@ final class Settings {
}
p = new PackageSetting(name, realName, codePath, resourcePath, nativeLibraryPathString,
vc, pkgFlags);
- p.uid = uid;
+ p.appId = uid;
if (addUserIdLPw(uid, p, name)) {
mPackages.put(name, p);
return p;
@@ -407,7 +407,7 @@ final class Settings {
p.copyFrom(origPackage);
p.signatures = s;
p.sharedUser = origPackage.sharedUser;
- p.uid = origPackage.uid;
+ p.appId = origPackage.appId;
p.origPackage = origPackage;
mRenamedPackages.put(name, origPackage.name);
name = origPackage.name;
@@ -435,7 +435,7 @@ final class Settings {
}
}
if (sharedUser != null) {
- p.uid = sharedUser.userId;
+ p.appId = sharedUser.userId;
} else {
// Clone the setting here for disabled system packages
PackageSetting dis = mDisabledSysPackages.get(name);
@@ -447,7 +447,7 @@ final class Settings {
if (dis.signatures.mSignatures != null) {
p.signatures.mSignatures = dis.signatures.mSignatures.clone();
}
- p.uid = dis.uid;
+ p.appId = dis.appId;
// Clone permissions
p.grantedPermissions = new HashSet<String>(dis.grantedPermissions);
// Clone component info
@@ -464,14 +464,14 @@ final class Settings {
}
}
// Add new setting to list of user ids
- addUserIdLPw(p.uid, p, name);
+ addUserIdLPw(p.appId, p, name);
} else {
// Assign new user id
- p.uid = newUserIdLPw(p);
+ p.appId = newUserIdLPw(p);
}
}
}
- if (p.uid < 0) {
+ if (p.appId < 0) {
PackageManagerService.reportSettingsProblem(Log.WARN,
"Package " + name + " could not be assigned a valid uid");
return null;
@@ -539,9 +539,9 @@ final class Settings {
+ p.sharedUser + " but is now " + sharedUser
+ "; I am not changing its files so it will probably fail!");
p.sharedUser.packages.remove(p);
- } else if (p.uid != sharedUser.userId) {
+ } else if (p.appId != sharedUser.userId) {
PackageManagerService.reportSettingsProblem(Log.ERROR,
- "Package " + p.name + " was user id " + p.uid
+ "Package " + p.name + " was user id " + p.appId
+ " but is now user " + sharedUser
+ " with id " + sharedUser.userId
+ "; I am not changing its files so it will probably fail!");
@@ -549,7 +549,7 @@ final class Settings {
sharedUser.packages.add(p);
p.sharedUser = sharedUser;
- p.uid = sharedUser.userId;
+ p.appId = sharedUser.userId;
}
}
@@ -614,8 +614,8 @@ final class Settings {
return p.sharedUser.userId;
}
} else {
- removeUserIdLPw(p.uid);
- return p.uid;
+ removeUserIdLPw(p.appId);
+ return p.appId;
}
}
return -1;
@@ -628,7 +628,7 @@ final class Settings {
p.sharedUser.packages.remove(p);
p.sharedUser.packages.add(newp);
} else {
- replaceUserIdLPw(p.uid, newp);
+ replaceUserIdLPw(p.appId, newp);
}
}
mPackages.put(name, newp);
@@ -1317,9 +1317,9 @@ final class Settings {
serializer.attribute(null, "nativeLibraryPath", pkg.nativeLibraryPathString);
}
if (pkg.sharedUser == null) {
- serializer.attribute(null, "userId", Integer.toString(pkg.uid));
+ serializer.attribute(null, "userId", Integer.toString(pkg.appId));
} else {
- serializer.attribute(null, "sharedUserId", Integer.toString(pkg.uid));
+ serializer.attribute(null, "sharedUserId", Integer.toString(pkg.appId));
}
serializer.startTag(null, "perms");
if (pkg.sharedUser == null) {
@@ -1364,9 +1364,9 @@ final class Settings {
serializer.attribute(null, "ut", Long.toHexString(pkg.lastUpdateTime));
serializer.attribute(null, "version", String.valueOf(pkg.versionCode));
if (pkg.sharedUser == null) {
- serializer.attribute(null, "userId", Integer.toString(pkg.uid));
+ serializer.attribute(null, "userId", Integer.toString(pkg.appId));
} else {
- serializer.attribute(null, "sharedUserId", Integer.toString(pkg.uid));
+ serializer.attribute(null, "sharedUserId", Integer.toString(pkg.appId));
}
if (pkg.uidError) {
serializer.attribute(null, "uidError", "true");
@@ -1607,7 +1607,7 @@ final class Settings {
final Iterator<PackageSetting> disabledIt = mDisabledSysPackages.values().iterator();
while (disabledIt.hasNext()) {
final PackageSetting disabledPs = disabledIt.next();
- final Object id = getUserIdLPr(disabledPs.uid);
+ final Object id = getUserIdLPr(disabledPs.appId);
if (id != null && id instanceof SharedUserSetting) {
disabledPs.sharedUser = (SharedUserSetting) id;
}
@@ -1753,10 +1753,10 @@ final class Settings {
}
}
String idStr = parser.getAttributeValue(null, "userId");
- ps.uid = idStr != null ? Integer.parseInt(idStr) : 0;
- if (ps.uid <= 0) {
+ ps.appId = idStr != null ? Integer.parseInt(idStr) : 0;
+ if (ps.appId <= 0) {
String sharedIdStr = parser.getAttributeValue(null, "sharedUserId");
- ps.uid = sharedIdStr != null ? Integer.parseInt(sharedIdStr) : 0;
+ ps.appId = sharedIdStr != null ? Integer.parseInt(sharedIdStr) : 0;
}
int outerDepth = parser.getDepth();
int type;
@@ -2164,6 +2164,13 @@ final class Settings {
}
}
+ void removeUserLPr(int userId) {
+ File file = getUserPackagesStateFile(userId);
+ file.delete();
+ file = getUserPackagesStateBackupFile(userId);
+ file.delete();
+ }
+
// Returns -1 if we could not find an available UserId to assign
private int newUserIdLPw(Object obj) {
// Let's be stupidly inefficient for now...
@@ -2265,11 +2272,11 @@ final class Settings {
if (pkgSetting == null) {
throw new IllegalArgumentException("Unknown package: " + packageName);
}
- if (!allowedByPermission && (appId != pkgSetting.uid)) {
+ if (!allowedByPermission && (appId != pkgSetting.appId)) {
throw new SecurityException(
"Permission Denial: attempt to change stopped state from pid="
+ Binder.getCallingPid()
- + ", uid=" + uid + ", package uid=" + pkgSetting.uid);
+ + ", uid=" + uid + ", package uid=" + pkgSetting.appId);
}
if (DEBUG_STOPPED) {
if (stopped) {
@@ -2285,7 +2292,7 @@ final class Settings {
if (pkgSetting.installerPackageName != null) {
PackageManagerService.sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_LAUNCH,
pkgSetting.name, null,
- pkgSetting.installerPackageName, null);
+ pkgSetting.installerPackageName, null, userId);
}
pkgSetting.setNotLaunched(false, userId);
}
@@ -2369,7 +2376,7 @@ final class Settings {
pw.println(ps.name);
}
- pw.print(" userId="); pw.print(ps.uid);
+ pw.print(" userId="); pw.print(ps.appId);
pw.print(" gids="); pw.println(PackageManagerService.arrayToString(ps.gids));
pw.print(" sharedUser="); pw.println(ps.sharedUser);
pw.print(" pkg="); pw.println(ps.pkg);
@@ -2513,7 +2520,7 @@ final class Settings {
pw.println(ps.name);
}
pw.print(" userId=");
- pw.println(ps.uid);
+ pw.println(ps.appId);
pw.print(" sharedUser=");
pw.println(ps.sharedUser);
pw.print(" codePath=");
diff --git a/services/java/com/android/server/pm/UserManager.java b/services/java/com/android/server/pm/UserManager.java
index 959e570..4e9e666 100644
--- a/services/java/com/android/server/pm/UserManager.java
+++ b/services/java/com/android/server/pm/UserManager.java
@@ -16,6 +16,7 @@
package com.android.server.pm;
+import com.android.internal.util.ArrayUtils;
import com.android.internal.util.FastXmlSerializer;
import android.content.pm.ApplicationInfo;
@@ -58,7 +59,7 @@ public class UserManager {
private static final String USER_INFO_DIR = "system" + File.separator + "users";
private static final String USER_LIST_FILENAME = "userlist.xml";
- private SparseArray<UserInfo> mUsers;
+ private SparseArray<UserInfo> mUsers = new SparseArray<UserInfo>();
private final File mUsersDir;
private final File mUserListFile;
@@ -91,11 +92,36 @@ public class UserManager {
}
public List<UserInfo> getUsers() {
- ArrayList<UserInfo> users = new ArrayList<UserInfo>(mUsers.size());
- for (int i = 0; i < mUsers.size(); i++) {
- users.add(mUsers.valueAt(i));
+ synchronized (mUsers) {
+ ArrayList<UserInfo> users = new ArrayList<UserInfo>(mUsers.size());
+ for (int i = 0; i < mUsers.size(); i++) {
+ users.add(mUsers.valueAt(i));
+ }
+ return users;
+ }
+ }
+
+ public UserInfo getUser(int userId) {
+ synchronized (mUsers) {
+ UserInfo info = mUsers.get(userId);
+ return info;
+ }
+ }
+
+ public boolean exists(int userId) {
+ synchronized (mUsers) {
+ return ArrayUtils.contains(mUserIds, userId);
+ }
+ }
+
+ public void updateUserName(int userId, String name) {
+ synchronized (mUsers) {
+ UserInfo info = mUsers.get(userId);
+ if (name != null && !name.equals(info.name)) {
+ info.name = name;
+ writeUserLocked(info);
+ }
}
- return users;
}
/**
@@ -108,9 +134,14 @@ public class UserManager {
}
private void readUserList() {
- mUsers = new SparseArray<UserInfo>();
+ synchronized (mUsers) {
+ readUserListLocked();
+ }
+ }
+
+ private void readUserListLocked() {
if (!mUserListFile.exists()) {
- fallbackToSingleUser();
+ fallbackToSingleUserLocked();
return;
}
FileInputStream fis = null;
@@ -126,7 +157,7 @@ public class UserManager {
if (type != XmlPullParser.START_TAG) {
Slog.e(LOG_TAG, "Unable to read user list");
- fallbackToSingleUser();
+ fallbackToSingleUserLocked();
return;
}
@@ -139,11 +170,11 @@ public class UserManager {
}
}
}
- updateUserIds();
+ updateUserIdsLocked();
} catch (IOException ioe) {
- fallbackToSingleUser();
+ fallbackToSingleUserLocked();
} catch (XmlPullParserException pe) {
- fallbackToSingleUser();
+ fallbackToSingleUserLocked();
} finally {
if (fis != null) {
try {
@@ -154,15 +185,15 @@ public class UserManager {
}
}
- private void fallbackToSingleUser() {
+ private void fallbackToSingleUserLocked() {
// Create the primary user
UserInfo primary = new UserInfo(0, "Primary",
UserInfo.FLAG_ADMIN | UserInfo.FLAG_PRIMARY);
mUsers.put(0, primary);
- updateUserIds();
+ updateUserIdsLocked();
- writeUserList();
- writeUser(primary);
+ writeUserListLocked();
+ writeUserLocked(primary);
}
/*
@@ -172,7 +203,7 @@ public class UserManager {
* <name>Primary</name>
* </user>
*/
- private void writeUser(UserInfo userInfo) {
+ private void writeUserLocked(UserInfo userInfo) {
FileOutputStream fos = null;
try {
final File mUserFile = new File(mUsersDir, userInfo.id + ".xml");
@@ -216,7 +247,7 @@ public class UserManager {
* <user id="2"></user>
* </users>
*/
- private void writeUserList() {
+ private void writeUserListLocked() {
FileOutputStream fos = null;
try {
fos = new FileOutputStream(mUserListFile);
@@ -309,17 +340,19 @@ public class UserManager {
return null;
}
- public UserInfo createUser(String name, int flags, List<ApplicationInfo> apps) {
+ public UserInfo createUser(String name, int flags) {
int userId = getNextAvailableId();
UserInfo userInfo = new UserInfo(userId, name, flags);
File userPath = new File(mBaseUserPath, Integer.toString(userId));
- if (!createPackageFolders(userId, userPath, apps)) {
+ if (!createPackageFolders(userId, userPath)) {
return null;
}
- mUsers.put(userId, userInfo);
- writeUserList();
- writeUser(userInfo);
- updateUserIds();
+ synchronized (mUsers) {
+ mUsers.put(userId, userInfo);
+ writeUserListLocked();
+ writeUserLocked(userInfo);
+ updateUserIdsLocked();
+ }
return userInfo;
}
@@ -328,7 +361,13 @@ public class UserManager {
* after the user's processes have been terminated.
* @param id the user's id
*/
- public void removeUser(int id) {
+ public boolean removeUser(int id) {
+ synchronized (mUsers) {
+ return removeUserLocked(id);
+ }
+ }
+
+ private boolean removeUserLocked(int id) {
// Remove from the list
UserInfo userInfo = mUsers.get(id);
if (userInfo != null) {
@@ -338,11 +377,11 @@ public class UserManager {
File userFile = new File(mUsersDir, id + ".xml");
userFile.delete();
// Update the user list
- writeUserList();
- // Remove the data directories for all packages for this user
- removePackageFolders(id);
- updateUserIds();
+ writeUserListLocked();
+ updateUserIdsLocked();
+ return true;
}
+ return false;
}
public void installPackageForAllUsers(String packageName, int uid) {
@@ -376,7 +415,7 @@ public class UserManager {
/**
* Caches the list of user ids in an array, adjusting the array size when necessary.
*/
- private void updateUserIds() {
+ private void updateUserIdsLocked() {
if (mUserIds == null || mUserIds.length != mUsers.size()) {
mUserIds = new int[mUsers.size()];
}
@@ -402,11 +441,10 @@ public class UserManager {
return i;
}
- private boolean createPackageFolders(int id, File userPath, final List<ApplicationInfo> apps) {
+ private boolean createPackageFolders(int id, File userPath) {
// mInstaller may not be available for unit-tests.
- if (mInstaller == null || apps == null) return true;
+ if (mInstaller == null) return true;
- final long startTime = SystemClock.elapsedRealtime();
// Create the user path
userPath.mkdir();
FileUtils.setPermissions(userPath.toString(), FileUtils.S_IRWXU | FileUtils.S_IRWXG
@@ -414,13 +452,10 @@ public class UserManager {
mInstaller.cloneUserData(0, id, false);
- final long stopTime = SystemClock.elapsedRealtime();
- Log.i(LOG_TAG,
- "Time to create " + apps.size() + " packages = " + (stopTime - startTime) + "ms");
return true;
}
- private boolean removePackageFolders(int id) {
+ boolean removePackageFolders(int id) {
// mInstaller may not be available for unit-tests.
if (mInstaller == null) return true;
diff --git a/services/java/com/android/server/wm/AppWindowToken.java b/services/java/com/android/server/wm/AppWindowToken.java
index 1442883..6269420 100644
--- a/services/java/com/android/server/wm/AppWindowToken.java
+++ b/services/java/com/android/server/wm/AppWindowToken.java
@@ -51,7 +51,7 @@ class AppWindowToken extends WindowToken {
int groupId = -1;
boolean appFullscreen;
int requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
-
+
// The input dispatching timeout for this application token in nanoseconds.
long inputDispatchingTimeoutNanos;
@@ -225,7 +225,7 @@ class AppWindowToken extends WindowToken {
if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(WindowManagerService.TAG,
"performing show on: " + w);
w.performShowLocked();
- isAnimating |= w.isAnimating();
+ isAnimating |= w.mWinAnimator.isAnimating();
}
return isAnimating;
}
@@ -243,11 +243,11 @@ class AppWindowToken extends WindowToken {
// cache often used attributes locally
final float tmpFloats[] = service.mTmpFloats;
thumbnailTransformation.getMatrix().getValues(tmpFloats);
- if (WindowManagerService.SHOW_TRANSACTIONS) service.logSurface(thumbnail,
+ if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(thumbnail,
"thumbnail", "POS " + tmpFloats[Matrix.MTRANS_X]
+ ", " + tmpFloats[Matrix.MTRANS_Y], null);
thumbnail.setPosition(tmpFloats[Matrix.MTRANS_X], tmpFloats[Matrix.MTRANS_Y]);
- if (WindowManagerService.SHOW_TRANSACTIONS) service.logSurface(thumbnail,
+ if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(thumbnail,
"thumbnail", "alpha=" + thumbnailTransformation.getAlpha()
+ " layer=" + thumbnailLayer
+ " matrix=[" + tmpFloats[Matrix.MSCALE_X]
@@ -358,7 +358,7 @@ class AppWindowToken extends WindowToken {
final int N = windows.size();
for (int i=0; i<N; i++) {
- windows.get(i).finishExit();
+ windows.get(i).mWinAnimator.finishExit();
}
updateReportedVisibilityLocked();
@@ -388,7 +388,7 @@ class AppWindowToken extends WindowToken {
if (WindowManagerService.DEBUG_VISIBILITY) {
Slog.v(WindowManagerService.TAG, "Win " + win + ": isDrawn="
+ win.isDrawnLw()
- + ", isAnimating=" + win.isAnimating());
+ + ", isAnimating=" + win.mWinAnimator.isAnimating());
if (!win.isDrawnLw()) {
Slog.v(WindowManagerService.TAG, "Not displayed: s=" + win.mSurface
+ " pv=" + win.mPolicyVisibility
@@ -398,17 +398,17 @@ class AppWindowToken extends WindowToken {
+ " th="
+ (win.mAppToken != null
? win.mAppToken.hiddenRequested : false)
- + " a=" + win.mAnimating);
+ + " a=" + win.mWinAnimator.mAnimating);
}
}
numInteresting++;
if (win.isDrawnLw()) {
numDrawn++;
- if (!win.isAnimating()) {
+ if (!win.mWinAnimator.isAnimating()) {
numVisible++;
}
nowGone = false;
- } else if (win.isAnimating()) {
+ } else if (win.mWinAnimator.isAnimating()) {
nowGone = false;
}
}
diff --git a/services/java/com/android/server/wm/DimAnimator.java b/services/java/com/android/server/wm/DimAnimator.java
index 85495ea..d8f2254 100644
--- a/services/java/com/android/server/wm/DimAnimator.java
+++ b/services/java/com/android/server/wm/DimAnimator.java
@@ -82,7 +82,7 @@ class DimAnimator {
/**
* Set's the dim surface's layer and update dim parameters that will be used in
- * {@link updateSurface} after all windows are examined.
+ * {@link #updateSurface} after all windows are examined.
*/
void updateParameters(Resources res, WindowState w, long currentTime) {
mDimSurface.setLayer(w.mAnimLayer - WindowManagerService.LAYER_OFFSET_DIM);
@@ -94,15 +94,15 @@ class DimAnimator {
// If the desired dim level has changed, then
// start an animation to it.
mLastDimAnimTime = currentTime;
- long duration = (w.mAnimating && w.mAnimation != null)
- ? w.mAnimation.computeDurationHint()
+ long duration = (w.mWinAnimator.mAnimating && w.mWinAnimator.mAnimation != null)
+ ? w.mWinAnimator.mAnimation.computeDurationHint()
: WindowManagerService.DEFAULT_DIM_DURATION;
if (target > mDimTargetAlpha) {
TypedValue tv = new TypedValue();
res.getValue(com.android.internal.R.fraction.config_dimBehindFadeDuration,
tv, true);
if (tv.type == TypedValue.TYPE_FRACTION) {
- duration = (long)tv.getFraction((float)duration, (float)duration);
+ duration = (long)tv.getFraction(duration, duration);
} else if (tv.type >= TypedValue.TYPE_FIRST_INT
&& tv.type <= TypedValue.TYPE_LAST_INT) {
duration = tv.data;
diff --git a/services/java/com/android/server/wm/WindowAnimator.java b/services/java/com/android/server/wm/WindowAnimator.java
index fbfd9ec..81e0a17 100644
--- a/services/java/com/android/server/wm/WindowAnimator.java
+++ b/services/java/com/android/server/wm/WindowAnimator.java
@@ -79,7 +79,7 @@ public class WindowAnimator {
}
}
}
-
+
final int NEAT = mService.mExitingAppTokens.size();
for (i=0; i<NEAT; i++) {
final AppWindowToken appToken = mService.mExitingAppTokens.get(i);
@@ -115,6 +115,7 @@ public class WindowAnimator {
for (int i = mService.mWindows.size() - 1; i >= 0; i--) {
WindowState w = mService.mWindows.get(i);
+ WindowStateAnimator winAnimator = w.mWinAnimator;
final WindowManager.LayoutParams attrs = w.mAttrs;
@@ -143,7 +144,7 @@ public class WindowAnimator {
// let's do something.
Animation a = AnimationUtils.loadAnimation(mContext,
com.android.internal.R.anim.window_move_from_decor);
- w.setAnimation(a);
+ winAnimator.setAnimation(a);
w.mAnimDw = w.mLastFrame.left - w.mFrame.left;
w.mAnimDh = w.mLastFrame.top - w.mFrame.top;
} else {
@@ -151,8 +152,8 @@ public class WindowAnimator {
w.mAnimDh = mInnerDh;
}
- final boolean wasAnimating = w.mWasAnimating;
- final boolean nowAnimating = w.stepAnimationLocked(mCurrentTime);
+ final boolean wasAnimating = winAnimator.mWasAnimating;
+ final boolean nowAnimating = winAnimator.stepAnimationLocked(mCurrentTime);
if (WindowManagerService.DEBUG_WALLPAPER) {
Slog.v(TAG, w + ": wasAnimating=" + wasAnimating +
@@ -163,17 +164,17 @@ public class WindowAnimator {
// an animating window and take care of a request to run
// a detached wallpaper animation.
if (nowAnimating) {
- if (w.mAnimation != null) {
+ if (winAnimator.mAnimation != null) {
if ((w.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0
- && w.mAnimation.getDetachWallpaper()) {
+ && winAnimator.mAnimation.getDetachWallpaper()) {
mService.mInnerFields.mDetachedWallpaper = w;
}
- if (w.mAnimation.getBackgroundColor() != 0) {
+ if (winAnimator.mAnimation.getBackgroundColor() != 0) {
if (mWindowAnimationBackground == null
|| (w.mAnimLayer < mWindowAnimationBackground.mAnimLayer)) {
mWindowAnimationBackground = w;
mWindowAnimationBackgroundColor =
- w.mAnimation.getBackgroundColor();
+ winAnimator.mAnimation.getBackgroundColor();
}
}
}
@@ -200,7 +201,7 @@ public class WindowAnimator {
}
}
- if (wasAnimating && !w.mAnimating && mService.mWallpaperTarget == w) {
+ if (wasAnimating && !winAnimator.mAnimating && mService.mWallpaperTarget == w) {
mService.mInnerFields.mWallpaperMayChange = true;
mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
@@ -219,7 +220,7 @@ public class WindowAnimator {
mService.debugLayoutRepeats("updateWindowsAndWallpaperLocked 3");
}
mService.mFocusMayChange = true;
- } else if (w.isReadyForDisplay() && w.mAnimation == null) {
+ } else if (w.isReadyForDisplay() && winAnimator.mAnimation == null) {
mForceHiding = true;
}
} else if (mPolicy.canBeForceHidden(w, attrs)) {
@@ -241,7 +242,7 @@ public class WindowAnimator {
// clean up later.
Animation a = mPolicy.createForceHideEnterAnimation();
if (a != null) {
- w.setAnimation(a);
+ winAnimator.setAnimation(a);
}
}
if (mCurrentFocus == null || mCurrentFocus.mLayer < w.mLayer) {
@@ -277,7 +278,7 @@ public class WindowAnimator {
WindowManagerService.DEBUG_ORIENTATION) {
Slog.v(TAG, "Eval win " + w + ": isDrawn="
+ w.isDrawnLw()
- + ", isAnimating=" + w.isAnimating());
+ + ", isAnimating=" + winAnimator.isAnimating());
if (!w.isDrawnLw()) {
Slog.v(TAG, "Not displayed: s=" + w.mSurface
+ " pv=" + w.mPolicyVisibility
@@ -285,7 +286,7 @@ public class WindowAnimator {
+ " cdp=" + w.mCommitDrawPending
+ " ah=" + w.mAttachedHidden
+ " th=" + atoken.hiddenRequested
- + " a=" + w.mAnimating);
+ + " a=" + winAnimator.mAnimating);
}
}
if (w != atoken.startingWindow) {
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 3ecbf77..9635b33 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -89,6 +89,7 @@ import android.os.TokenWatcher;
import android.provider.Settings;
import android.util.DisplayMetrics;
import android.util.EventLog;
+import android.util.FloatMath;
import android.util.Log;
import android.util.Pair;
import android.util.Slog;
@@ -1237,7 +1238,7 @@ public class WindowManagerService extends IWindowManager.Stub
if (highestTarget != null) {
if (DEBUG_INPUT_METHOD) Slog.v(TAG, "mNextAppTransition="
+ mNextAppTransition + " " + highestTarget
- + " animating=" + highestTarget.isAnimating()
+ + " animating=" + highestTarget.mWinAnimator.isAnimating()
+ " layer=" + highestTarget.mAnimLayer
+ " new layer=" + w.mAnimLayer);
@@ -1247,7 +1248,7 @@ public class WindowManagerService extends IWindowManager.Stub
mInputMethodTargetWaitingAnim = true;
mInputMethodTarget = highestTarget;
return highestPos + 1;
- } else if (highestTarget.isAnimating() &&
+ } else if (highestTarget.mWinAnimator.isAnimating() &&
highestTarget.mAnimLayer > w.mAnimLayer) {
// If the window we are currently targeting is involved
// with an animation, and it is on top of the next target
@@ -1600,7 +1601,7 @@ public class WindowManagerService extends IWindowManager.Stub
foundI = i;
if (w == mWallpaperTarget && ((w.mAppToken != null
&& w.mAppToken.animation != null)
- || w.mAnimation != null)) {
+ || w.mWinAnimator.mAnimation != null)) {
// The current wallpaper target is animating, so we'll
// look behind it for another possible target and figure
// out what is going on below.
@@ -1657,9 +1658,9 @@ public class WindowManagerService extends IWindowManager.Stub
// Now what is happening... if the current and new targets are
// animating, then we are in our super special mode!
if (foundW != null && oldW != null) {
- boolean oldAnim = oldW.mAnimation != null
+ boolean oldAnim = oldW.mWinAnimator.mAnimation != null
|| (oldW.mAppToken != null && oldW.mAppToken.animation != null);
- boolean foundAnim = foundW.mAnimation != null
+ boolean foundAnim = foundW.mWinAnimator.mAnimation != null
|| (foundW.mAppToken != null && foundW.mAppToken.animation != null);
if (DEBUG_WALLPAPER) {
Slog.v(TAG, "New animation: " + foundAnim
@@ -1711,10 +1712,10 @@ public class WindowManagerService extends IWindowManager.Stub
} else if (mLowerWallpaperTarget != null) {
// Is it time to stop animating?
- boolean lowerAnimating = mLowerWallpaperTarget.mAnimation != null
+ boolean lowerAnimating = mLowerWallpaperTarget.mWinAnimator.mAnimation != null
|| (mLowerWallpaperTarget.mAppToken != null
&& mLowerWallpaperTarget.mAppToken.animation != null);
- boolean upperAnimating = mUpperWallpaperTarget.mAnimation != null
+ boolean upperAnimating = mUpperWallpaperTarget.mWinAnimator.mAnimation != null
|| (mUpperWallpaperTarget.mAppToken != null
&& mUpperWallpaperTarget.mAppToken.animation != null);
if (!lowerAnimating || !upperAnimating) {
@@ -2302,7 +2303,7 @@ public class WindowManagerService extends IWindowManager.Stub
if (DEBUG_APP_TRANSITIONS) Slog.v(
TAG, "Remove " + win + ": mSurface=" + win.mSurface
+ " mExiting=" + win.mExiting
- + " isAnimating=" + win.isAnimating()
+ + " isAnimating=" + win.mWinAnimator.isAnimating()
+ " app-animation="
+ (win.mAppToken != null ? win.mAppToken.animation : null)
+ " inPendingTransaction="
@@ -2329,7 +2330,7 @@ public class WindowManagerService extends IWindowManager.Stub
win.mExiting = true;
}
}
- if (win.mExiting || win.isAnimating()) {
+ if (win.mExiting || win.mWinAnimator.isAnimating()) {
// The exit animation is running... wait for it!
//Slog.i(TAG, "*** Running exit animation...");
win.mExiting = true;
@@ -2698,7 +2699,7 @@ public class WindowManagerService extends IWindowManager.Stub
(win.mAppToken == null || !win.mAppToken.clientHidden)) {
displayed = !win.isVisibleLw();
if (win.mExiting) {
- win.cancelExitAnimationForNextAnimationLocked();
+ win.mWinAnimator.cancelExitAnimationForNextAnimationLocked();
}
if (win.mDestroying) {
win.mDestroying = false;
@@ -2802,7 +2803,7 @@ public class WindowManagerService extends IWindowManager.Stub
applyAnimationLocked(win, transit, false)) {
focusMayChange = true;
win.mExiting = true;
- } else if (win.isAnimating()) {
+ } else if (win.mWinAnimator.isAnimating()) {
// Currently in a hide animation... turn this into
// an exit.
win.mExiting = true;
@@ -2811,7 +2812,7 @@ public class WindowManagerService extends IWindowManager.Stub
// window, we need to change both of them inside
// of a transaction to avoid artifacts.
win.mExiting = true;
- win.mAnimating = true;
+ win.mWinAnimator.mAnimating = true;
} else {
if (mInputMethodWindow == win) {
mInputMethodWindow = null;
@@ -3025,7 +3026,8 @@ public class WindowManagerService extends IWindowManager.Stub
*/
boolean applyAnimationLocked(WindowState win,
int transit, boolean isEntrance) {
- if (win.mLocalAnimating && win.mAnimationIsEntrance == isEntrance) {
+ if (win.mWinAnimator.mLocalAnimating &&
+ win.mWinAnimator.mAnimationIsEntrance == isEntrance) {
// If we are trying to apply an animation, but already running
// an animation of the same type, then just leave that one alone.
return true;
@@ -3062,7 +3064,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
if (DEBUG_ANIM) Slog.v(TAG, "applyAnimation: win=" + win
+ " anim=" + anim + " attr=0x" + Integer.toHexString(attr)
- + " mAnimation=" + win.mAnimation
+ + " mAnimation=" + win.mWinAnimator.mAnimation
+ " isEntrance=" + isEntrance);
if (a != null) {
if (DEBUG_ANIM) {
@@ -3073,14 +3075,14 @@ public class WindowManagerService extends IWindowManager.Stub
}
Slog.v(TAG, "Loaded animation " + a + " for " + win, e);
}
- win.setAnimation(a);
- win.mAnimationIsEntrance = isEntrance;
+ win.mWinAnimator.setAnimation(a);
+ win.mWinAnimator.mAnimationIsEntrance = isEntrance;
}
} else {
- win.clearAnimation();
+ win.mWinAnimator.clearAnimation();
}
- return win.mAnimation != null;
+ return win.mWinAnimator.mAnimation != null;
}
private Animation loadAnimation(WindowManager.LayoutParams lp, int animAttr) {
@@ -3369,7 +3371,7 @@ public class WindowManagerService extends IWindowManager.Stub
for (int i=0; i<N; i++) {
WindowState win = wtoken.windows.get(i);
- if (win.isAnimating()) {
+ if (win.mWinAnimator.isAnimating()) {
delayed = true;
}
@@ -4062,7 +4064,7 @@ public class WindowManagerService extends IWindowManager.Stub
continue;
}
- if (win.isAnimating()) {
+ if (win.mWinAnimator.isAnimating()) {
delayed = true;
}
@@ -5261,8 +5263,8 @@ public class WindowManagerService extends IWindowManager.Stub
synchronized(mWindowMap) {
long ident = Binder.clearCallingIdentity();
- dw = mAppDisplayWidth;
- dh = mAppDisplayHeight;
+ dw = mCurDisplayWidth;
+ dh = mCurDisplayHeight;
int aboveAppLayer = mPolicy.windowTypeToLayerLw(
WindowManager.LayoutParams.TYPE_APPLICATION) * TYPE_LAYER_MULTIPLIER
@@ -5382,7 +5384,7 @@ public class WindowManagerService extends IWindowManager.Stub
Bitmap bm = Bitmap.createBitmap(width, height, rawss.getConfig());
Matrix matrix = new Matrix();
ScreenRotationAnimation.createRotationMatrix(rot, dw, dh, matrix);
- matrix.postTranslate(-(int)(frame.left*scale), -(int)(frame.top*scale));
+ matrix.postTranslate(-FloatMath.ceil(frame.left*scale), -FloatMath.ceil(frame.top*scale));
Canvas canvas = new Canvas(bm);
canvas.drawBitmap(rawss, matrix, null);
canvas.setBitmap(null);
@@ -8098,11 +8100,11 @@ public class WindowManagerService extends IWindowManager.Stub
if (DEBUG_FOCUS) Slog.i(TAG, "win=" + w + " force hides other windows");
mAnimator.mForceHiding = true;
} else if (mPolicy.canBeForceHidden(w, attrs)) {
- if (!w.mAnimating) {
+ if (!w.mWinAnimator.mAnimating) {
// We set the animation above so it
// is not yet running.
// TODO(cmautner): We lose the enter animation when this occurs.
- w.clearAnimation();
+ w.mWinAnimator.clearAnimation();
}
}
}
@@ -9769,7 +9771,7 @@ public class WindowManagerService extends IWindowManager.Stub
public interface OnHardKeyboardStatusChangeListener {
public void onHardKeyboardStatusChange(boolean available, boolean enabled);
}
-
+
void debugLayoutRepeats(final String msg) {
if (mLayoutRepeatCount >= LAYOUT_REPEAT_THRESHOLD) {
Slog.v(TAG, "Layouts looping: " + msg);
diff --git a/services/java/com/android/server/wm/WindowState.java b/services/java/com/android/server/wm/WindowState.java
index 1146189..615cd80 100644
--- a/services/java/com/android/server/wm/WindowState.java
+++ b/services/java/com/android/server/wm/WindowState.java
@@ -45,7 +45,6 @@ import android.view.ViewTreeObserver;
import android.view.WindowManager;
import android.view.WindowManagerPolicy;
import android.view.WindowManager.LayoutParams;
-import android.view.animation.Animation;
import android.view.animation.Transformation;
import java.io.PrintWriter;
@@ -91,7 +90,6 @@ final class WindowState implements WindowManagerPolicy.WindowState {
boolean mAttachedHidden; // is our parent window hidden?
boolean mLastHidden; // was this window last hidden?
boolean mWallpaperVisible; // for wallpaper, what was last vis report?
- boolean mWasAnimating; // Were we animating going into the most recent animation step?
/**
* The window size that was requested by the application. These are in
@@ -110,9 +108,9 @@ final class WindowState implements WindowManagerPolicy.WindowState {
boolean mTurnOnScreen;
int mLayoutSeq = -1;
-
+
Configuration mConfiguration = null;
-
+
/**
* Actual frame shown on-screen (may be modified by animation). These
* are in the screen's coordinate space (WITH the compatibility scale
@@ -212,15 +210,6 @@ final class WindowState implements WindowManagerPolicy.WindowState {
// an enter animation.
boolean mEnterAnimationPending;
- // Currently running animation.
- boolean mAnimating;
- boolean mLocalAnimating;
- Animation mAnimation;
- boolean mAnimationIsEntrance;
- boolean mHasTransformation;
- boolean mHasLocalTransformation;
- final Transformation mTransformation = new Transformation();
-
// If a window showing a wallpaper: the requested offset for the
// wallpaper; if a wallpaper window: the currently applied offset.
float mWallpaperX = -1;
@@ -305,6 +294,8 @@ final class WindowState implements WindowManagerPolicy.WindowState {
int mAnimDw;
int mAnimDh;
+ final WindowStateAnimator mWinAnimator;
+
WindowState(WindowManagerService service, Session s, IWindow c, WindowToken token,
WindowState attachedWindow, int seq, WindowManager.LayoutParams a,
int viewVisibility) {
@@ -333,6 +324,7 @@ final class WindowState implements WindowManagerPolicy.WindowState {
mBaseLayer = 0;
mSubLayer = 0;
mInputWindowHandle = null;
+ mWinAnimator = null;
return;
}
mDeathRecipient = deathRecipient;
@@ -369,9 +361,11 @@ final class WindowState implements WindowManagerPolicy.WindowState {
mIsFloatingLayer = mIsImWindow || mIsWallpaper;
}
+ mWinAnimator = new WindowStateAnimator(service, this, mAttachedWindow);
+
WindowState appWin = this;
while (appWin.mAttachedWindow != null) {
- appWin = mAttachedWindow;
+ appWin = appWin.mAttachedWindow;
}
WindowToken appToken = appWin.mToken;
while (appToken.appWindowToken == null) {
@@ -405,6 +399,7 @@ final class WindowState implements WindowManagerPolicy.WindowState {
mSession.windowAddedLocked();
}
+ @Override
public void computeFrameLw(Rect pf, Rect df, Rect cf, Rect vf) {
mHaveFrame = true;
@@ -547,38 +542,47 @@ final class WindowState implements WindowManagerPolicy.WindowState {
}
}
+ @Override
public Rect getFrameLw() {
return mFrame;
}
+ @Override
public RectF getShownFrameLw() {
return mShownFrame;
}
+ @Override
public Rect getDisplayFrameLw() {
return mDisplayFrame;
}
+ @Override
public Rect getContentFrameLw() {
return mContentFrame;
}
+ @Override
public Rect getVisibleFrameLw() {
return mVisibleFrame;
}
+ @Override
public boolean getGivenInsetsPendingLw() {
return mGivenInsetsPending;
}
+ @Override
public Rect getGivenContentInsetsLw() {
return mGivenContentInsets;
}
+ @Override
public Rect getGivenVisibleInsetsLw() {
return mGivenVisibleInsets;
}
+ @Override
public WindowManager.LayoutParams getAttrs() {
return mAttrs;
}
@@ -632,41 +636,6 @@ final class WindowState implements WindowManagerPolicy.WindowState {
return mAppToken != null ? mAppToken.firstWindowDrawn : false;
}
- public void setAnimation(Animation anim) {
- if (WindowManagerService.localLOGV) Slog.v(
- WindowManagerService.TAG, "Setting animation in " + this + ": " + anim);
- mAnimating = false;
- mLocalAnimating = false;
- mAnimation = anim;
- mAnimation.restrictDuration(WindowManagerService.MAX_ANIMATION_DURATION);
- mAnimation.scaleCurrentDuration(mService.mWindowAnimationScale);
- // Start out animation gone if window is gone, or visible if window is visible.
- mTransformation.clear();
- mTransformation.setAlpha(mLastHidden ? 0 : 1);
- mHasLocalTransformation = true;
- }
-
- public void clearAnimation() {
- if (mAnimation != null) {
- mAnimating = true;
- mLocalAnimating = false;
- mAnimation.cancel();
- mAnimation = null;
- }
- }
-
- // TODO: Fix and call finishExit() instead of cancelExitAnimationForNextAnimationLocked()
- // for avoiding the code duplication.
- void cancelExitAnimationForNextAnimationLocked() {
- if (!mExiting) return;
- if (mAnimation != null) {
- mAnimation.cancel();
- mAnimation = null;
- destroySurfaceLocked();
- }
- mExiting = false;
- }
-
Surface createSurfaceLocked() {
if (mSurface == null) {
mReportDestroySurface = false;
@@ -931,7 +900,7 @@ final class WindowState implements WindowManagerPolicy.WindowState {
+ (mAppToken != null ? mAppToken.hiddenRequested : false)
+ " tok.hidden="
+ (mAppToken != null ? mAppToken.hidden : false)
- + " animating=" + mAnimating
+ + " animating=" + mWinAnimator.mAnimating
+ " tok animating="
+ (mAppToken != null ? mAppToken.animating : false));
if (!mService.showSurfaceRobustlyLocked(this)) {
@@ -978,11 +947,11 @@ final class WindowState implements WindowManagerPolicy.WindowState {
// will do an animation to reveal it from behind the
// starting window, so there is no need for it to also
// be doing its own stuff.
- if (mAnimation != null) {
- mAnimation.cancel();
- mAnimation = null;
+ if (mWinAnimator.mAnimation != null) {
+ mWinAnimator.mAnimation.cancel();
+ mWinAnimator.mAnimation = null;
// Make sure we clean up the animation.
- mAnimating = true;
+ mWinAnimator.mAnimating = true;
}
mService.mFinishedStarting.add(mAppToken);
mService.mH.sendEmptyMessage(H.FINISHED_STARTING);
@@ -995,192 +964,6 @@ final class WindowState implements WindowManagerPolicy.WindowState {
return true;
}
- private boolean stepAnimation(long currentTime) {
- if ((mAnimation == null) || !mLocalAnimating) {
- return false;
- }
- mTransformation.clear();
- final boolean more = mAnimation.getTransformation(currentTime, mTransformation);
- if (WindowManagerService.DEBUG_ANIM) Slog.v(
- WindowManagerService.TAG, "Stepped animation in " + this +
- ": more=" + more + ", xform=" + mTransformation);
- return more;
- }
-
- // This must be called while inside a transaction. Returns true if
- // there is more animation to run.
- boolean stepAnimationLocked(long currentTime) {
- // Save the animation state as it was before this step so WindowManagerService can tell if
- // we just started or just stopped animating by comparing mWasAnimating with isAnimating().
- mWasAnimating = mAnimating;
- if (mService.okToDisplay()) {
- // We will run animations as long as the display isn't frozen.
-
- if (isDrawnLw() && mAnimation != null) {
- mHasTransformation = true;
- mHasLocalTransformation = true;
- if (!mLocalAnimating) {
- if (WindowManagerService.DEBUG_ANIM) Slog.v(
- WindowManagerService.TAG, "Starting animation in " + this +
- " @ " + currentTime + ": ww=" + mFrame.width() +
- " wh=" + mFrame.height() +
- " dw=" + mAnimDw + " dh=" + mAnimDh +
- " scale=" + mService.mWindowAnimationScale);
- mAnimation.initialize(mFrame.width(), mFrame.height(), mAnimDw, mAnimDh);
- mAnimation.setStartTime(currentTime);
- mLocalAnimating = true;
- mAnimating = true;
- }
- if ((mAnimation != null) && mLocalAnimating) {
- if (stepAnimation(currentTime)) {
- return true;
- }
- }
- if (WindowManagerService.DEBUG_ANIM) Slog.v(
- WindowManagerService.TAG, "Finished animation in " + this +
- " @ " + currentTime);
- //WindowManagerService.this.dump();
- }
- mHasLocalTransformation = false;
- if ((!mLocalAnimating || mAnimationIsEntrance) && mAppToken != null
- && mAppToken.animation != null) {
- // When our app token is animating, we kind-of pretend like
- // we are as well. Note the mLocalAnimating mAnimationIsEntrance
- // part of this check means that we will only do this if
- // our window is not currently exiting, or it is not
- // locally animating itself. The idea being that one that
- // is exiting and doing a local animation should be removed
- // once that animation is done.
- mAnimating = true;
- mHasTransformation = true;
- mTransformation.clear();
- return false;
- } else if (mHasTransformation) {
- // Little trick to get through the path below to act like
- // we have finished an animation.
- mAnimating = true;
- } else if (isAnimating()) {
- mAnimating = true;
- }
- } else if (mAnimation != null) {
- // If the display is frozen, and there is a pending animation,
- // clear it and make sure we run the cleanup code.
- mAnimating = true;
- mLocalAnimating = true;
- mAnimation.cancel();
- mAnimation = null;
- }
-
- if (!mAnimating && !mLocalAnimating) {
- return false;
- }
-
- if (WindowManagerService.DEBUG_ANIM) Slog.v(
- WindowManagerService.TAG, "Animation done in " + this + ": exiting=" + mExiting
- + ", reportedVisible="
- + (mAppToken != null ? mAppToken.reportedVisible : false));
-
- mAnimating = false;
- mLocalAnimating = false;
- if (mAnimation != null) {
- mAnimation.cancel();
- mAnimation = null;
- }
- if (mService.mWindowDetachedWallpaper == this) {
- mService.mWindowDetachedWallpaper = null;
- }
- mAnimLayer = mLayer;
- if (mIsImWindow) {
- mAnimLayer += mService.mInputMethodAnimLayerAdjustment;
- } else if (mIsWallpaper) {
- mAnimLayer += mService.mWallpaperAnimLayerAdjustment;
- }
- if (WindowManagerService.DEBUG_LAYERS) Slog.v(WindowManagerService.TAG, "Stepping win " + this
- + " anim layer: " + mAnimLayer);
- mHasTransformation = false;
- mHasLocalTransformation = false;
- if (mPolicyVisibility != mPolicyVisibilityAfterAnim) {
- if (DEBUG_VISIBILITY) {
- Slog.v(WindowManagerService.TAG, "Policy visibility changing after anim in " + this + ": "
- + mPolicyVisibilityAfterAnim);
- }
- mPolicyVisibility = mPolicyVisibilityAfterAnim;
- mService.mLayoutNeeded = true;
- if (!mPolicyVisibility) {
- if (mService.mCurrentFocus == this) {
- mService.mFocusMayChange = true;
- }
- // Window is no longer visible -- make sure if we were waiting
- // for it to be displayed before enabling the display, that
- // we allow the display to be enabled now.
- mService.enableScreenIfNeededLocked();
- }
- }
- mTransformation.clear();
- if (mHasDrawn
- && mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING
- && mAppToken != null
- && mAppToken.firstWindowDrawn
- && mAppToken.startingData != null) {
- if (WindowManagerService.DEBUG_STARTING_WINDOW) Slog.v(WindowManagerService.TAG, "Finish starting "
- + mToken + ": first real window done animating");
- mService.mFinishedStarting.add(mAppToken);
- mService.mH.sendEmptyMessage(H.FINISHED_STARTING);
- }
-
- finishExit();
- mService.mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
- if (WindowManagerService.DEBUG_LAYOUT_REPEATS) mService.debugLayoutRepeats("WindowState");
-
- if (mAppToken != null) {
- mAppToken.updateReportedVisibilityLocked();
- }
-
- return false;
- }
-
- void finishExit() {
- if (WindowManagerService.DEBUG_ANIM) Slog.v(
- WindowManagerService.TAG, "finishExit in " + this
- + ": exiting=" + mExiting
- + " remove=" + mRemoveOnExit
- + " windowAnimating=" + isWindowAnimating());
-
- final int N = mChildWindows.size();
- for (int i=0; i<N; i++) {
- mChildWindows.get(i).finishExit();
- }
-
- if (!mExiting) {
- return;
- }
-
- if (isWindowAnimating()) {
- return;
- }
-
- if (WindowManagerService.localLOGV) Slog.v(
- WindowManagerService.TAG, "Exit animation finished in " + this
- + ": remove=" + mRemoveOnExit);
- if (mSurface != null) {
- mService.mDestroySurface.add(this);
- mDestroying = true;
- if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(this, "HIDE (finishExit)", null);
- mSurfaceShown = false;
- try {
- mSurface.hide();
- } catch (RuntimeException e) {
- Slog.w(WindowManagerService.TAG, "Error hiding surface in " + this, e);
- }
- mLastHidden = true;
- }
- mExiting = false;
- if (mRemoveOnExit) {
- mService.mPendingRemove.add(this);
- mRemoveOnExit = false;
- }
- }
-
boolean isIdentityMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
if (dsdx < .99999f || dsdx > 1.00001f) return false;
if (dtdy < .99999f || dtdy > 1.00001f) return false;
@@ -1199,10 +982,10 @@ final class WindowState implements WindowManagerPolicy.WindowState {
}
void computeShownFrameLocked() {
- final boolean selfTransformation = mHasLocalTransformation;
+ final boolean selfTransformation = mWinAnimator.mHasLocalTransformation;
Transformation attachedTransformation =
- (mAttachedWindow != null && mAttachedWindow.mHasLocalTransformation)
- ? mAttachedWindow.mTransformation : null;
+ (mAttachedWindow != null && mAttachedWindow.mWinAnimator.mHasLocalTransformation)
+ ? mAttachedWindow.mWinAnimator.mTransformation : null;
Transformation appTransformation =
(mAppToken != null && mAppToken.hasTransformation)
? mAppToken.transformation : null;
@@ -1211,10 +994,10 @@ final class WindowState implements WindowManagerPolicy.WindowState {
// are currently targeting.
if (mAttrs.type == TYPE_WALLPAPER && mService.mLowerWallpaperTarget == null
&& mService.mWallpaperTarget != null) {
- if (mService.mWallpaperTarget.mHasLocalTransformation &&
- mService.mWallpaperTarget.mAnimation != null &&
- !mService.mWallpaperTarget.mAnimation.getDetachWallpaper()) {
- attachedTransformation = mService.mWallpaperTarget.mTransformation;
+ if (mService.mWallpaperTarget.mWinAnimator.mHasLocalTransformation &&
+ mService.mWallpaperTarget.mWinAnimator.mAnimation != null &&
+ !mService.mWallpaperTarget.mWinAnimator.mAnimation.getDetachWallpaper()) {
+ attachedTransformation = mService.mWallpaperTarget.mWinAnimator.mTransformation;
if (WindowManagerService.DEBUG_WALLPAPER && attachedTransformation != null) {
Slog.v(WindowManagerService.TAG, "WP target attached xform: " + attachedTransformation);
}
@@ -1260,7 +1043,7 @@ final class WindowState implements WindowManagerPolicy.WindowState {
}
tmpMatrix.postScale(mGlobalScale, mGlobalScale);
if (selfTransformation) {
- tmpMatrix.postConcat(mTransformation.getMatrix());
+ tmpMatrix.postConcat(mWinAnimator.mTransformation.getMatrix());
}
tmpMatrix.postTranslate(frame.left + mXOffset, frame.top + mYOffset);
if (attachedTransformation != null) {
@@ -1304,7 +1087,7 @@ final class WindowState implements WindowManagerPolicy.WindowState {
&& x == frame.left && y == frame.top))) {
//Slog.i(TAG, "Applying alpha transform");
if (selfTransformation) {
- mShownAlpha *= mTransformation.getAlpha();
+ mShownAlpha *= mWinAnimator.mTransformation.getAlpha();
}
if (attachedTransformation != null) {
mShownAlpha *= attachedTransformation.getAlpha();
@@ -1323,7 +1106,7 @@ final class WindowState implements WindowManagerPolicy.WindowState {
if (WindowManagerService.localLOGV) Slog.v(
WindowManagerService.TAG, "computeShownFrameLocked: Animating " + this +
": " + mShownFrame +
- ", alpha=" + mTransformation.getAlpha() + ", mShownAlpha=" + mShownAlpha);
+ ", alpha=" + mWinAnimator.mTransformation.getAlpha() + ", mShownAlpha=" + mShownAlpha);
return;
}
@@ -1374,7 +1157,7 @@ final class WindowState implements WindowManagerPolicy.WindowState {
&& (atoken == null ? mPolicyVisibility : !atoken.hiddenRequested)
&& ((!mAttachedHidden && mViewVisibility == View.VISIBLE
&& !mRootToken.hidden)
- || mAnimation != null || animating);
+ || mWinAnimator.mAnimation != null || animating);
}
/**
@@ -1431,10 +1214,10 @@ final class WindowState implements WindowManagerPolicy.WindowState {
if (atoken != null) {
return mSurface != null && mPolicyVisibility && !mDestroying
&& ((!mAttachedHidden && !atoken.hiddenRequested)
- || mAnimation != null || atoken.animation != null);
+ || mWinAnimator.mAnimation != null || atoken.animation != null);
} else {
return mSurface != null && mPolicyVisibility && !mDestroying
- && (!mAttachedHidden || mAnimation != null);
+ && (!mAttachedHidden || mWinAnimator.mAnimation != null);
}
}
@@ -1450,26 +1233,10 @@ final class WindowState implements WindowManagerPolicy.WindowState {
return mSurface != null && mPolicyVisibility && !mDestroying
&& ((!mAttachedHidden && mViewVisibility == View.VISIBLE
&& !mRootToken.hidden)
- || mAnimation != null
+ || mWinAnimator.mAnimation != null
|| ((mAppToken != null) && (mAppToken.animation != null)));
}
- /** Is the window or its container currently animating? */
- boolean isAnimating() {
- final WindowState attached = mAttachedWindow;
- final AppWindowToken atoken = mAppToken;
- return mAnimation != null
- || (attached != null && attached.mAnimation != null)
- || (atoken != null &&
- (atoken.animation != null
- || atoken.inPendingTransaction));
- }
-
- /** Is this window currently animating? */
- boolean isWindowAnimating() {
- return mAnimation != null;
- }
-
/**
* Like isOnScreen, but returns false if the surface hasn't yet
* been drawn.
@@ -1479,7 +1246,7 @@ final class WindowState implements WindowManagerPolicy.WindowState {
return isDrawnLw() && mPolicyVisibility
&& ((!mAttachedHidden &&
(atoken == null || !atoken.hiddenRequested))
- || mAnimating);
+ || mWinAnimator.mAnimating);
}
public boolean isGoneForLayoutLw() {
@@ -1508,7 +1275,7 @@ final class WindowState implements WindowManagerPolicy.WindowState {
boolean isOpaqueDrawn() {
return (mAttrs.format == PixelFormat.OPAQUE
|| mAttrs.type == TYPE_WALLPAPER)
- && isDrawnLw() && mAnimation == null
+ && isDrawnLw() && mWinAnimator.mAnimation == null
&& (mAppToken == null || mAppToken.animation == null);
}
@@ -1607,10 +1374,10 @@ final class WindowState implements WindowManagerPolicy.WindowState {
if (DEBUG_VISIBILITY) Slog.v(WindowManagerService.TAG, "Policy visibility true: " + this);
if (doAnimation) {
if (DEBUG_VISIBILITY) Slog.v(WindowManagerService.TAG, "doAnimation: mPolicyVisibility="
- + mPolicyVisibility + " mAnimation=" + mAnimation);
+ + mPolicyVisibility + " mAnimation=" + mWinAnimator.mAnimation);
if (!mService.okToDisplay()) {
doAnimation = false;
- } else if (mPolicyVisibility && mAnimation == null) {
+ } else if (mPolicyVisibility && mWinAnimator.mAnimation == null) {
// Check for the case where we are currently visible and
// not animating; we do not want to do animation at such a
// point to become visible when we already are.
@@ -1646,7 +1413,7 @@ final class WindowState implements WindowManagerPolicy.WindowState {
}
if (doAnimation) {
mService.applyAnimationLocked(this, WindowManagerPolicy.TRANSIT_EXIT, false);
- if (mAnimation == null) {
+ if (mWinAnimator.mAnimation == null) {
doAnimation = false;
}
}
@@ -1821,20 +1588,7 @@ final class WindowState implements WindowManagerPolicy.WindowState {
pw.print(" last="); mLastVisibleInsets.printShortString(pw);
pw.println();
}
- if (mAnimating || mLocalAnimating || mAnimationIsEntrance
- || mAnimation != null) {
- pw.print(prefix); pw.print("mAnimating="); pw.print(mAnimating);
- pw.print(" mLocalAnimating="); pw.print(mLocalAnimating);
- pw.print(" mAnimationIsEntrance="); pw.print(mAnimationIsEntrance);
- pw.print(" mAnimation="); pw.println(mAnimation);
- }
- if (mHasTransformation || mHasLocalTransformation) {
- pw.print(prefix); pw.print("XForm: has=");
- pw.print(mHasTransformation);
- pw.print(" hasLocal="); pw.print(mHasLocalTransformation);
- pw.print(" "); mTransformation.printShortString(pw);
- pw.println();
- }
+ mWinAnimator.dump(pw, prefix, dumpAll);
if (mShownAlpha != 1 || mAlpha != 1 || mLastAlpha != 1) {
pw.print(prefix); pw.print("mShownAlpha="); pw.print(mShownAlpha);
pw.print(" mAlpha="); pw.print(mAlpha);
diff --git a/services/java/com/android/server/wm/WindowStateAnimator.java b/services/java/com/android/server/wm/WindowStateAnimator.java
new file mode 100644
index 0000000..d86d411
--- /dev/null
+++ b/services/java/com/android/server/wm/WindowStateAnimator.java
@@ -0,0 +1,298 @@
+// Copyright 2012 Google Inc. All Rights Reserved.
+
+package com.android.server.wm;
+
+import android.util.Slog;
+import android.view.WindowManager;
+import android.view.WindowManagerPolicy;
+import android.view.animation.Animation;
+import android.view.animation.Transformation;
+
+import com.android.server.wm.WindowManagerService.H;
+
+import java.io.PrintWriter;
+
+/**
+ * @author cmautner@google.com (Craig Mautner)
+ *
+ */
+class WindowStateAnimator {
+
+ final WindowManagerService mService;
+ final WindowState mWin;
+ final WindowState mAttachedWindow;
+
+ // Currently running animation.
+ boolean mAnimating;
+ boolean mLocalAnimating;
+ Animation mAnimation;
+ boolean mAnimationIsEntrance;
+ boolean mHasTransformation;
+ boolean mHasLocalTransformation;
+ final Transformation mTransformation = new Transformation();
+ boolean mWasAnimating; // Were we animating going into the most recent animation step?
+
+ public WindowStateAnimator(final WindowManagerService service, final WindowState win,
+ final WindowState attachedWindow) {
+ mService = service;
+ mWin = win;
+ mAttachedWindow = attachedWindow;
+ }
+
+ public void setAnimation(Animation anim) {
+ if (WindowManagerService.localLOGV) Slog.v(
+ WindowManagerService.TAG, "Setting animation in " + this + ": " + anim);
+ mAnimating = false;
+ mLocalAnimating = false;
+ mAnimation = anim;
+ mAnimation.restrictDuration(WindowManagerService.MAX_ANIMATION_DURATION);
+ mAnimation.scaleCurrentDuration(mService.mWindowAnimationScale);
+ // Start out animation gone if window is gone, or visible if window is visible.
+ mTransformation.clear();
+ mTransformation.setAlpha(mWin.mLastHidden ? 0 : 1);
+ mHasLocalTransformation = true;
+ }
+
+ public void clearAnimation() {
+ if (mAnimation != null) {
+ mAnimating = true;
+ mLocalAnimating = false;
+ mAnimation.cancel();
+ mAnimation = null;
+ }
+ }
+
+ /** Is the window or its container currently animating? */
+ boolean isAnimating() {
+ final WindowState attached = mAttachedWindow;
+ final AppWindowToken atoken = mWin.mAppToken;
+ return mAnimation != null
+ || (attached != null && attached.mWinAnimator.mAnimation != null)
+ || (atoken != null &&
+ (atoken.animation != null
+ || atoken.inPendingTransaction));
+ }
+
+ /** Is this window currently animating? */
+ boolean isWindowAnimating() {
+ return mAnimation != null;
+ }
+
+ // TODO: Fix and call finishExit() instead of cancelExitAnimationForNextAnimationLocked()
+ // for avoiding the code duplication.
+ void cancelExitAnimationForNextAnimationLocked() {
+ if (!mWin.mExiting) return;
+ if (mAnimation != null) {
+ mAnimation.cancel();
+ mAnimation = null;
+ mWin.destroySurfaceLocked();
+ }
+ mWin.mExiting = false;
+ }
+
+ private boolean stepAnimation(long currentTime) {
+ if ((mAnimation == null) || !mLocalAnimating) {
+ return false;
+ }
+ mTransformation.clear();
+ final boolean more = mAnimation.getTransformation(currentTime, mTransformation);
+ if (WindowManagerService.DEBUG_ANIM) Slog.v(
+ WindowManagerService.TAG, "Stepped animation in " + this +
+ ": more=" + more + ", xform=" + mTransformation);
+ return more;
+ }
+
+ // This must be called while inside a transaction. Returns true if
+ // there is more animation to run.
+ boolean stepAnimationLocked(long currentTime) {
+ // Save the animation state as it was before this step so WindowManagerService can tell if
+ // we just started or just stopped animating by comparing mWasAnimating with isAnimating().
+ mWasAnimating = mAnimating;
+ if (mService.okToDisplay()) {
+ // We will run animations as long as the display isn't frozen.
+
+ if (mWin.isDrawnLw() && mAnimation != null) {
+ mHasTransformation = true;
+ mHasLocalTransformation = true;
+ if (!mLocalAnimating) {
+ if (WindowManagerService.DEBUG_ANIM) Slog.v(
+ WindowManagerService.TAG, "Starting animation in " + this +
+ " @ " + currentTime + ": ww=" + mWin.mFrame.width() +
+ " wh=" + mWin.mFrame.height() +
+ " dw=" + mWin.mAnimDw + " dh=" + mWin.mAnimDh +
+ " scale=" + mService.mWindowAnimationScale);
+ mAnimation.initialize(mWin.mFrame.width(), mWin.mFrame.height(), mWin.mAnimDw,
+ mWin.mAnimDh);
+ mAnimation.setStartTime(currentTime);
+ mLocalAnimating = true;
+ mAnimating = true;
+ }
+ if ((mAnimation != null) && mLocalAnimating) {
+ if (stepAnimation(currentTime)) {
+ return true;
+ }
+ }
+ if (WindowManagerService.DEBUG_ANIM) Slog.v(
+ WindowManagerService.TAG, "Finished animation in " + this +
+ " @ " + currentTime);
+ //WindowManagerService.this.dump();
+ }
+ mHasLocalTransformation = false;
+ if ((!mLocalAnimating || mAnimationIsEntrance) && mWin.mAppToken != null
+ && mWin.mAppToken.animation != null) {
+ // When our app token is animating, we kind-of pretend like
+ // we are as well. Note the mLocalAnimating mAnimationIsEntrance
+ // part of this check means that we will only do this if
+ // our window is not currently exiting, or it is not
+ // locally animating itself. The idea being that one that
+ // is exiting and doing a local animation should be removed
+ // once that animation is done.
+ mAnimating = true;
+ mHasTransformation = true;
+ mTransformation.clear();
+ return false;
+ } else if (mHasTransformation) {
+ // Little trick to get through the path below to act like
+ // we have finished an animation.
+ mAnimating = true;
+ } else if (isAnimating()) {
+ mAnimating = true;
+ }
+ } else if (mAnimation != null) {
+ // If the display is frozen, and there is a pending animation,
+ // clear it and make sure we run the cleanup code.
+ mAnimating = true;
+ mLocalAnimating = true;
+ mAnimation.cancel();
+ mAnimation = null;
+ }
+
+ if (!mAnimating && !mLocalAnimating) {
+ return false;
+ }
+
+ if (WindowManagerService.DEBUG_ANIM) Slog.v(
+ WindowManagerService.TAG, "Animation done in " + this + ": exiting=" + mWin.mExiting
+ + ", reportedVisible="
+ + (mWin.mAppToken != null ? mWin.mAppToken.reportedVisible : false));
+
+ mAnimating = false;
+ mLocalAnimating = false;
+ if (mAnimation != null) {
+ mAnimation.cancel();
+ mAnimation = null;
+ }
+ if (mService.mWindowDetachedWallpaper == mWin) {
+ mService.mWindowDetachedWallpaper = null;
+ }
+ mWin.mAnimLayer = mWin.mLayer;
+ if (mWin.mIsImWindow) {
+ mWin.mAnimLayer += mService.mInputMethodAnimLayerAdjustment;
+ } else if (mWin.mIsWallpaper) {
+ mWin.mAnimLayer += mService.mWallpaperAnimLayerAdjustment;
+ }
+ if (WindowManagerService.DEBUG_LAYERS) Slog.v(WindowManagerService.TAG, "Stepping win " + this
+ + " anim layer: " + mWin.mAnimLayer);
+ mHasTransformation = false;
+ mHasLocalTransformation = false;
+ if (mWin.mPolicyVisibility != mWin.mPolicyVisibilityAfterAnim) {
+ if (WindowState.DEBUG_VISIBILITY) {
+ Slog.v(WindowManagerService.TAG, "Policy visibility changing after anim in " + this + ": "
+ + mWin.mPolicyVisibilityAfterAnim);
+ }
+ mWin.mPolicyVisibility = mWin.mPolicyVisibilityAfterAnim;
+ mService.mLayoutNeeded = true;
+ if (!mWin.mPolicyVisibility) {
+ if (mService.mCurrentFocus == mWin) {
+ mService.mFocusMayChange = true;
+ }
+ // Window is no longer visible -- make sure if we were waiting
+ // for it to be displayed before enabling the display, that
+ // we allow the display to be enabled now.
+ mService.enableScreenIfNeededLocked();
+ }
+ }
+ mTransformation.clear();
+ if (mWin.mHasDrawn
+ && mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING
+ && mWin.mAppToken != null
+ && mWin.mAppToken.firstWindowDrawn
+ && mWin.mAppToken.startingData != null) {
+ if (WindowManagerService.DEBUG_STARTING_WINDOW) Slog.v(WindowManagerService.TAG, "Finish starting "
+ + mWin.mToken + ": first real window done animating");
+ mService.mFinishedStarting.add(mWin.mAppToken);
+ mService.mH.sendEmptyMessage(H.FINISHED_STARTING);
+ }
+
+ finishExit();
+ mService.mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
+ if (WindowManagerService.DEBUG_LAYOUT_REPEATS) mService.debugLayoutRepeats("WindowState");
+
+ if (mWin.mAppToken != null) {
+ mWin.mAppToken.updateReportedVisibilityLocked();
+ }
+
+ return false;
+ }
+
+ void finishExit() {
+ if (WindowManagerService.DEBUG_ANIM) Slog.v(
+ WindowManagerService.TAG, "finishExit in " + this
+ + ": exiting=" + mWin.mExiting
+ + " remove=" + mWin.mRemoveOnExit
+ + " windowAnimating=" + isWindowAnimating());
+
+ final int N = mWin.mChildWindows.size();
+ for (int i=0; i<N; i++) {
+ mWin.mChildWindows.get(i).mWinAnimator.finishExit();
+ }
+
+ if (!mWin.mExiting) {
+ return;
+ }
+
+ if (isWindowAnimating()) {
+ return;
+ }
+
+ if (WindowManagerService.localLOGV) Slog.v(
+ WindowManagerService.TAG, "Exit animation finished in " + this
+ + ": remove=" + mWin.mRemoveOnExit);
+ if (mWin.mSurface != null) {
+ mService.mDestroySurface.add(mWin);
+ mWin.mDestroying = true;
+ if (WindowState.SHOW_TRANSACTIONS) WindowManagerService.logSurface(
+ mWin, "HIDE (finishExit)", null);
+ mWin.mSurfaceShown = false;
+ try {
+ mWin.mSurface.hide();
+ } catch (RuntimeException e) {
+ Slog.w(WindowManagerService.TAG, "Error hiding surface in " + this, e);
+ }
+ mWin.mLastHidden = true;
+ }
+ mWin.mExiting = false;
+ if (mWin.mRemoveOnExit) {
+ mService.mPendingRemove.add(mWin);
+ mWin.mRemoveOnExit = false;
+ }
+ }
+
+ public void dump(PrintWriter pw, String prefix, boolean dumpAll) {
+ if (mAnimating || mLocalAnimating || mAnimationIsEntrance
+ || mAnimation != null) {
+ pw.print(prefix); pw.print("mAnimating="); pw.print(mAnimating);
+ pw.print(" mLocalAnimating="); pw.print(mLocalAnimating);
+ pw.print(" mAnimationIsEntrance="); pw.print(mAnimationIsEntrance);
+ pw.print(" mAnimation="); pw.println(mAnimation);
+ }
+ if (mHasTransformation || mHasLocalTransformation) {
+ pw.print(prefix); pw.print("XForm: has=");
+ pw.print(mHasTransformation);
+ pw.print(" hasLocal="); pw.print(mHasLocalTransformation);
+ pw.print(" "); mTransformation.printShortString(pw);
+ pw.println();
+ }
+ }
+
+}
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
index e8188e7..d736ac1 100644
--- a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
@@ -54,7 +54,7 @@ public class UserManagerTest extends AndroidTestCase {
public void testAddUser() throws Exception {
final UserManager details = mUserManager;
- UserInfo userInfo = details.createUser("Guest 1", UserInfo.FLAG_GUEST, null);
+ UserInfo userInfo = details.createUser("Guest 1", UserInfo.FLAG_GUEST);
assertTrue(userInfo != null);
List<UserInfo> list = details.getUsers();
@@ -73,8 +73,8 @@ public class UserManagerTest extends AndroidTestCase {
public void testAdd2Users() throws Exception {
final UserManager details = mUserManager;
- UserInfo user1 = details.createUser("Guest 1", UserInfo.FLAG_GUEST, null);
- UserInfo user2 = details.createUser("User 2", UserInfo.FLAG_ADMIN, null);
+ UserInfo user1 = details.createUser("Guest 1", UserInfo.FLAG_GUEST);
+ UserInfo user2 = details.createUser("User 2", UserInfo.FLAG_ADMIN);
assertTrue(user1 != null);
assertTrue(user2 != null);
@@ -87,7 +87,7 @@ public class UserManagerTest extends AndroidTestCase {
public void testRemoveUser() throws Exception {
final UserManager details = mUserManager;
- UserInfo userInfo = details.createUser("Guest 1", UserInfo.FLAG_GUEST, null);
+ UserInfo userInfo = details.createUser("Guest 1", UserInfo.FLAG_GUEST);
details.removeUser(userInfo.id);