summaryrefslogtreecommitdiff
path: root/services/java
diff options
context:
space:
mode:
author Dianne Hackborn <hackbod@google.com> 2012-08-27 15:59:56 -0700
committer Android (Google) Code Review <android-gerrit@google.com> 2012-08-27 15:59:56 -0700
commit0e17e5bc43373ff9dd8d567f876a26f990ed638e (patch)
tree344da2d01806715678bede4ec7f4c3d04eb21ead /services/java
parent40edfc97795e34b1f24b15ca8f0ccba37fa1efbc (diff)
parent786b44046a79d6c4c9cd07f5989d491c7196ad80 (diff)
Merge "Fix installing applications from non-primary users." into jb-mr1-dev
Diffstat (limited to 'services/java')
-rw-r--r--services/java/com/android/server/am/ActivityManagerService.java20
-rw-r--r--services/java/com/android/server/am/BroadcastRecord.java22
-rw-r--r--services/java/com/android/server/pm/PackageManagerService.java82
-rw-r--r--services/java/com/android/server/pm/PackageSettingBase.java6
4 files changed, 94 insertions, 36 deletions
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 2b4f8b136316..5921d88ef1d1 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -9404,9 +9404,15 @@ public final class ActivityManagerService extends ActivityManagerNative
boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
int opti, boolean dumpAll, String dumpPackage) {
boolean needSep = false;
-
+ boolean onlyHistory = false;
+
+ if ("history".equals(dumpPackage)) {
+ onlyHistory = true;
+ dumpPackage = null;
+ }
+
pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
- if (dumpAll) {
+ if (!onlyHistory && dumpAll) {
if (mRegisteredReceivers.size() > 0) {
boolean printed = false;
Iterator it = mRegisteredReceivers.values().iterator();
@@ -9439,7 +9445,7 @@ public final class ActivityManagerService extends ActivityManagerNative
needSep = true;
- if (mStickyBroadcasts != null && dumpPackage == null) {
+ if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
if (needSep) {
pw.println();
}
@@ -9471,7 +9477,7 @@ public final class ActivityManagerService extends ActivityManagerNative
needSep = true;
}
- if (dumpAll) {
+ if (!onlyHistory && dumpAll) {
pw.println();
for (BroadcastQueue queue : mBroadcastQueues) {
pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]="
@@ -10982,7 +10988,7 @@ public final class ActivityManagerService extends ActivityManagerNative
BroadcastQueue queue = broadcastQueueForIntent(intent);
BroadcastRecord r = new BroadcastRecord(queue, intent, null,
null, -1, -1, null, receivers, null, 0, null, null,
- false, true, true, false);
+ false, true, true, false, -1);
queue.enqueueParallelBroadcastLocked(r);
queue.scheduleBroadcastsLocked();
}
@@ -11288,7 +11294,7 @@ public final class ActivityManagerService extends ActivityManagerNative
BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
callerPackage, callingPid, callingUid, requiredPermission,
registeredReceivers, resultTo, resultCode, resultData, map,
- ordered, sticky, false, onlySendToCaller);
+ ordered, sticky, false, onlySendToCaller, userId);
if (DEBUG_BROADCAST) Slog.v(
TAG, "Enqueueing parallel broadcast " + r);
final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
@@ -11378,7 +11384,7 @@ public final class ActivityManagerService extends ActivityManagerNative
BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
callerPackage, callingPid, callingUid, requiredPermission,
receivers, resultTo, resultCode, resultData, map, ordered,
- sticky, false, onlySendToCaller);
+ sticky, false, onlySendToCaller, userId);
if (DEBUG_BROADCAST) Slog.v(
TAG, "Enqueueing ordered broadcast " + r
+ ": prev had " + queue.mOrderedBroadcasts.size());
diff --git a/services/java/com/android/server/am/BroadcastRecord.java b/services/java/com/android/server/am/BroadcastRecord.java
index 799b609be310..87f1111981b9 100644
--- a/services/java/com/android/server/am/BroadcastRecord.java
+++ b/services/java/com/android/server/am/BroadcastRecord.java
@@ -45,6 +45,7 @@ class BroadcastRecord extends Binder {
final boolean sticky; // originated from existing sticky data?
final boolean initialSticky; // initial broadcast from register to sticky?
final boolean onlySendToCaller; // only allow receipt by sender's components?
+ final int userId; // user id this broadcast was for
final String requiredPermission; // a permission the caller has required
final List receivers; // contains BroadcastFilter and ResolveInfo
IIntentReceiver resultTo; // who receives final result if non-null
@@ -80,7 +81,7 @@ class BroadcastRecord extends Binder {
void dump(PrintWriter pw, String prefix) {
final long now = SystemClock.uptimeMillis();
- pw.print(prefix); pw.println(this);
+ pw.print(prefix); pw.print(this); pw.print(" to user "); pw.println(userId);
pw.print(prefix); pw.println(intent);
if (sticky) {
Bundle bundle = intent.getExtras();
@@ -141,14 +142,15 @@ class BroadcastRecord extends Binder {
pw.println(curReceiver.applicationInfo.sourceDir);
}
}
- String stateStr = " (?)";
- switch (state) {
- case IDLE: stateStr=" (IDLE)"; break;
- case APP_RECEIVE: stateStr=" (APP_RECEIVE)"; break;
- case CALL_IN_RECEIVE: stateStr=" (CALL_IN_RECEIVE)"; break;
- case CALL_DONE_RECEIVE: stateStr=" (CALL_DONE_RECEIVE)"; break;
+ if (state != IDLE) {
+ String stateStr = " (?)";
+ switch (state) {
+ case APP_RECEIVE: stateStr=" (APP_RECEIVE)"; break;
+ case CALL_IN_RECEIVE: stateStr=" (CALL_IN_RECEIVE)"; break;
+ case CALL_DONE_RECEIVE: stateStr=" (CALL_DONE_RECEIVE)"; break;
+ }
+ pw.print(prefix); pw.print("state="); pw.print(state); pw.println(stateStr);
}
- pw.print(prefix); pw.print("state="); pw.print(state); pw.println(stateStr);
final int N = receivers != null ? receivers.size() : 0;
String p2 = prefix + " ";
PrintWriterPrinter printer = new PrintWriterPrinter(pw);
@@ -168,7 +170,8 @@ class BroadcastRecord extends Binder {
int _callingPid, int _callingUid, String _requiredPermission,
List _receivers, IIntentReceiver _resultTo, int _resultCode,
String _resultData, Bundle _resultExtras, boolean _serialized,
- boolean _sticky, boolean _initialSticky, boolean _onlySendToCaller) {
+ boolean _sticky, boolean _initialSticky, boolean _onlySendToCaller,
+ int _userId) {
queue = _queue;
intent = _intent;
callerApp = _callerApp;
@@ -185,6 +188,7 @@ class BroadcastRecord extends Binder {
sticky = _sticky;
initialSticky = _initialSticky;
onlySendToCaller = _onlySendToCaller;
+ userId = _userId;
nextReceiver = 0;
state = IDLE;
}
diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java
index b84e25a6b26d..13d86baf2abf 100644
--- a/services/java/com/android/server/pm/PackageManagerService.java
+++ b/services/java/com/android/server/pm/PackageManagerService.java
@@ -710,20 +710,56 @@ public class PackageManagerService extends IPackageManager.Stub {
res.removedInfo.sendBroadcast(false, true);
Bundle extras = new Bundle(1);
extras.putInt(Intent.EXTRA_UID, res.uid);
+ // Determine the set of users who are adding this
+ // package for the first time vs. those who are seeing
+ // an update.
+ int[] firstUsers;
+ int[] updateUsers = new int[0];
+ if (res.origUsers == null || res.origUsers.length == 0) {
+ firstUsers = res.newUsers;
+ } else {
+ firstUsers = new int[0];
+ for (int i=0; i<res.newUsers.length; i++) {
+ int user = res.newUsers[i];
+ boolean isNew = true;
+ for (int j=0; j<res.origUsers.length; j++) {
+ if (res.origUsers[j] == user) {
+ isNew = false;
+ break;
+ }
+ }
+ if (isNew) {
+ int[] newFirst = new int[firstUsers.length+1];
+ System.arraycopy(firstUsers, 0, newFirst, 0,
+ firstUsers.length);
+ newFirst[firstUsers.length] = user;
+ firstUsers = newFirst;
+ } else {
+ int[] newUpdate = new int[updateUsers.length+1];
+ System.arraycopy(updateUsers, 0, newUpdate, 0,
+ updateUsers.length);
+ newUpdate[updateUsers.length] = user;
+ updateUsers = newUpdate;
+ }
+ }
+ }
+ sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
+ res.pkg.applicationInfo.packageName,
+ extras, null, null, firstUsers);
final boolean update = res.removedInfo.removedPackage != null;
if (update) {
extras.putBoolean(Intent.EXTRA_REPLACING, true);
}
sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
res.pkg.applicationInfo.packageName,
- extras, null, null, res.users);
+ extras, null, null, updateUsers);
if (update) {
sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
res.pkg.applicationInfo.packageName,
- extras, null, null, res.users);
+ extras, null, null, updateUsers);
sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
null, null,
- res.pkg.applicationInfo.packageName, null, res.users);
+ res.pkg.applicationInfo.packageName, null, updateUsers);
}
if (res.removedInfo.args != null) {
// Remove the replaced package's older resources safely now
@@ -5343,8 +5379,10 @@ public class PackageManagerService extends IPackageManager.Stub {
public void onEvent(int event, String path) {
String removedPackage = null;
int removedUid = -1;
+ int[] removedUsers = null;
String addedPackage = null;
int addedUid = -1;
+ int[] addedUsers = null;
// TODO post a message to the handler to obtain serial ordering
synchronized (mInstallLock) {
@@ -5373,6 +5411,15 @@ public class PackageManagerService extends IPackageManager.Stub {
// reader
synchronized (mPackages) {
p = mAppDirs.get(fullPathStr);
+ if (p != null) {
+ PackageSetting ps = mSettings.mPackages.get(p.applicationInfo.packageName);
+ if (ps != null) {
+ removedUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
+ } else {
+ removedUsers = sUserManager.getUserIds();
+ }
+ }
+ addedUsers = sUserManager.getUserIds();
}
if ((event&REMOVE_EVENTS) != 0) {
if (p != null) {
@@ -5390,7 +5437,7 @@ public class PackageManagerService extends IPackageManager.Stub {
PackageParser.PARSE_CHATTY |
PackageParser.PARSE_MUST_BE_APK,
SCAN_MONITOR | SCAN_NO_PATHS | SCAN_UPDATE_TIME,
- System.currentTimeMillis(), null);
+ System.currentTimeMillis(), UserHandle.ALL);
if (p != null) {
/*
* TODO this seems dangerous as the package may have
@@ -5419,13 +5466,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, null);
+ extras, null, null, removedUsers);
}
if (addedPackage != null) {
Bundle extras = new Bundle(1);
extras.putInt(Intent.EXTRA_UID, addedUid);
sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, addedPackage,
- extras, null, null, null);
+ extras, null, null, addedUsers);
}
}
@@ -5468,7 +5515,7 @@ public class PackageManagerService extends IPackageManager.Stub {
if ((flags&PackageManager.INSTALL_ALL_USERS) != 0) {
user = UserHandle.ALL;
} else {
- user = Process.myUserHandle();
+ user = new UserHandle(UserHandle.getUserId(uid));
}
final int filteredFlags;
@@ -7212,7 +7259,10 @@ public class PackageManagerService extends IPackageManager.Stub {
class PackageInstalledInfo {
String name;
int uid;
- int[] users;
+ // The set of users that originally had this package installed.
+ int[] origUsers;
+ // The set of users that now have this package installed.
+ int[] newUsers;
PackageParser.Package pkg;
int returnCode;
PackageRemovedInfo removedInfo;
@@ -7362,7 +7412,7 @@ public class PackageManagerService extends IPackageManager.Stub {
int oldScanMode = (oldOnSd ? 0 : SCAN_MONITOR) | SCAN_UPDATE_SIGNATURE
| SCAN_UPDATE_TIME;
if (scanPackageLI(restoreFile, oldParseFlags, oldScanMode,
- origUpdateTime, user) == null) {
+ origUpdateTime, null) == null) {
Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade");
return;
}
@@ -7511,10 +7561,6 @@ public class PackageManagerService extends IPackageManager.Stub {
UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0
? UPDATE_PERMISSIONS_ALL : 0));
res.name = pkgName;
- PackageSetting ps = mSettings.mPackages.get(pkgName);
- if (ps != null) {
- res.users = ps.getInstalledUsers(sUserManager.getUserIds());
- }
res.uid = newPackage.applicationInfo.uid;
res.pkg = newPackage;
mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE);
@@ -7612,6 +7658,7 @@ public class PackageManagerService extends IPackageManager.Stub {
systemApp = (ps.pkg.applicationInfo.flags &
ApplicationInfo.FLAG_SYSTEM) != 0;
}
+ res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
}
}
@@ -7634,12 +7681,12 @@ public class PackageManagerService extends IPackageManager.Stub {
installerPackageName, res);
} else {
installNewPackageLI(pkg, parseFlags, scanMode, args.user,
- installerPackageName,res);
+ installerPackageName, res);
}
synchronized (mPackages) {
- PackageSetting ps = mSettings.mPackages.get(pkgName);
+ final PackageSetting ps = mSettings.mPackages.get(pkgName);
if (ps != null) {
- res.users = ps.getInstalledUsers(sUserManager.getUserIds());
+ res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
}
}
}
@@ -7865,7 +7912,8 @@ public class PackageManagerService extends IPackageManager.Stub {
if (outInfo != null) {
outInfo.removedPackage = packageName;
outInfo.removedUsers = deletedPs != null
- ? deletedPs.getInstalledUsers(sUserManager.getUserIds()) : null;
+ ? deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true)
+ : null;
}
}
if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
diff --git a/services/java/com/android/server/pm/PackageSettingBase.java b/services/java/com/android/server/pm/PackageSettingBase.java
index 6d31f0e81db1..d8f73458d387 100644
--- a/services/java/com/android/server/pm/PackageSettingBase.java
+++ b/services/java/com/android/server/pm/PackageSettingBase.java
@@ -210,17 +210,17 @@ class PackageSettingBase extends GrantedPermissions {
return false;
}
- int[] getInstalledUsers(int[] users) {
+ int[] queryInstalledUsers(int[] users, boolean installed) {
int num = 0;
for (int user : users) {
- if (getInstalled(user)) {
+ if (getInstalled(user) == installed) {
num++;
}
}
int[] res = new int[num];
num = 0;
for (int user : users) {
- if (getInstalled(user)) {
+ if (getInstalled(user) == installed) {
res[num] = user;
num++;
}