Mitigate the races during installation
When handling post-install during the installation process, some tasks are posted to PackageHandler and be executed after notifying the install observer (install initiator). The task includes force- stopping the package. If the install observer starts the app right after being notified, the ongoing force-stop will kill the process. The race happens. To mitigate the potential race, We should defer the notification until these tasks are done. Bug: 165012101 Test: atest -p services/core/java/com/android/server/pm Change-Id: Ia6b32f72f3d75b8a40c42e11d21f21c459db5299
This commit is contained in:
@@ -655,6 +655,11 @@ public abstract class PackageManagerInternal implements PackageSettingsSnapshotP
|
|||||||
*/
|
*/
|
||||||
public abstract void notifyPackageUse(String packageName, int reason);
|
public abstract void notifyPackageUse(String packageName, int reason);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notify the package is force stopped.
|
||||||
|
*/
|
||||||
|
public abstract void onPackageProcessKilledForUninstall(String packageName);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a package object for the given package name.
|
* Returns a package object for the given package name.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -13563,6 +13563,8 @@ public class ActivityManagerService extends IActivityManager.Stub
|
|||||||
intent.getIntExtra(Intent.EXTRA_UID, -1)),
|
intent.getIntExtra(Intent.EXTRA_UID, -1)),
|
||||||
false, true, true, false, fullUninstall, userId,
|
false, true, true, false, fullUninstall, userId,
|
||||||
removed ? "pkg removed" : "pkg changed");
|
removed ? "pkg removed" : "pkg changed");
|
||||||
|
getPackageManagerInternal()
|
||||||
|
.onPackageProcessKilledForUninstall(ssp);
|
||||||
} else {
|
} else {
|
||||||
// Kill any app zygotes always, since they can't fork new
|
// Kill any app zygotes always, since they can't fork new
|
||||||
// processes with references to the old code
|
// processes with references to the old code
|
||||||
|
|||||||
@@ -2885,9 +2885,13 @@ final class InstallPackageHelper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final boolean deferInstallObserver = succeeded && update && !killApp;
|
final boolean deferInstallObserver = succeeded && update;
|
||||||
if (deferInstallObserver) {
|
if (deferInstallObserver) {
|
||||||
mPm.scheduleDeferredNoKillInstallObserver(res, installObserver);
|
if (killApp) {
|
||||||
|
mPm.scheduleDeferredPendingKillInstallObserver(res, installObserver);
|
||||||
|
} else {
|
||||||
|
mPm.scheduleDeferredNoKillInstallObserver(res, installObserver);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
mPm.notifyInstallObserver(res, installObserver);
|
mPm.notifyInstallObserver(res, installObserver);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import static com.android.server.pm.PackageManagerService.DEBUG_INSTALL;
|
|||||||
import static com.android.server.pm.PackageManagerService.DEFAULT_UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD;
|
import static com.android.server.pm.PackageManagerService.DEFAULT_UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD;
|
||||||
import static com.android.server.pm.PackageManagerService.DEFERRED_NO_KILL_INSTALL_OBSERVER;
|
import static com.android.server.pm.PackageManagerService.DEFERRED_NO_KILL_INSTALL_OBSERVER;
|
||||||
import static com.android.server.pm.PackageManagerService.DEFERRED_NO_KILL_POST_DELETE;
|
import static com.android.server.pm.PackageManagerService.DEFERRED_NO_KILL_POST_DELETE;
|
||||||
|
import static com.android.server.pm.PackageManagerService.DEFERRED_PENDING_KILL_INSTALL_OBSERVER;
|
||||||
import static com.android.server.pm.PackageManagerService.DOMAIN_VERIFICATION;
|
import static com.android.server.pm.PackageManagerService.DOMAIN_VERIFICATION;
|
||||||
import static com.android.server.pm.PackageManagerService.ENABLE_ROLLBACK_STATUS;
|
import static com.android.server.pm.PackageManagerService.ENABLE_ROLLBACK_STATUS;
|
||||||
import static com.android.server.pm.PackageManagerService.ENABLE_ROLLBACK_TIMEOUT;
|
import static com.android.server.pm.PackageManagerService.ENABLE_ROLLBACK_TIMEOUT;
|
||||||
@@ -126,10 +127,12 @@ final class PackageHandler extends Handler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case DEFERRED_NO_KILL_INSTALL_OBSERVER: {
|
case DEFERRED_NO_KILL_INSTALL_OBSERVER:
|
||||||
String packageName = (String) msg.obj;
|
case DEFERRED_PENDING_KILL_INSTALL_OBSERVER: {
|
||||||
|
final String packageName = (String) msg.obj;
|
||||||
if (packageName != null) {
|
if (packageName != null) {
|
||||||
mPm.notifyInstallObserver(packageName);
|
final boolean killApp = msg.what == DEFERRED_PENDING_KILL_INSTALL_OBSERVER;
|
||||||
|
mPm.notifyInstallObserver(packageName, killApp);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case WRITE_SETTINGS: {
|
case WRITE_SETTINGS: {
|
||||||
|
|||||||
@@ -843,6 +843,9 @@ public class PackageManagerService extends IPackageManager.Stub
|
|||||||
private final Map<String, Pair<PackageInstalledInfo, IPackageInstallObserver2>>
|
private final Map<String, Pair<PackageInstalledInfo, IPackageInstallObserver2>>
|
||||||
mNoKillInstallObservers = Collections.synchronizedMap(new HashMap<>());
|
mNoKillInstallObservers = Collections.synchronizedMap(new HashMap<>());
|
||||||
|
|
||||||
|
private final Map<String, Pair<PackageInstalledInfo, IPackageInstallObserver2>>
|
||||||
|
mPendingKillInstallObservers = Collections.synchronizedMap(new HashMap<>());
|
||||||
|
|
||||||
// Internal interface for permission manager
|
// Internal interface for permission manager
|
||||||
final PermissionManagerServiceInternal mPermissionManager;
|
final PermissionManagerServiceInternal mPermissionManager;
|
||||||
|
|
||||||
@@ -890,9 +893,11 @@ public class PackageManagerService extends IPackageManager.Stub
|
|||||||
static final int CHECK_PENDING_INTEGRITY_VERIFICATION = 26;
|
static final int CHECK_PENDING_INTEGRITY_VERIFICATION = 26;
|
||||||
static final int DOMAIN_VERIFICATION = 27;
|
static final int DOMAIN_VERIFICATION = 27;
|
||||||
static final int PRUNE_UNUSED_STATIC_SHARED_LIBRARIES = 28;
|
static final int PRUNE_UNUSED_STATIC_SHARED_LIBRARIES = 28;
|
||||||
|
static final int DEFERRED_PENDING_KILL_INSTALL_OBSERVER = 29;
|
||||||
|
|
||||||
static final int DEFERRED_NO_KILL_POST_DELETE_DELAY_MS = 3 * 1000;
|
static final int DEFERRED_NO_KILL_POST_DELETE_DELAY_MS = 3 * 1000;
|
||||||
private static final int DEFERRED_NO_KILL_INSTALL_OBSERVER_DELAY_MS = 500;
|
private static final int DEFERRED_NO_KILL_INSTALL_OBSERVER_DELAY_MS = 500;
|
||||||
|
private static final int DEFERRED_PENDING_KILL_INSTALL_OBSERVER_DELAY_MS = 1000;
|
||||||
|
|
||||||
static final int WRITE_SETTINGS_DELAY = 10*1000; // 10 seconds
|
static final int WRITE_SETTINGS_DELAY = 10*1000; // 10 seconds
|
||||||
|
|
||||||
@@ -1174,13 +1179,14 @@ public class PackageManagerService extends IPackageManager.Stub
|
|||||||
ArraySet<String> packagesToNotify =
|
ArraySet<String> packagesToNotify =
|
||||||
mComputer.getNotifyPackagesForReplacedReceived(packages);
|
mComputer.getNotifyPackagesForReplacedReceived(packages);
|
||||||
for (int index = 0; index < packagesToNotify.size(); index++) {
|
for (int index = 0; index < packagesToNotify.size(); index++) {
|
||||||
notifyInstallObserver(packagesToNotify.valueAt(index));
|
notifyInstallObserver(packagesToNotify.valueAt(index), false /* killApp */);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void notifyInstallObserver(String packageName) {
|
void notifyInstallObserver(String packageName, boolean killApp) {
|
||||||
Pair<PackageInstalledInfo, IPackageInstallObserver2> pair =
|
final Pair<PackageInstalledInfo, IPackageInstallObserver2> pair =
|
||||||
mNoKillInstallObservers.remove(packageName);
|
killApp ? mPendingKillInstallObservers.remove(packageName)
|
||||||
|
: mNoKillInstallObservers.remove(packageName);
|
||||||
|
|
||||||
if (pair != null) {
|
if (pair != null) {
|
||||||
notifyInstallObserver(pair.first, pair.second);
|
notifyInstallObserver(pair.first, pair.second);
|
||||||
@@ -1219,6 +1225,15 @@ public class PackageManagerService extends IPackageManager.Stub
|
|||||||
delay ? getPruneUnusedSharedLibrariesDelay() : 0);
|
delay ? getPruneUnusedSharedLibrariesDelay() : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void scheduleDeferredPendingKillInstallObserver(PackageInstalledInfo info,
|
||||||
|
IPackageInstallObserver2 observer) {
|
||||||
|
final String packageName = info.mPkg.getPackageName();
|
||||||
|
mPendingKillInstallObservers.put(packageName, Pair.create(info, observer));
|
||||||
|
final Message message = mHandler.obtainMessage(DEFERRED_PENDING_KILL_INSTALL_OBSERVER,
|
||||||
|
packageName);
|
||||||
|
mHandler.sendMessageDelayed(message, DEFERRED_PENDING_KILL_INSTALL_OBSERVER_DELAY_MS);
|
||||||
|
}
|
||||||
|
|
||||||
private static long getPruneUnusedSharedLibrariesDelay() {
|
private static long getPruneUnusedSharedLibrariesDelay() {
|
||||||
return SystemProperties.getLong("debug.pm.prune_unused_shared_libraries_delay",
|
return SystemProperties.getLong("debug.pm.prune_unused_shared_libraries_delay",
|
||||||
PRUNE_UNUSED_SHARED_LIBRARIES_DELAY);
|
PRUNE_UNUSED_SHARED_LIBRARIES_DELAY);
|
||||||
@@ -7499,6 +7514,12 @@ public class PackageManagerService extends IPackageManager.Stub
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPackageProcessKilledForUninstall(String packageName) {
|
||||||
|
mHandler.post(() -> PackageManagerService.this.notifyInstallObserver(packageName,
|
||||||
|
true /* killApp */));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SparseArray<String> getAppsWithSharedUserIds() {
|
public SparseArray<String> getAppsWithSharedUserIds() {
|
||||||
return mComputer.getAppsWithSharedUserIds();
|
return mComputer.getAppsWithSharedUserIds();
|
||||||
|
|||||||
Reference in New Issue
Block a user