diff options
Diffstat (limited to 'services')
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)); |