Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 23863be9 authored by Winson's avatar Winson Committed by Winson Chiu
Browse files

Delayed install completion

This change is an attempt at delaying the install complete callback
to the installer on a DONT_KILL install until the package indicates
that it as completed updating its classpath with the new APKs.

Bug: 80269951
Bug: 109751013

Test: manual test of dynamic delivery/instant apps

Merged-In: I689ec523522da37987cff9b1a67eaae9e5633ffb
Change-Id: I689ec523522da37987cff9b1a67eaae9e5633ffb
(cherry picked from commit abfc054c)
parent a9bf579e
Loading
Loading
Loading
Loading
+14 −3
Original line number Diff line number Diff line
@@ -5718,14 +5718,18 @@ public final class ActivityThread extends ClientTransactionHandler {
                if (packages == null) {
                    break;
                }

                List<String> packagesHandled = new ArrayList<>();

                synchronized (mResourcesManager) {
                    for (int i = packages.length - 1; i >= 0; i--) {
                        WeakReference<LoadedApk> ref = mPackages.get(packages[i]);
                        String packageName = packages[i];
                        WeakReference<LoadedApk> ref = mPackages.get(packageName);
                        LoadedApk pkgInfo = ref != null ? ref.get() : null;
                        if (pkgInfo != null) {
                            hasPkgInfo = true;
                        } else {
                            ref = mResourcePackages.get(packages[i]);
                            ref = mResourcePackages.get(packageName);
                            pkgInfo = ref != null ? ref.get() : null;
                            if (pkgInfo != null) {
                                hasPkgInfo = true;
@@ -5736,8 +5740,8 @@ public final class ActivityThread extends ClientTransactionHandler {
                        // Adjust it's internal references to the application info and
                        // resources.
                        if (pkgInfo != null) {
                            packagesHandled.add(packageName);
                            try {
                                final String packageName = packages[i];
                                final ApplicationInfo aInfo =
                                        sPackageManager.getApplicationInfo(
                                                packageName,
@@ -5769,6 +5773,13 @@ public final class ActivityThread extends ClientTransactionHandler {
                        }
                    }
                }

                try {
                    getPackageManager().notifyPackagesReplacedReceived(
                            packagesHandled.toArray(new String[0]));
                } catch (RemoteException ignored) {
                }

                break;
            }
        }
+2 −0
Original line number Diff line number Diff line
@@ -770,4 +770,6 @@ interface IPackageManager {
    int getRuntimePermissionsVersion(int userId);

    void setRuntimePermissionsVersion(int version, int userId);

    void notifyPackagesReplacedReceived(in String[] packages);
}
+13 −0
Original line number Diff line number Diff line
@@ -3172,15 +3172,28 @@ public final class ProcessList {

    @GuardedBy("mService")
    void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
        boolean foundProcess = false;
        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
            ProcessRecord r = mLruProcesses.get(i);
            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
                try {
                    for (int index = packages.length - 1; index >= 0 && !foundProcess; index--) {
                        if (packages[index].equals(r.info.packageName)) {
                            foundProcess = true;
                        }
                    }
                    r.thread.dispatchPackageBroadcast(cmd, packages);
                } catch (RemoteException ex) {
                }
            }
        }

        if (!foundProcess) {
            try {
                AppGlobals.getPackageManager().notifyPackagesReplacedReceived(packages);
            } catch (RemoteException ignored) {
            }
        }
    }

    /** Returns the uid's process state or PROCESS_STATE_NONEXISTENT if not running */
+62 −9
Original line number Diff line number Diff line
@@ -952,6 +952,9 @@ public class PackageManagerService extends IPackageManager.Stub
    ActivityInfo mInstantAppInstallerActivity;
    final ResolveInfo mInstantAppInstallerInfo = new ResolveInfo();
    private final Map<String, Pair<PackageInstalledInfo, IPackageInstallObserver2>>
            mNoKillInstallObservers = Collections.synchronizedMap(new HashMap<>());
    final SparseArray<IntentFilterVerificationState> mIntentFilterVerificationStates
            = new SparseArray<>();
@@ -1320,8 +1323,10 @@ public class PackageManagerService extends IPackageManager.Stub
    static final int ENABLE_ROLLBACK_STATUS = 21;
    static final int ENABLE_ROLLBACK_TIMEOUT = 22;
    static final int DEFERRED_NO_KILL_POST_DELETE = 23;
    static final int DEFERRED_NO_KILL_INSTALL_OBSERVER = 24;
    static final int DEFERRED_NO_KILL_POST_DELETE_DELAY_MS = 5 * 1000;
    static final int DEFERRED_NO_KILL_POST_DELETE_DELAY_MS = 3 * 1000;
    static final int DEFERRED_NO_KILL_INSTALL_OBSERVER_DELAY_MS = 500;
    static final int WRITE_SETTINGS_DELAY = 10*1000;  // 10 seconds
@@ -1531,8 +1536,16 @@ public class PackageManagerService extends IPackageManager.Stub
                case DEFERRED_NO_KILL_POST_DELETE: {
                    synchronized (mInstallLock) {
                        InstallArgs args = (InstallArgs) msg.obj;
                        if (args != null) {
                            args.doPostDeleteLI(true);
                        }
                    }
                } break;
                case DEFERRED_NO_KILL_INSTALL_OBSERVER: {
                    String packageName = (String) msg.obj;
                    if (packageName != null) {
                        notifyInstallObserver(packageName);
                    }
                } break;
                case WRITE_SETTINGS: {
                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
@@ -1800,7 +1813,10 @@ public class PackageManagerService extends IPackageManager.Stub
            String[] grantedPermissions, List<String> whitelistedRestrictedPermissions,
            boolean launchedForRestore, String installerPackage,
            IPackageInstallObserver2 installObserver) {
        if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
        final boolean succeeded = res.returnCode == PackageManager.INSTALL_SUCCEEDED;
        final boolean update = res.removedInfo != null && res.removedInfo.removedPackage != null;
        if (succeeded) {
            // Send the removed broadcasts
            if (res.removedInfo != null) {
                res.removedInfo.sendPackageRemovedBroadcasts(killApp);
@@ -1828,8 +1844,6 @@ public class PackageManagerService extends IPackageManager.Stub
                        mPermissionCallback);
            }
            final boolean update = res.removedInfo != null
                    && res.removedInfo.removedPackage != null;
            final String installerPackageName =
                    res.installerPackageName != null
                            ? res.installerPackageName
@@ -2072,12 +2086,43 @@ public class PackageManagerService extends IPackageManager.Stub
            }
        }
        // If someone is watching installs - notify them
        final boolean deferInstallObserver = succeeded && update && !killApp;
        if (deferInstallObserver) {
            scheduleDeferredNoKillInstallObserver(res, installObserver);
        } else {
            notifyInstallObserver(res, installObserver);
        }
    }
    @Override
    public void notifyPackagesReplacedReceived(String[] packages) {
        final int callingUid = Binder.getCallingUid();
        final int callingUserId = UserHandle.getUserId(callingUid);
        for (String packageName : packages) {
            PackageSetting setting = mSettings.mPackages.get(packageName);
            if (setting != null && filterAppAccessLPr(setting, callingUid, callingUserId)) {
                notifyInstallObserver(packageName);
            }
        }
    }
    private void notifyInstallObserver(String packageName) {
        Pair<PackageInstalledInfo, IPackageInstallObserver2> pair =
                mNoKillInstallObservers.remove(packageName);
        if (pair != null) {
            notifyInstallObserver(pair.first, pair.second);
        }
    }
    private void notifyInstallObserver(PackageInstalledInfo info,
            IPackageInstallObserver2 installObserver) {
        if (installObserver != null) {
            try {
                Bundle extras = extrasForInstallResult(res);
                installObserver.onPackageInstalled(res.name, res.returnCode,
                        res.returnMsg, extras);
                Bundle extras = extrasForInstallResult(info);
                installObserver.onPackageInstalled(info.name, info.returnCode,
                        info.returnMsg, extras);
            } catch (RemoteException e) {
                Slog.i(TAG, "Observer no longer exists.");
            }
@@ -2089,6 +2134,14 @@ public class PackageManagerService extends IPackageManager.Stub
        mHandler.sendMessageDelayed(message, DEFERRED_NO_KILL_POST_DELETE_DELAY_MS);
    }
    private void scheduleDeferredNoKillInstallObserver(PackageInstalledInfo info,
            IPackageInstallObserver2 observer) {
        String packageName = info.pkg.packageName;
        mNoKillInstallObservers.put(packageName, Pair.create(info, observer));
        Message message = mHandler.obtainMessage(DEFERRED_NO_KILL_INSTALL_OBSERVER, packageName);
        mHandler.sendMessageDelayed(message, DEFERRED_NO_KILL_INSTALL_OBSERVER_DELAY_MS);
    }
    /**
     * Gets the type of the external storage a package is installed on.
     * @param packageVolume The storage volume of the package.