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

Commit a99ff5fa authored by Winson Chiu's avatar Winson Chiu Committed by Android (Google) Code Review
Browse files

Merge changes I689ec523,Id249a185 into qt-dev

* changes:
  Delayed install completion
  Defer post-install resource clean up for 5 seconds
parents c755a232 23863be9
Loading
Loading
Loading
Loading
+14 −3
Original line number Diff line number Diff line
@@ -5719,14 +5719,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;
@@ -5737,8 +5741,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,
@@ -5770,6 +5774,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 */
+86 −12
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<>();
@@ -1319,6 +1322,11 @@ public class PackageManagerService extends IPackageManager.Stub
    static final int INSTANT_APP_RESOLUTION_PHASE_TWO = 20;
    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 = 3 * 1000;
    static final int DEFERRED_NO_KILL_INSTALL_OBSERVER_DELAY_MS = 500;
    static final int WRITE_SETTINGS_DELAY = 10*1000;  // 10 seconds
@@ -1525,6 +1533,20 @@ public class PackageManagerService extends IPackageManager.Stub
                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "postInstall", msg.arg1);
                } break;
                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);
                    synchronized (mPackages) {
@@ -1791,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);
@@ -1819,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
@@ -2029,11 +2052,18 @@ public class PackageManagerService extends IPackageManager.Stub
                    getUnknownSourcesSettings());
            // Remove the replaced package's older resources safely now
            // We delete after a gc for applications  on sdcard.
            if (res.removedInfo != null && res.removedInfo.args != null) {
                Runtime.getRuntime().gc();
            InstallArgs args = res.removedInfo != null ? res.removedInfo.args : null;
            if (args != null) {
                if (!killApp) {
                    // If we didn't kill the app, defer the deletion of code/resource files, since
                    // they may still be in use by the running application. This mitigates problems
                    // in cases where resources or code is loaded by a new Activity before
                    // ApplicationInfo changes have propagated to all application threads.
                    scheduleDeferredNoKillPostDelete(args);
                } else {
                    synchronized (mInstallLock) {
                    res.removedInfo.args.doPostDeleteLI(true);
                        args.doPostDeleteLI(true);
                    }
                }
            } else {
                // Force a gc to clear up things. Ask for a background one, it's fine to go on
@@ -2056,18 +2086,62 @@ 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.");
            }
        }
    }
    private void scheduleDeferredNoKillPostDelete(InstallArgs args) {
        Message message = mHandler.obtainMessage(DEFERRED_NO_KILL_POST_DELETE, args);
        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.