Fix race condition in PackageManager.
When Google Play installs 2 apps concurrently (e.g.
personal and work profile) PackageManager can hit a
race condition when connection to media container has
not yet been established but the MCS_BOUND event is
triggered from MCS_UNBIND.
Detailed step by step scenario:
1. package1 comes in
2. INIT_COPY (initiate bind, add pending install)
3. onServiceConnected triggers (MSC_BOUND)
4. MSC_BOUND, process pending package and schedule MSC_UNBIND
5. MSC_UNBIND is triggered once the package is verified
6. service is diconnected
7. package2 comes in
8. INIT_COPY (initiate bind, add pending install)
9. MSC_UNBIND scheduled at step 4
10. MSC_UNBIND sees that there is a pending package,
schedules MSC_BIND
11. MSC_BIND arrives before service is connected and we fail.
Solution: do not fail if we wait for connection.
Bug: 21849046
Change-Id: I39928e1efc81ba64e45c622cc08cb786801d6569
This commit is contained in:
@@ -866,7 +866,7 @@ public class PackageManagerService extends IPackageManager.Stub {
|
||||
public void onServiceDisconnected(ComponentName name) {
|
||||
if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Recordkeeping of restore-after-install operations that are currently in flight
|
||||
// between the Package Manager and the Backup Manager
|
||||
@@ -878,7 +878,8 @@ public class PackageManagerService extends IPackageManager.Stub {
|
||||
args = _a;
|
||||
res = _r;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>();
|
||||
int mNextInstallToken = 1; // nonzero; will be wrapped back to 1 when ++ overflows
|
||||
|
||||
@@ -1104,13 +1105,18 @@ public class PackageManagerService extends IPackageManager.Stub {
|
||||
mContainerService = (IMediaContainerService) msg.obj;
|
||||
}
|
||||
if (mContainerService == null) {
|
||||
// Something seriously wrong. Bail out
|
||||
Slog.e(TAG, "Cannot bind to media container service");
|
||||
for (HandlerParams params : mPendingInstalls) {
|
||||
// Indicate service bind error
|
||||
params.serviceError();
|
||||
if (!mBound) {
|
||||
// Something seriously wrong since we are not bound and we are not
|
||||
// waiting for connection. Bail out.
|
||||
Slog.e(TAG, "Cannot bind to media container service");
|
||||
for (HandlerParams params : mPendingInstalls) {
|
||||
// Indicate service bind error
|
||||
params.serviceError();
|
||||
}
|
||||
mPendingInstalls.clear();
|
||||
} else {
|
||||
Slog.w(TAG, "Waiting to connect to media container service");
|
||||
}
|
||||
mPendingInstalls.clear();
|
||||
} else if (mPendingInstalls.size() > 0) {
|
||||
HandlerParams params = mPendingInstalls.get(0);
|
||||
if (params != null) {
|
||||
|
||||
Reference in New Issue
Block a user