Skip to content

Commit 4428e17

Browse files
author
Dianne Hackborn
committed
Some clean up of app install and user management.
UserManagerService is now closely tied to PackageManagerService, sharing the same locks. There is no longer direct access of Installer by UserManagerService, instead the package manager is back to solely owning it. Creating a new user now correctly only installs system apps for that user. Fixed some misc bugs, where we were getting nulls when querying content providers and instrumentation in uninstalled users, incorrect locking, etc. Change-Id: Ife69b6e373d0cf7c5cfc03fc588e36b43ad5d8b0
1 parent a31803f commit 4428e17

File tree

5 files changed

+193
-187
lines changed

5 files changed

+193
-187
lines changed

core/java/android/content/pm/RegisteredServicesCache.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -331,12 +331,16 @@ public void generateServicesMap() {
331331
notifyListener(v1, true /* removed */);
332332
}
333333
if (changes.length() > 0) {
334-
Log.d(TAG, "generateServicesMap(" + mInterfaceName + "): " +
335-
serviceInfos.size() + " services:\n" + changes);
334+
if (Log.isLoggable(TAG, Log.VERBOSE)) {
335+
Log.d(TAG, "generateServicesMap(" + mInterfaceName + "): " +
336+
serviceInfos.size() + " services:\n" + changes);
337+
}
336338
writePersistentServicesLocked();
337339
} else {
338-
Log.d(TAG, "generateServicesMap(" + mInterfaceName + "): " +
339-
serviceInfos.size() + " services unchanged");
340+
if (Log.isLoggable(TAG, Log.VERBOSE)) {
341+
Log.d(TAG, "generateServicesMap(" + mInterfaceName + "): " +
342+
serviceInfos.size() + " services unchanged");
343+
}
340344
}
341345
mPersistentServicesFileDidNotExist = false;
342346
}

services/java/com/android/server/SystemServer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ public void run() {
197197

198198
Slog.i(TAG, "User Service");
199199
ServiceManager.addService(Context.USER_SERVICE,
200-
UserManagerService.getInstance(context));
200+
UserManagerService.getInstance());
201201

202202

203203
mContentResolver = context.getContentResolver();

services/java/com/android/server/pm/PackageManagerService.java

Lines changed: 91 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -950,8 +950,8 @@ public PackageManagerService(Context context, boolean factoryTest, boolean onlyC
950950
mUserAppDataDir = new File(dataDir, "user");
951951
mDrmAppPrivateInstallDir = new File(dataDir, "app-private");
952952

953-
sUserManager = UserManagerService.getInstance(context);
954-
sUserManager.setInstaller(this, mInstaller);
953+
sUserManager = new UserManagerService(context, this,
954+
mInstallLock, mPackages);
955955

956956
readPermissions();
957957

@@ -1145,8 +1145,7 @@ public PackageManagerService(Context context, boolean factoryTest, boolean onlyC
11451145
String msg = "System package " + ps.name
11461146
+ " no longer exists; wiping its data";
11471147
reportSettingsProblem(Log.WARN, msg);
1148-
mInstaller.remove(ps.name, 0);
1149-
sUserManager.removePackageForAllUsers(ps.name);
1148+
removeDataDirsLI(ps.name);
11501149
} else {
11511150
final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name);
11521151
if (disabledPs.codePath == null || !disabledPs.codePath.exists()) {
@@ -1195,9 +1194,7 @@ public PackageManagerService(Context context, boolean factoryTest, boolean onlyC
11951194
if (deletedPkg == null) {
11961195
msg = "Updated system package " + deletedAppName
11971196
+ " no longer exists; wiping its data";
1198-
1199-
mInstaller.remove(deletedAppName, 0);
1200-
sUserManager.removePackageForAllUsers(deletedAppName);
1197+
removeDataDirsLI(deletedAppName);
12011198
} else {
12021199
msg = "Updated system app + " + deletedAppName
12031200
+ " no longer present; removing system privileges for "
@@ -1332,13 +1329,7 @@ public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
13321329

13331330
void cleanupInstallFailedPackage(PackageSetting ps) {
13341331
Slog.i(TAG, "Cleaning up incompletely installed app: " + ps.name);
1335-
int retCode = mInstaller.remove(ps.name, 0);
1336-
if (retCode < 0) {
1337-
Slog.w(TAG, "Couldn't remove app data directory for package: "
1338-
+ ps.name + ", retcode=" + retCode);
1339-
} else {
1340-
sUserManager.removePackageForAllUsers(ps.name);
1341-
}
1332+
removeDataDirsLI(ps.name);
13421333
if (ps.codePath != null) {
13431334
if (!ps.codePath.delete()) {
13441335
Slog.w(TAG, "Unable to remove old code file: " + ps.codePath);
@@ -1818,9 +1809,11 @@ public void freeStorageAndNotify(final long freeStorageSize, final IPackageDataO
18181809
public void run() {
18191810
mHandler.removeCallbacks(this);
18201811
int retCode = -1;
1821-
retCode = mInstaller.freeCache(freeStorageSize);
1822-
if (retCode < 0) {
1823-
Slog.w(TAG, "Couldn't clear application caches");
1812+
synchronized (mInstallLock) {
1813+
retCode = mInstaller.freeCache(freeStorageSize);
1814+
if (retCode < 0) {
1815+
Slog.w(TAG, "Couldn't clear application caches");
1816+
}
18241817
}
18251818
if (observer != null) {
18261819
try {
@@ -1841,9 +1834,11 @@ public void freeStorage(final long freeStorageSize, final IntentSender pi) {
18411834
public void run() {
18421835
mHandler.removeCallbacks(this);
18431836
int retCode = -1;
1844-
retCode = mInstaller.freeCache(freeStorageSize);
1845-
if (retCode < 0) {
1846-
Slog.w(TAG, "Couldn't clear application caches");
1837+
synchronized (mInstallLock) {
1838+
retCode = mInstaller.freeCache(freeStorageSize);
1839+
if (retCode < 0) {
1840+
Slog.w(TAG, "Couldn't clear application caches");
1841+
}
18471842
}
18481843
if(pi != null) {
18491844
try {
@@ -2994,7 +2989,9 @@ public List<ProviderInfo> queryContentProviders(String processName,
29942989
}
29952990
ProviderInfo info = PackageParser.generateProviderInfo(p, flags,
29962991
ps.readUserState(userId), userId);
2997-
finalList.add(info);
2992+
if (info != null) {
2993+
finalList.add(info);
2994+
}
29982995
}
29992996
}
30002997
}
@@ -3027,8 +3024,11 @@ public List<InstrumentationInfo> queryInstrumentation(String targetPackage,
30273024
final PackageParser.Instrumentation p = i.next();
30283025
if (targetPackage == null
30293026
|| targetPackage.equals(p.info.targetPackage)) {
3030-
finalList.add(PackageParser.generateInstrumentationInfo(p,
3031-
flags));
3027+
InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p,
3028+
flags);
3029+
if (ii != null) {
3030+
finalList.add(ii);
3031+
}
30323032
}
30333033
}
30343034
}
@@ -3189,7 +3189,7 @@ private PackageParser.Package scanPackageLI(File scanFile,
31893189

31903190
InstallArgs args = createInstallArgs(packageFlagsToInstallFlags(ps),
31913191
ps.codePathString, ps.resourcePathString, ps.nativeLibraryPathString);
3192-
synchronized (mInstaller) {
3192+
synchronized (mInstallLock) {
31933193
args.cleanUpResourcesLI();
31943194
}
31953195
synchronized (mPackages) {
@@ -3245,7 +3245,7 @@ private PackageParser.Package scanPackageLI(File scanFile,
32453245
+ " better than installed " + ps.versionCode);
32463246
InstallArgs args = createInstallArgs(packageFlagsToInstallFlags(ps),
32473247
ps.codePathString, ps.resourcePathString, ps.nativeLibraryPathString);
3248-
synchronized (mInstaller) {
3248+
synchronized (mInstallLock) {
32493249
args.cleanUpResourcesLI();
32503250
}
32513251
}
@@ -3479,6 +3479,36 @@ private File getDataPathForPackage(String packageName, int userId) {
34793479
}
34803480
}
34813481

3482+
private int createDataDirsLI(String packageName, int uid) {
3483+
int[] users = sUserManager.getUserIds();
3484+
int res = mInstaller.install(packageName, uid, uid);
3485+
if (res < 0) {
3486+
return res;
3487+
}
3488+
for (int user : users) {
3489+
if (user != 0) {
3490+
res = mInstaller.createUserData(packageName,
3491+
UserHandle.getUid(user, uid), user);
3492+
if (res < 0) {
3493+
return res;
3494+
}
3495+
}
3496+
}
3497+
return res;
3498+
}
3499+
3500+
private int removeDataDirsLI(String packageName) {
3501+
int[] users = sUserManager.getUserIds();
3502+
int res = 0;
3503+
for (int user : users) {
3504+
int resInner = mInstaller.remove(packageName, user);
3505+
if (resInner < 0) {
3506+
res = resInner;
3507+
}
3508+
}
3509+
return res;
3510+
}
3511+
34823512
private PackageParser.Package scanPackageLI(PackageParser.Package pkg,
34833513
int parseFlags, int scanMode, long currentTime, UserHandle user) {
34843514
File scanFile = new File(pkg.mScanPath);
@@ -3831,11 +3861,9 @@ private PackageParser.Package scanPackageLI(PackageParser.Package pkg,
38313861
|| (scanMode&SCAN_BOOTING) != 0)) {
38323862
// If this is a system app, we can at least delete its
38333863
// current data so the application will still work.
3834-
int ret = mInstaller.remove(pkgName, 0);
3864+
int ret = removeDataDirsLI(pkgName);
38353865
if (ret >= 0) {
38363866
// TODO: Kill the processes first
3837-
// Remove the data directories for all users
3838-
sUserManager.removePackageForAllUsers(pkgName);
38393867
// Old data gone!
38403868
String prefix = (parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0
38413869
? "System package " : "Third party package ";
@@ -3847,8 +3875,7 @@ private PackageParser.Package scanPackageLI(PackageParser.Package pkg,
38473875
recovered = true;
38483876

38493877
// And now re-install the app.
3850-
ret = mInstaller.install(pkgName, pkg.applicationInfo.uid,
3851-
pkg.applicationInfo.uid);
3878+
ret = createDataDirsLI(pkgName, pkg.applicationInfo.uid);
38523879
if (ret == -1) {
38533880
// Ack should not happen!
38543881
msg = prefix + pkg.packageName
@@ -3857,9 +3884,6 @@ private PackageParser.Package scanPackageLI(PackageParser.Package pkg,
38573884
mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
38583885
return null;
38593886
}
3860-
// Create data directories for all users
3861-
sUserManager.installPackageForAllUsers(pkgName,
3862-
pkg.applicationInfo.uid);
38633887
}
38643888
if (!recovered) {
38653889
mHasSystemUidErrors = true;
@@ -3897,15 +3921,12 @@ private PackageParser.Package scanPackageLI(PackageParser.Package pkg,
38973921
Log.v(TAG, "Want this data dir: " + dataPath);
38983922
}
38993923
//invoke installer to do the actual installation
3900-
int ret = mInstaller.install(pkgName, pkg.applicationInfo.uid,
3901-
pkg.applicationInfo.uid);
3924+
int ret = createDataDirsLI(pkgName, pkg.applicationInfo.uid);
39023925
if (ret < 0) {
39033926
// Error from installer
39043927
mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
39053928
return null;
39063929
}
3907-
// Create data directories for all users
3908-
sUserManager.installPackageForAllUsers(pkgName, pkg.applicationInfo.uid);
39093930

39103931
if (dataPath.exists()) {
39113932
pkg.applicationInfo.dataDir = dataPath.getPath();
@@ -5078,6 +5099,9 @@ protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter,
50785099
}
50795100
ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags,
50805101
ps.readUserState(userId), userId);
5102+
if (si == null) {
5103+
return null;
5104+
}
50815105
final ResolveInfo res = new ResolveInfo();
50825106
res.serviceInfo = si;
50835107
if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
@@ -7819,15 +7843,7 @@ private void removePackageDataLI(PackageParser.Package p, PackageRemovedInfo out
78197843
}
78207844
}
78217845
if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
7822-
int retCode = mInstaller.remove(packageName, 0);
7823-
if (retCode < 0) {
7824-
Slog.w(TAG, "Couldn't remove app data or cache directory for package: "
7825-
+ packageName + ", retcode=" + retCode);
7826-
// we don't consider this to be a failure of the core package deletion
7827-
} else {
7828-
// TODO: Kill the processes first
7829-
sUserManager.removePackageForAllUsers(packageName);
7830-
}
7846+
removeDataDirsLI(packageName);
78317847
schedulePackageCleaning(packageName, UserHandle.USER_ALL, true);
78327848
}
78337849
// writer
@@ -9742,15 +9758,36 @@ public int getInstallLocation() {
97429758
}
97439759

97449760
/** Called by UserManagerService */
9745-
void cleanUpUser(int userHandle) {
9761+
void cleanUpUserLILPw(int userHandle) {
97469762
// Disable all the packages for the user first
9747-
synchronized (mPackages) {
9748-
Set<Entry<String, PackageSetting>> entries = mSettings.mPackages.entrySet();
9749-
for (Entry<String, PackageSetting> entry : entries) {
9750-
entry.getValue().removeUser(userHandle);
9751-
}
9752-
if (mDirtyUsers.remove(userHandle));
9753-
mSettings.removeUserLPr(userHandle);
9763+
Set<Entry<String, PackageSetting>> entries = mSettings.mPackages.entrySet();
9764+
for (Entry<String, PackageSetting> entry : entries) {
9765+
entry.getValue().removeUser(userHandle);
9766+
}
9767+
if (mDirtyUsers.remove(userHandle));
9768+
mSettings.removeUserLPr(userHandle);
9769+
if (mInstaller != null) {
9770+
// Technically, we shouldn't be doing this with the package lock
9771+
// held. However, this is very rare, and there is already so much
9772+
// other disk I/O going on, that we'll let it slide for now.
9773+
mInstaller.removeUserDataDirs(userHandle);
9774+
}
9775+
}
9776+
9777+
/** Called by UserManagerService */
9778+
void createNewUserLILPw(int userHandle, File path) {
9779+
if (mInstaller != null) {
9780+
path.mkdir();
9781+
FileUtils.setPermissions(path.toString(), FileUtils.S_IRWXU | FileUtils.S_IRWXG
9782+
| FileUtils.S_IXOTH, -1, -1);
9783+
for (PackageSetting ps : mSettings.mPackages.values()) {
9784+
// Only system apps are initially installed.
9785+
ps.setInstalled((ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) != 0, userHandle);
9786+
// Need to create a data directory for all apps under this user.
9787+
mInstaller.createUserData(ps.name,
9788+
UserHandle.getUid(userHandle, ps.appId), userHandle);
9789+
}
9790+
mSettings.writePackageRestrictionsLPr(userHandle);
97549791
}
97559792
}
97569793

services/java/com/android/server/pm/Settings.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2476,7 +2476,7 @@ boolean setPackageStoppedStateLPw(String packageName, boolean stopped,
24762476
private List<UserInfo> getAllUsers() {
24772477
long id = Binder.clearCallingIdentity();
24782478
try {
2479-
return UserManagerService.getInstance(mContext).getUsers();
2479+
return UserManagerService.getInstance().getUsers();
24802480
} catch (NullPointerException npe) {
24812481
// packagemanager not yet initialized
24822482
} finally {

0 commit comments

Comments
 (0)