summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
Diffstat (limited to 'services')
-rw-r--r--services/java/com/android/server/am/ActiveServices.java33
-rw-r--r--services/java/com/android/server/am/ActivityManagerService.java220
-rw-r--r--services/java/com/android/server/am/PendingIntentRecord.java1
-rw-r--r--services/java/com/android/server/am/ProviderMap.java43
-rw-r--r--services/java/com/android/server/pm/PackageManagerService.java372
-rw-r--r--services/java/com/android/server/pm/Settings.java4
6 files changed, 414 insertions, 259 deletions
diff --git a/services/java/com/android/server/am/ActiveServices.java b/services/java/com/android/server/am/ActiveServices.java
index 6a3010b..7144808 100644
--- a/services/java/com/android/server/am/ActiveServices.java
+++ b/services/java/com/android/server/am/ActiveServices.java
@@ -185,7 +185,7 @@ public class ActiveServices {
}
private HashMap<ComponentName, ServiceRecord> getServices(int callingUser) {
- HashMap map = mServicesByNamePerUser.get(callingUser);
+ HashMap<ComponentName, ServiceRecord> map = mServicesByNamePerUser.get(callingUser);
if (map == null) {
map = new HashMap<ComponentName, ServiceRecord>();
mServicesByNamePerUser.put(callingUser, map);
@@ -195,7 +195,8 @@ public class ActiveServices {
private HashMap<Intent.FilterComparison, ServiceRecord> getServicesByIntent(
int callingUser) {
- HashMap map = mServicesByIntentPerUser.get(callingUser);
+ HashMap<Intent.FilterComparison, ServiceRecord> map
+ = mServicesByIntentPerUser.get(callingUser);
if (map == null) {
map = new HashMap<Intent.FilterComparison, ServiceRecord>();
mServicesByIntentPerUser.put(callingUser, map);
@@ -1514,10 +1515,12 @@ public class ActiveServices {
}
}
- boolean forceStopLocked(String name, int userId, boolean evenPersistent, boolean doit) {
+ private boolean collectForceStopServicesLocked(String name, int userId,
+ boolean evenPersistent, boolean doit,
+ HashMap<ComponentName, ServiceRecord> services,
+ ArrayList<ServiceRecord> result) {
boolean didSomething = false;
- ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
- for (ServiceRecord service : mServiceMap.getAllServices(userId)) {
+ for (ServiceRecord service : services.values()) {
if ((name == null || service.packageName.equals(name))
&& (service.app == null || evenPersistent || !service.app.persistent)) {
if (!doit) {
@@ -1530,9 +1533,27 @@ public class ActiveServices {
}
service.app = null;
service.isolatedProc = null;
- services.add(service);
+ result.add(service);
}
}
+ return didSomething;
+ }
+
+ boolean forceStopLocked(String name, int userId, boolean evenPersistent, boolean doit) {
+ boolean didSomething = false;
+ ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
+ if (userId == UserHandle.USER_ALL) {
+ for (int i=0; i<mServiceMap.mServicesByNamePerUser.size(); i++) {
+ didSomething |= collectForceStopServicesLocked(name, userId, evenPersistent,
+ doit, mServiceMap.mServicesByNamePerUser.valueAt(i), services);
+ if (!doit && didSomething) {
+ return true;
+ }
+ }
+ } else {
+ didSomething = collectForceStopServicesLocked(name, userId, evenPersistent,
+ doit, mServiceMap.mServicesByNamePerUser.get(userId), services);
+ }
int N = services.size();
for (int i=0; i<N; i++) {
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 614b93a..76a4f15 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -116,13 +116,11 @@ import android.os.UserManager;
import android.provider.Settings;
import android.text.format.Time;
import android.util.EventLog;
-import android.util.LocaleUtil;
import android.util.Log;
import android.util.Pair;
import android.util.PrintWriterPrinter;
import android.util.Slog;
import android.util.SparseArray;
-import android.util.SparseIntArray;
import android.util.TimeUtils;
import android.view.Gravity;
import android.view.LayoutInflater;
@@ -434,6 +432,11 @@ public final class ActivityManagerService extends ActivityManagerNative
final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
/**
+ * LRU list of history of current users. Most recently current is at the end.
+ */
+ final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
+
+ /**
* Packages that the user has asked to have run in screen size
* compatibility mode instead of filling the screen.
*/
@@ -1094,11 +1097,11 @@ public final class ActivityManagerService extends ActivityManagerNative
} break;
case KILL_APPLICATION_MSG: {
synchronized (ActivityManagerService.this) {
- int uid = msg.arg1;
+ int appid = msg.arg1;
boolean restart = (msg.arg2 == 1);
String pkg = (String) msg.obj;
- forceStopPackageLocked(pkg, uid, restart, false, true, false,
- UserHandle.getUserId(uid));
+ forceStopPackageLocked(pkg, appid, restart, false, true, false,
+ UserHandle.USER_ALL);
}
} break;
case FINALIZE_PENDING_INTENT_MSG: {
@@ -1526,6 +1529,7 @@ public final class ActivityManagerService extends ActivityManagerNative
// User 0 is the first and only user that runs at boot.
mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
+ mUserLru.add(Integer.valueOf(0));
GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
@@ -2385,8 +2389,10 @@ public final class ActivityManagerService extends ActivityManagerNative
public final WaitResult startActivityAndWait(IApplicationThread caller,
Intent intent, String resolvedType, IBinder resultTo,
String resultWho, int requestCode, int startFlags, String profileFile,
- ParcelFileDescriptor profileFd, Bundle options) {
+ ParcelFileDescriptor profileFd, Bundle options, int userId) {
enforceNotIsolatedCaller("startActivityAndWait");
+ userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId,
+ false, true, "startActivityAndWait", null);
WaitResult res = new WaitResult();
mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
@@ -3542,16 +3548,15 @@ public final class ActivityManagerService extends ActivityManagerNative
}
/*
- * The pkg name and uid have to be specified.
- * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int)
+ * The pkg name and app id have to be specified.
*/
- public void killApplicationWithUid(String pkg, int uid) {
+ public void killApplicationWithAppId(String pkg, int appid) {
if (pkg == null) {
return;
}
// Make sure the uid is valid.
- if (uid < 0) {
- Slog.w(TAG, "Invalid uid specified for pkg : " + pkg);
+ if (appid < 0) {
+ Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
return;
}
int callerUid = Binder.getCallingUid();
@@ -3559,7 +3564,7 @@ public final class ActivityManagerService extends ActivityManagerNative
if (callerUid == Process.SYSTEM_UID) {
// Post an aysnc message to kill the application
Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
- msg.arg1 = uid;
+ msg.arg1 = appid;
msg.arg2 = 0;
msg.obj = pkg;
mHandler.sendMessage(msg);
@@ -3691,7 +3696,7 @@ public final class ActivityManagerService extends ActivityManagerNative
MY_PID, Process.SYSTEM_UID, userId);
}
- private final boolean killPackageProcessesLocked(String packageName, int uid,
+ private final boolean killPackageProcessesLocked(String packageName, int appId,
int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
boolean doit, boolean evenPersistent, String reason) {
ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
@@ -3712,32 +3717,41 @@ public final class ActivityManagerService extends ActivityManagerNative
if (doit) {
procs.add(app);
}
+ continue;
+ }
+
+ // Skip process if it doesn't meet our oom adj requirement.
+ if (app.setAdj < minOomAdj) {
+ continue;
+ }
+
// If no package is specified, we call all processes under the
// give user id.
- } else if (packageName == null) {
- if (app.userId == userId) {
- if (app.setAdj >= minOomAdj) {
- if (!doit) {
- return true;
- }
- app.removed = true;
- procs.add(app);
- }
+ if (packageName == null) {
+ if (app.userId != userId) {
+ continue;
}
- // 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))) {
- if (app.setAdj >= minOomAdj) {
- if (!doit) {
- return true;
- }
- app.removed = true;
- procs.add(app);
+ // Package has been specified, we want to hit all processes
+ // that match it. We need to qualify this by the processes
+ // that are running under the specified app and user ID.
+ } else {
+ if (UserHandle.getAppId(app.uid) != appId) {
+ continue;
+ }
+ if (userId != UserHandle.USER_ALL && app.userId != userId) {
+ continue;
+ }
+ if (!app.pkgList.contains(packageName)) {
+ continue;
}
}
+
+ // Process has passed all conditions, kill it!
+ if (!doit) {
+ return true;
+ }
+ app.removed = true;
+ procs.add(app);
}
}
@@ -3748,22 +3762,28 @@ public final class ActivityManagerService extends ActivityManagerNative
return N > 0;
}
- private final boolean forceStopPackageLocked(String name, int uid,
+ private final boolean forceStopPackageLocked(String name, int appId,
boolean callerWillRestart, boolean purgeCache, boolean doit,
boolean evenPersistent, int userId) {
int i;
int N;
- if (uid < 0 && name != null) {
+ if (userId == UserHandle.USER_ALL && name == null) {
+ Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
+ }
+
+ if (appId < 0 && name != null) {
try {
- uid = AppGlobals.getPackageManager().getPackageUid(name, userId);
+ appId = UserHandle.getAppId(
+ AppGlobals.getPackageManager().getPackageUid(name, 0));
} catch (RemoteException e) {
}
}
if (doit) {
if (name != null) {
- Slog.i(TAG, "Force stopping package " + name + " uid=" + uid);
+ Slog.i(TAG, "Force stopping package " + name + " appid=" + appId
+ + " user=" + userId);
} else {
Slog.i(TAG, "Force stopping user " + userId);
}
@@ -3775,8 +3795,14 @@ public final class ActivityManagerService extends ActivityManagerNative
boolean remove = false;
final int entUid = ba.keyAt(i);
if (name != null) {
- if (entUid == uid) {
- remove = true;
+ if (userId == UserHandle.USER_ALL) {
+ if (UserHandle.getAppId(entUid) == appId) {
+ remove = true;
+ }
+ } else {
+ if (entUid == UserHandle.getUid(userId, appId)) {
+ remove = true;
+ }
}
} else if (UserHandle.getUserId(entUid) == userId) {
remove = true;
@@ -3791,9 +3817,8 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
- boolean didSomething = killPackageProcessesLocked(name, uid,
- name == null ? userId : -1 , -100, callerWillRestart, false,
- doit, evenPersistent,
+ boolean didSomething = killPackageProcessesLocked(name, appId, userId,
+ -100, callerWillRestart, false, doit, evenPersistent,
name == null ? ("force stop user " + userId) : ("force stop " + name));
TaskRecord lastTask = null;
@@ -3801,7 +3826,7 @@ public final class ActivityManagerService extends ActivityManagerNative
ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
final boolean samePackage = r.packageName.equals(name)
|| (name == null && r.userId == userId);
- if (r.userId == userId
+ if ((userId == UserHandle.USER_ALL || r.userId == userId)
&& (samePackage || r.task == lastTask)
&& (r.app == null || evenPersistent || !r.app.persistent)) {
if (!doit) {
@@ -3841,22 +3866,64 @@ public final class ActivityManagerService extends ActivityManagerNative
}
ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
- for (ContentProviderRecord provider : mProviderMap.getProvidersByClass(userId).values()) {
- if ((name == null || provider.info.packageName.equals(name))
- && (provider.proc == null || evenPersistent || !provider.proc.persistent)) {
- if (!doit) {
- return true;
- }
- didSomething = true;
- providers.add(provider);
+ if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
+ userId, providers)) {
+ if (!doit) {
+ return true;
}
+ didSomething = true;
}
-
N = providers.size();
for (i=0; i<N; i++) {
removeDyingProviderLocked(null, providers.get(i), true);
}
+ if (mIntentSenderRecords.size() > 0) {
+ Iterator<WeakReference<PendingIntentRecord>> it
+ = mIntentSenderRecords.values().iterator();
+ while (it.hasNext()) {
+ WeakReference<PendingIntentRecord> wpir = it.next();
+ if (wpir == null) {
+ it.remove();
+ continue;
+ }
+ PendingIntentRecord pir = wpir.get();
+ if (pir == null) {
+ it.remove();
+ continue;
+ }
+ if (name == null) {
+ // Stopping user, remove all objects for the user.
+ if (pir.key.userId != userId) {
+ // Not the same user, skip it.
+ continue;
+ }
+ } else {
+ if (UserHandle.getAppId(pir.uid) != appId) {
+ // Different app id, skip it.
+ continue;
+ }
+ if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
+ // Different user, skip it.
+ continue;
+ }
+ if (!pir.key.packageName.equals(name)) {
+ // Different package, skip it.
+ continue;
+ }
+ }
+ if (!doit) {
+ return true;
+ }
+ didSomething = true;
+ it.remove();
+ pir.canceled = true;
+ if (pir.key.activity != null) {
+ pir.key.activity.pendingResults.remove(pir.ref);
+ }
+ }
+ }
+
if (doit) {
if (purgeCache && name != null) {
AttributeCache ac = AttributeCache.instance();
@@ -6778,10 +6845,11 @@ public final class ActivityManagerService extends ActivityManagerNative
* Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
* src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
*/
- public String getProviderMimeType(Uri uri) {
+ public String getProviderMimeType(Uri uri, int userId) {
enforceNotIsolatedCaller("getProviderMimeType");
+ userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(),
+ userId, false, true, "getProviderMimeType", null);
final String name = uri.getAuthority();
- final int userId = UserHandle.getCallingUserId();
final long ident = Binder.clearCallingIdentity();
ContentProviderHolder holder = null;
@@ -7134,7 +7202,8 @@ public final class ActivityManagerService extends ActivityManagerNative
mDebugTransient = !persistent;
if (packageName != null) {
final long origId = Binder.clearCallingIdentity();
- forceStopPackageLocked(packageName, -1, false, false, true, true, 0);
+ forceStopPackageLocked(packageName, -1, false, false, true, true,
+ UserHandle.USER_ALL);
Binder.restoreCallingIdentity(origId);
}
}
@@ -9129,9 +9198,14 @@ public final class ActivityManagerService extends ActivityManagerNative
for (int i=0; i<mStartedUsers.size(); i++) {
UserStartedState uss = mStartedUsers.valueAt(i);
pw.print(" User #"); pw.print(uss.mHandle.getIdentifier());
- pw.println(":");
- uss.dump(" ", pw);
+ pw.print(": "); uss.dump("", pw);
+ }
+ pw.print(" mUserLru: [");
+ for (int i=0; i<mUserLru.size(); i++) {
+ if (i > 0) pw.print(", ");
+ pw.print(mUserLru.get(i));
}
+ pw.println("]");
pw.println(" mHomeProcess: " + mHomeProcess);
pw.println(" mPreviousProcess: " + mPreviousProcess);
if (dumpAll) {
@@ -11815,8 +11889,10 @@ public final class ActivityManagerService extends ActivityManagerNative
public boolean startInstrumentation(ComponentName className,
String profileFile, int flags, Bundle arguments,
- IInstrumentationWatcher watcher) {
+ IInstrumentationWatcher watcher, int userId) {
enforceNotIsolatedCaller("startInstrumentation");
+ userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(),
+ userId, false, true, "startInstrumentation", null);
// Refuse possible leaked file descriptors
if (arguments != null && arguments.hasFileDescriptors()) {
throw new IllegalArgumentException("File descriptors passed in Bundle");
@@ -11828,9 +11904,10 @@ public final class ActivityManagerService extends ActivityManagerNative
try {
ii = mContext.getPackageManager().getInstrumentationInfo(
className, STOCK_PM_FLAGS);
- ai = mContext.getPackageManager().getApplicationInfo(
- ii.targetPackage, STOCK_PM_FLAGS);
+ ai = AppGlobals.getPackageManager().getApplicationInfo(
+ ii.targetPackage, STOCK_PM_FLAGS, userId);
} catch (PackageManager.NameNotFoundException e) {
+ } catch (RemoteException e) {
}
if (ii == null) {
reportStartInstrumentationFailure(watcher, className,
@@ -11857,7 +11934,6 @@ public final class ActivityManagerService extends ActivityManagerNative
throw new SecurityException(msg);
}
- int userId = UserHandle.getCallingUserId();
final long origId = Binder.clearCallingIdentity();
// Instrumentation can kill and relaunch even persistent processes
forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId);
@@ -13780,6 +13856,9 @@ public final class ActivityManagerService extends ActivityManagerNative
}
mCurrentUserId = userId;
+ Integer userIdInt = Integer.valueOf(userId);
+ mUserLru.remove(userIdInt);
+ mUserLru.add(userIdInt);
boolean haveActivities = mMainStack.switchUser(userId);
if (!haveActivities) {
startHomeActivityLocked(userId, mStartedUsers.get(userId));
@@ -13928,6 +14007,23 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
+ @Override
+ public boolean isUserRunning(int userId) {
+ if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
+ != PackageManager.PERMISSION_GRANTED) {
+ String msg = "Permission Denial: isUserRunning() from pid="
+ + Binder.getCallingPid()
+ + ", uid=" + Binder.getCallingUid()
+ + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
+ Slog.w(TAG, msg);
+ throw new SecurityException(msg);
+ }
+ synchronized (this) {
+ UserStartedState state = mStartedUsers.get(userId);
+ return state != null && state.mState != UserStartedState.STATE_STOPPING;
+ }
+ }
+
private boolean userExists(int userId) {
UserInfo user = getUserManager().getUserInfo(userId);
return user != null;
diff --git a/services/java/com/android/server/am/PendingIntentRecord.java b/services/java/com/android/server/am/PendingIntentRecord.java
index 0f72409..c61f13c 100644
--- a/services/java/com/android/server/am/PendingIntentRecord.java
+++ b/services/java/com/android/server/am/PendingIntentRecord.java
@@ -25,7 +25,6 @@ import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
-import android.os.UserHandle;
import android.util.Slog;
import java.io.PrintWriter;
diff --git a/services/java/com/android/server/am/ProviderMap.java b/services/java/com/android/server/am/ProviderMap.java
index 7a4fef6..2d7167b 100644
--- a/services/java/com/android/server/am/ProviderMap.java
+++ b/services/java/com/android/server/am/ProviderMap.java
@@ -180,6 +180,49 @@ public class ProviderMap {
}
}
+ private boolean collectForceStopProvidersLocked(String name, int appId,
+ boolean doit, boolean evenPersistent, int userId,
+ HashMap<ComponentName, ContentProviderRecord> providers,
+ ArrayList<ContentProviderRecord> result) {
+ boolean didSomething = false;
+ for (ContentProviderRecord provider : providers.values()) {
+ if ((name == null || provider.info.packageName.equals(name))
+ && (provider.proc == null || evenPersistent || !provider.proc.persistent)) {
+ if (!doit) {
+ return true;
+ }
+ didSomething = true;
+ result.add(provider);
+ }
+ }
+ return didSomething;
+ }
+
+ boolean collectForceStopProviders(String name, int appId,
+ boolean doit, boolean evenPersistent, int userId,
+ ArrayList<ContentProviderRecord> result) {
+ boolean didSomething = collectForceStopProvidersLocked(name, appId, doit,
+ evenPersistent, userId, mSingletonByClass, result);
+ if (!doit && didSomething) {
+ return true;
+ }
+ if (userId == UserHandle.USER_ALL) {
+ for (int i=0; i<mProvidersByClassPerUser.size(); i++) {
+ if (collectForceStopProvidersLocked(name, appId, doit, evenPersistent,
+ userId, mProvidersByClassPerUser.valueAt(i), result)) {
+ if (!doit) {
+ return true;
+ }
+ didSomething = true;
+ }
+ }
+ } else {
+ didSomething |= collectForceStopProvidersLocked(name, appId, doit, evenPersistent,
+ userId, getProvidersByClass(userId), result);
+ }
+ return didSomething;
+ }
+
private void dumpProvidersByClassLocked(PrintWriter pw, boolean dumpAll,
HashMap<ComponentName, ContentProviderRecord> map) {
Iterator<Map.Entry<ComponentName, ContentProviderRecord>> it = map.entrySet().iterator();
diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java
index 55da11f..5ddf3c3 100644
--- a/services/java/com/android/server/pm/PackageManagerService.java
+++ b/services/java/com/android/server/pm/PackageManagerService.java
@@ -1193,7 +1193,7 @@ public class PackageManagerService extends IPackageManager.Stub {
if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
Slog.i(TAG, "Expecting better updatd system app for " + ps.name
+ "; removing system app");
- removePackageLI(scannedPkg, true);
+ removePackageLI(ps, true);
}
continue;
@@ -1822,7 +1822,7 @@ public class PackageManagerService extends IPackageManager.Stub {
}
pkg = new PackageParser.Package(packageName);
pkg.applicationInfo.packageName = packageName;
- pkg.applicationInfo.flags = ps.pkgFlags;
+ pkg.applicationInfo.flags = ps.pkgFlags | ApplicationInfo.FLAG_IS_DATA_ONLY;
pkg.applicationInfo.publicSourceDir = ps.resourcePathString;
pkg.applicationInfo.sourceDir = ps.codePathString;
pkg.applicationInfo.dataDir =
@@ -4429,20 +4429,40 @@ public class PackageManagerService extends IPackageManager.Stub {
return pkg;
}
- private void killApplication(String pkgName, int uid) {
+ private void killApplication(String pkgName, int appId) {
// Request the ActivityManager to kill the process(only for existing packages)
// so that we do not end up in a confused state while the user is still using the older
// version of the application while the new one gets installed.
IActivityManager am = ActivityManagerNative.getDefault();
if (am != null) {
try {
- am.killApplicationWithUid(pkgName, uid);
+ am.killApplicationWithAppId(pkgName, appId);
} catch (RemoteException e) {
}
}
}
- void removePackageLI(PackageParser.Package pkg, boolean chatty) {
+ void removePackageLI(PackageSetting ps, boolean chatty) {
+ if (DEBUG_INSTALL) {
+ if (chatty)
+ Log.d(TAG, "Removing package " + ps.name);
+ }
+
+ // writer
+ synchronized (mPackages) {
+ mPackages.remove(ps.name);
+ if (ps.codePathString != null) {
+ mAppDirs.remove(ps.codePathString);
+ }
+
+ final PackageParser.Package pkg = ps.pkg;
+ if (pkg != null) {
+ cleanPackageDataStructuresLILPw(pkg, chatty);
+ }
+ }
+ }
+
+ void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) {
if (DEBUG_INSTALL) {
if (chatty)
Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName);
@@ -4454,143 +4474,146 @@ public class PackageManagerService extends IPackageManager.Stub {
if (pkg.mPath != null) {
mAppDirs.remove(pkg.mPath);
}
+ cleanPackageDataStructuresLILPw(pkg, chatty);
+ }
+ }
- int N = pkg.providers.size();
- StringBuilder r = null;
- int i;
- for (i=0; i<N; i++) {
- PackageParser.Provider p = pkg.providers.get(i);
- mProvidersByComponent.remove(new ComponentName(p.info.packageName,
- p.info.name));
- if (p.info.authority == null) {
-
- /* The is another ContentProvider with this authority when
- * this app was installed so this authority is null,
- * Ignore it as we don't have to unregister the provider.
- */
- continue;
- }
- String names[] = p.info.authority.split(";");
- for (int j = 0; j < names.length; j++) {
- if (mProviders.get(names[j]) == p) {
- mProviders.remove(names[j]);
- if (DEBUG_REMOVE) {
- if (chatty)
- Log.d(TAG, "Unregistered content provider: " + names[j]
- + ", className = " + p.info.name + ", isSyncable = "
- + p.info.isSyncable);
- }
- }
- }
- if (chatty) {
- if (r == null) {
- r = new StringBuilder(256);
- } else {
- r.append(' ');
- }
- r.append(p.info.name);
- }
- }
- if (r != null) {
- if (DEBUG_REMOVE) Log.d(TAG, " Providers: " + r);
+ void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) {
+ int N = pkg.providers.size();
+ StringBuilder r = null;
+ int i;
+ for (i=0; i<N; i++) {
+ PackageParser.Provider p = pkg.providers.get(i);
+ mProvidersByComponent.remove(new ComponentName(p.info.packageName,
+ p.info.name));
+ if (p.info.authority == null) {
+
+ /* There was another ContentProvider with this authority when
+ * this app was installed so this authority is null,
+ * Ignore it as we don't have to unregister the provider.
+ */
+ continue;
}
-
- N = pkg.services.size();
- r = null;
- for (i=0; i<N; i++) {
- PackageParser.Service s = pkg.services.get(i);
- mServices.removeService(s);
- if (chatty) {
- if (r == null) {
- r = new StringBuilder(256);
- } else {
- r.append(' ');
+ String names[] = p.info.authority.split(";");
+ for (int j = 0; j < names.length; j++) {
+ if (mProviders.get(names[j]) == p) {
+ mProviders.remove(names[j]);
+ if (DEBUG_REMOVE) {
+ if (chatty)
+ Log.d(TAG, "Unregistered content provider: " + names[j]
+ + ", className = " + p.info.name + ", isSyncable = "
+ + p.info.isSyncable);
}
- r.append(s.info.name);
}
}
- if (r != null) {
- if (DEBUG_REMOVE) Log.d(TAG, " Services: " + r);
+ if (chatty) {
+ if (r == null) {
+ r = new StringBuilder(256);
+ } else {
+ r.append(' ');
+ }
+ r.append(p.info.name);
}
+ }
+ if (r != null) {
+ if (DEBUG_REMOVE) Log.d(TAG, " Providers: " + r);
+ }
- N = pkg.receivers.size();
- r = null;
- for (i=0; i<N; i++) {
- PackageParser.Activity a = pkg.receivers.get(i);
- mReceivers.removeActivity(a, "receiver");
- if (chatty) {
- if (r == null) {
- r = new StringBuilder(256);
- } else {
- r.append(' ');
- }
- r.append(a.info.name);
+ N = pkg.services.size();
+ r = null;
+ for (i=0; i<N; i++) {
+ PackageParser.Service s = pkg.services.get(i);
+ mServices.removeService(s);
+ if (chatty) {
+ if (r == null) {
+ r = new StringBuilder(256);
+ } else {
+ r.append(' ');
}
+ r.append(s.info.name);
}
- if (r != null) {
- if (DEBUG_REMOVE) Log.d(TAG, " Receivers: " + r);
- }
+ }
+ if (r != null) {
+ if (DEBUG_REMOVE) Log.d(TAG, " Services: " + r);
+ }
- N = pkg.activities.size();
- r = null;
- for (i=0; i<N; i++) {
- PackageParser.Activity a = pkg.activities.get(i);
- mActivities.removeActivity(a, "activity");
- if (chatty) {
- if (r == null) {
- r = new StringBuilder(256);
- } else {
- r.append(' ');
- }
- r.append(a.info.name);
+ N = pkg.receivers.size();
+ r = null;
+ for (i=0; i<N; i++) {
+ PackageParser.Activity a = pkg.receivers.get(i);
+ mReceivers.removeActivity(a, "receiver");
+ if (chatty) {
+ if (r == null) {
+ r = new StringBuilder(256);
+ } else {
+ r.append(' ');
}
+ r.append(a.info.name);
}
- if (r != null) {
- if (DEBUG_REMOVE) Log.d(TAG, " Activities: " + r);
- }
+ }
+ if (r != null) {
+ if (DEBUG_REMOVE) Log.d(TAG, " Receivers: " + r);
+ }
- N = pkg.permissions.size();
- r = null;
- for (i=0; i<N; i++) {
- PackageParser.Permission p = pkg.permissions.get(i);
- BasePermission bp = mSettings.mPermissions.get(p.info.name);
- if (bp == null) {
- bp = mSettings.mPermissionTrees.get(p.info.name);
- }
- if (bp != null && bp.perm == p) {
- bp.perm = null;
- if (chatty) {
- if (r == null) {
- r = new StringBuilder(256);
- } else {
- r.append(' ');
- }
- r.append(p.info.name);
- }
+ N = pkg.activities.size();
+ r = null;
+ for (i=0; i<N; i++) {
+ PackageParser.Activity a = pkg.activities.get(i);
+ mActivities.removeActivity(a, "activity");
+ if (chatty) {
+ if (r == null) {
+ r = new StringBuilder(256);
+ } else {
+ r.append(' ');
}
+ r.append(a.info.name);
}
- if (r != null) {
- if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r);
- }
+ }
+ if (r != null) {
+ if (DEBUG_REMOVE) Log.d(TAG, " Activities: " + r);
+ }
- N = pkg.instrumentation.size();
- r = null;
- for (i=0; i<N; i++) {
- PackageParser.Instrumentation a = pkg.instrumentation.get(i);
- mInstrumentation.remove(a.getComponentName());
+ N = pkg.permissions.size();
+ r = null;
+ for (i=0; i<N; i++) {
+ PackageParser.Permission p = pkg.permissions.get(i);
+ BasePermission bp = mSettings.mPermissions.get(p.info.name);
+ if (bp == null) {
+ bp = mSettings.mPermissionTrees.get(p.info.name);
+ }
+ if (bp != null && bp.perm == p) {
+ bp.perm = null;
if (chatty) {
if (r == null) {
r = new StringBuilder(256);
} else {
r.append(' ');
}
- r.append(a.info.name);
+ r.append(p.info.name);
}
}
- if (r != null) {
- if (DEBUG_REMOVE) Log.d(TAG, " Instrumentation: " + r);
+ }
+ if (r != null) {
+ if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r);
+ }
+
+ N = pkg.instrumentation.size();
+ r = null;
+ for (i=0; i<N; i++) {
+ PackageParser.Instrumentation a = pkg.instrumentation.get(i);
+ mInstrumentation.remove(a.getComponentName());
+ if (chatty) {
+ if (r == null) {
+ r = new StringBuilder(256);
+ } else {
+ r.append(' ');
+ }
+ r.append(a.info.name);
}
}
+ if (r != null) {
+ if (DEBUG_REMOVE) Log.d(TAG, " Instrumentation: " + r);
+ }
}
private static final boolean isPackageFilename(String name) {
@@ -5424,10 +5447,10 @@ public class PackageManagerService extends IPackageManager.Stub {
public void onEvent(int event, String path) {
String removedPackage = null;
- int removedUid = -1;
+ int removedAppId = -1;
int[] removedUsers = null;
String addedPackage = null;
- int addedUid = -1;
+ int addedAppId = -1;
int[] addedUsers = null;
// TODO post a message to the handler to obtain serial ordering
@@ -5454,11 +5477,12 @@ public class PackageManagerService extends IPackageManager.Stub {
return;
}
PackageParser.Package p = null;
+ PackageSetting ps = null;
// reader
synchronized (mPackages) {
p = mAppDirs.get(fullPathStr);
if (p != null) {
- PackageSetting ps = mSettings.mPackages.get(p.applicationInfo.packageName);
+ ps = mSettings.mPackages.get(p.applicationInfo.packageName);
if (ps != null) {
removedUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
} else {
@@ -5468,10 +5492,10 @@ public class PackageManagerService extends IPackageManager.Stub {
addedUsers = sUserManager.getUserIds();
}
if ((event&REMOVE_EVENTS) != 0) {
- if (p != null) {
- removePackageLI(p, true);
- removedPackage = p.applicationInfo.packageName;
- removedUid = p.applicationInfo.uid;
+ if (ps != null) {
+ removePackageLI(ps, true);
+ removedPackage = ps.name;
+ removedAppId = ps.appId;
}
}
@@ -5496,7 +5520,7 @@ public class PackageManagerService extends IPackageManager.Stub {
p.permissions.size() > 0 ? UPDATE_PERMISSIONS_ALL : 0);
}
addedPackage = p.applicationInfo.packageName;
- addedUid = p.applicationInfo.uid;
+ addedAppId = UserHandle.getAppId(p.applicationInfo.uid);
}
}
}
@@ -5509,14 +5533,14 @@ public class PackageManagerService extends IPackageManager.Stub {
if (removedPackage != null) {
Bundle extras = new Bundle(1);
- extras.putInt(Intent.EXTRA_UID, removedUid);
+ extras.putInt(Intent.EXTRA_UID, removedAppId);
extras.putBoolean(Intent.EXTRA_DATA_REMOVED, false);
sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage,
extras, null, null, removedUsers);
}
if (addedPackage != null) {
Bundle extras = new Bundle(1);
- extras.putInt(Intent.EXTRA_UID, addedUid);
+ extras.putInt(Intent.EXTRA_UID, addedAppId);
sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, addedPackage,
extras, null, null, addedUsers);
}
@@ -7527,7 +7551,7 @@ public class PackageManagerService extends IPackageManager.Stub {
res.removedInfo.uid = oldPkg.applicationInfo.uid;
res.removedInfo.removedPackage = packageName;
// Remove existing system package
- removePackageLI(oldPkg, true);
+ removePackageLI(oldPkgSetting, true);
// writer
synchronized (mPackages) {
if (!mSettings.disableSystemPackageLPw(packageName) && deletedPackage != null) {
@@ -7566,7 +7590,7 @@ public class PackageManagerService extends IPackageManager.Stub {
// Re installation failed. Restore old information
// Remove new pkg information
if (newPackage != null) {
- removePackageLI(newPackage, true);
+ removeInstalledPackageLI(newPackage, true);
}
// Add back the old system package
scanPackageLI(oldPkg, parseFlags, SCAN_MONITOR | SCAN_UPDATE_SIGNATURE, 0, user);
@@ -7967,10 +7991,10 @@ public class PackageManagerService extends IPackageManager.Stub {
* make sure this flag is set for partially installed apps. If not its meaningless to
* delete a partially installed application.
*/
- private void removePackageDataLI(PackageParser.Package p, PackageRemovedInfo outInfo,
+ private void removePackageDataLI(PackageSetting ps, PackageRemovedInfo outInfo,
int flags, boolean writeSettings) {
- String packageName = p.packageName;
- removePackageLI(p, (flags&REMOVE_CHATTY) != 0);
+ String packageName = ps.name;
+ removePackageLI(ps, (flags&REMOVE_CHATTY) != 0);
// Retrieve object to delete permissions for shared user later on
final PackageSetting deletedPs;
// reader
@@ -8015,38 +8039,32 @@ public class PackageManagerService extends IPackageManager.Stub {
/*
* Tries to delete system package.
*/
- private boolean deleteSystemPackageLI(PackageParser.Package p,
+ private boolean deleteSystemPackageLI(PackageSetting newPs,
int flags, PackageRemovedInfo outInfo, boolean writeSettings) {
- ApplicationInfo applicationInfo = p.applicationInfo;
- //applicable for non-partially installed applications only
- if (applicationInfo == null) {
- Slog.w(TAG, "Package " + p.packageName + " has no applicationInfo.");
- return false;
- }
- PackageSetting ps = null;
+ PackageSetting disabledPs = null;
// Confirm if the system package has been updated
// An updated system app can be deleted. This will also have to restore
// the system pkg from system partition
// reader
synchronized (mPackages) {
- ps = mSettings.getDisabledSystemPkgLPr(p.packageName);
+ disabledPs = mSettings.getDisabledSystemPkgLPr(newPs.name);
}
- if (ps == null) {
- Slog.w(TAG, "Attempt to delete unknown system package "+ p.packageName);
+ if (disabledPs == null) {
+ Slog.w(TAG, "Attempt to delete unknown system package "+ newPs.name);
return false;
} else {
Log.i(TAG, "Deleting system pkg from data partition");
}
// Delete the updated package
outInfo.isRemovedPackageSystemUpdate = true;
- if (ps.versionCode < p.mVersionCode) {
+ if (disabledPs.versionCode < newPs.versionCode) {
// Delete data for downgrades
flags &= ~PackageManager.DELETE_KEEP_DATA;
} else {
// Preserve data by setting flag
flags |= PackageManager.DELETE_KEEP_DATA;
}
- boolean ret = deleteInstalledPackageLI(p, true, flags, outInfo,
+ boolean ret = deleteInstalledPackageLI(newPs, true, flags, outInfo,
writeSettings);
if (!ret) {
return false;
@@ -8054,17 +8072,18 @@ public class PackageManagerService extends IPackageManager.Stub {
// writer
synchronized (mPackages) {
// Reinstate the old system package
- mSettings.enableSystemPackageLPw(p.packageName);
+ mSettings.enableSystemPackageLPw(newPs.name);
// Remove any native libraries from the upgraded package.
- NativeLibraryHelper.removeNativeBinariesLI(p.applicationInfo.nativeLibraryDir);
+ NativeLibraryHelper.removeNativeBinariesLI(newPs.nativeLibraryPathString);
}
// Install the system package
- PackageParser.Package newPkg = scanPackageLI(ps.codePath,
+ PackageParser.Package newPkg = scanPackageLI(disabledPs.codePath,
PackageParser.PARSE_MUST_BE_APK | PackageParser.PARSE_IS_SYSTEM,
SCAN_MONITOR | SCAN_NO_PATHS, 0, null);
if (newPkg == null) {
- Slog.w(TAG, "Failed to restore system package:"+p.packageName+" with error:" + mLastScanError);
+ Slog.w(TAG, "Failed to restore system package:" + newPs.name
+ + " with error:" + mLastScanError);
return false;
}
// writer
@@ -8079,28 +8098,23 @@ public class PackageManagerService extends IPackageManager.Stub {
return true;
}
- private boolean deleteInstalledPackageLI(PackageParser.Package p,
+ private boolean deleteInstalledPackageLI(PackageSetting ps,
boolean deleteCodeAndResources, int flags, PackageRemovedInfo outInfo,
boolean writeSettings) {
- ApplicationInfo applicationInfo = p.applicationInfo;
- if (applicationInfo == null) {
- Slog.w(TAG, "Package " + p.packageName + " has no applicationInfo.");
- return false;
- }
if (outInfo != null) {
- outInfo.uid = applicationInfo.uid;
+ outInfo.uid = ps.appId;
}
// Delete package data from internal structures and also remove data if flag is set
- removePackageDataLI(p, outInfo, flags, writeSettings);
+ removePackageDataLI(ps, outInfo, flags, writeSettings);
// Delete application code and resources
if (deleteCodeAndResources) {
// TODO can pick up from PackageSettings as well
- int installFlags = isExternal(p) ? PackageManager.INSTALL_EXTERNAL : 0;
- installFlags |= isForwardLocked(p) ? PackageManager.INSTALL_FORWARD_LOCK : 0;
- outInfo.args = createInstallArgs(installFlags, applicationInfo.sourceDir,
- applicationInfo.publicSourceDir, applicationInfo.nativeLibraryDir);
+ int installFlags = isExternal(ps) ? PackageManager.INSTALL_EXTERNAL : 0;
+ installFlags |= isForwardLocked(ps) ? PackageManager.INSTALL_FORWARD_LOCK : 0;
+ outInfo.args = createInstallArgs(installFlags, ps.codePathString,
+ ps.resourcePathString, ps.nativeLibraryPathString);
}
return true;
}
@@ -8115,28 +8129,17 @@ public class PackageManagerService extends IPackageManager.Stub {
Slog.w(TAG, "Attempt to delete null packageName.");
return false;
}
- PackageParser.Package p;
+ PackageSetting ps;
boolean dataOnly = false;
int removeUser = -1;
int appId = -1;
synchronized (mPackages) {
- p = mPackages.get(packageName);
- if (p == null) {
- //this retrieves partially installed apps
- dataOnly = true;
- PackageSetting ps = mSettings.mPackages.get(packageName);
- if (ps == null) {
- Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
- return false;
- }
- p = ps.pkg;
- }
- if (p == null) {
+ ps = mSettings.mPackages.get(packageName);
+ if (ps == null) {
Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
return false;
}
- final PackageSetting ps = (PackageSetting)p.mExtras;
- if (!isSystemApp(p) && ps != null && user != null
+ if (!isSystemApp(ps) && user != null
&& user.getIdentifier() != UserHandle.USER_ALL) {
// The caller is asking that the package only be deleted for a single
// user. To do this, we just mark its uninstalled state and delete
@@ -8177,25 +8180,20 @@ public class PackageManagerService extends IPackageManager.Stub {
if (dataOnly) {
// Delete application data first
- removePackageDataLI(p, outInfo, flags, writeSettings);
+ removePackageDataLI(ps, outInfo, flags, writeSettings);
return true;
}
- // At this point the package should have ApplicationInfo associated with it
- if (p.applicationInfo == null) {
- Slog.w(TAG, "Package " + p.packageName + " has no applicationInfo.");
- return false;
- }
boolean ret = false;
- if (isSystemApp(p)) {
- Log.i(TAG, "Removing system package:"+p.packageName);
+ if (isSystemApp(ps)) {
+ Log.i(TAG, "Removing system package:" + ps.name);
// When an updated system application is deleted we delete the existing resources as well and
// fall back to existing code in system partition
- ret = deleteSystemPackageLI(p, flags, outInfo, writeSettings);
+ ret = deleteSystemPackageLI(ps, flags, outInfo, writeSettings);
} else {
- Log.i(TAG, "Removing non-system package:"+p.packageName);
+ Log.i(TAG, "Removing non-system package:" + ps.name);
// Kill application pre-emptively especially for apps on sd.
- killApplication(packageName, p.applicationInfo.uid);
- ret = deleteInstalledPackageLI(p, deleteCodeAndResources, flags, outInfo,
+ killApplication(packageName, ps.appId);
+ ret = deleteInstalledPackageLI(ps, deleteCodeAndResources, flags, outInfo,
writeSettings);
}
return ret;
diff --git a/services/java/com/android/server/pm/Settings.java b/services/java/com/android/server/pm/Settings.java
index 5f10d44..d058a82 100644
--- a/services/java/com/android/server/pm/Settings.java
+++ b/services/java/com/android/server/pm/Settings.java
@@ -32,7 +32,6 @@ import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlSerializer;
-import android.app.AppGlobals;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -50,7 +49,6 @@ import android.os.Binder;
import android.os.Environment;
import android.os.FileUtils;
import android.os.Process;
-import android.os.RemoteException;
import android.os.UserHandle;
import android.util.Log;
import android.util.Slog;
@@ -2603,8 +2601,8 @@ final class Settings {
first = false;
pw.print("anyDensity");
}
+ pw.println("]");
}
- pw.println("]");
pw.print(" timeStamp=");
date.setTime(ps.timeStamp);
pw.println(sdf.format(date));