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

Commit 1d0f68c5 authored by Alex Buynytskyy's avatar Alex Buynytskyy Committed by Android (Google) Code Review
Browse files

Merge "Offload IO to Handler thread."

parents 0153dd58 3ddd1a42
Loading
Loading
Loading
Loading
+1 −5
Original line number Diff line number Diff line
@@ -36,7 +36,6 @@ import static com.android.server.pm.PackageManagerService.PRUNE_UNUSED_STATIC_SH
import static com.android.server.pm.PackageManagerService.SEND_PENDING_BROADCAST;
import static com.android.server.pm.PackageManagerService.TAG;
import static com.android.server.pm.PackageManagerService.WRITE_PACKAGE_LIST;
import static com.android.server.pm.PackageManagerService.WRITE_PACKAGE_RESTRICTIONS;
import static com.android.server.pm.PackageManagerService.WRITE_SETTINGS;

import android.content.Intent;
@@ -119,10 +118,7 @@ final class PackageHandler extends Handler {
                }
            } break;
            case WRITE_SETTINGS: {
                mPm.writeSettings();
            } break;
            case WRITE_PACKAGE_RESTRICTIONS: {
                mPm.writePendingRestrictions();
                mPm.writeSettings(/*sync=*/false);
            } break;
            case WRITE_PACKAGE_LIST: {
                mPm.writePackageList(msg.arg1);
+52 −16
Original line number Diff line number Diff line
@@ -558,6 +558,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService
    static final char RANDOM_CODEPATH_PREFIX = '-';

    final Handler mHandler;
    final Handler mBackgroundHandler;

    final ProcessLoggingHandler mProcessLoggingHandler;

@@ -873,7 +874,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService
    // public static final int UNUSED = 5;
    static final int POST_INSTALL = 9;
    static final int WRITE_SETTINGS = 13;
    static final int WRITE_PACKAGE_RESTRICTIONS = 14;
    static final int WRITE_DIRTY_PACKAGE_RESTRICTIONS = 14;
    static final int PACKAGE_VERIFIED = 15;
    static final int CHECK_PENDING_VERIFICATION = 16;
    // public static final int UNUSED = 17;
@@ -890,6 +891,8 @@ public class PackageManagerService implements PackageSender, TestUtilityService
    static final int PRUNE_UNUSED_STATIC_SHARED_LIBRARIES = 28;
    static final int DEFERRED_PENDING_KILL_INSTALL_OBSERVER = 29;

    static final int WRITE_USER_PACKAGE_RESTRICTIONS = 30;

    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_PENDING_KILL_INSTALL_OBSERVER_DELAY_MS = 1000;
@@ -1397,28 +1400,33 @@ public class PackageManagerService implements PackageSender, TestUtilityService
                mDirtyUsers.add(userId);
            }
        }
        if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {
            mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY);
        if (!mBackgroundHandler.hasMessages(WRITE_DIRTY_PACKAGE_RESTRICTIONS)) {
            mBackgroundHandler.sendMessageDelayed(
                    mBackgroundHandler.obtainMessage(WRITE_DIRTY_PACKAGE_RESTRICTIONS, this),
                    WRITE_SETTINGS_DELAY);
        }
    }

    void writePendingRestrictions() {
        final Integer[] dirtyUsers;
        synchronized (mLock) {
            mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS);
            mBackgroundHandler.removeMessages(WRITE_DIRTY_PACKAGE_RESTRICTIONS);
            synchronized (mDirtyUsers) {
                for (int userId : mDirtyUsers) {
                    mSettings.writePackageRestrictionsLPr(userId);
                if (mDirtyUsers.isEmpty()) {
                    return;
                }
                dirtyUsers = mDirtyUsers.toArray(Integer[]::new);
                mDirtyUsers.clear();
            }
        }
        mSettings.writePackageRestrictions(dirtyUsers);
    }

    void writeSettings() {
    void writeSettings(boolean sync) {
        synchronized (mLock) {
            mHandler.removeMessages(WRITE_SETTINGS);
            mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS);
            writeSettingsLPrTEMP();
            mBackgroundHandler.removeMessages(WRITE_DIRTY_PACKAGE_RESTRICTIONS);
            writeSettingsLPrTEMP(sync);
            synchronized (mDirtyUsers) {
                mDirtyUsers.clear();
            }
@@ -1432,6 +1440,25 @@ public class PackageManagerService implements PackageSender, TestUtilityService
        }
    }

    private static final Handler.Callback BACKGROUND_HANDLER_CALLBACK = new Handler.Callback() {
        @Override
        public boolean handleMessage(@NonNull Message msg) {
            switch (msg.what) {
                case WRITE_DIRTY_PACKAGE_RESTRICTIONS: {
                    PackageManagerService pm = (PackageManagerService) msg.obj;
                    pm.writePendingRestrictions();
                    return true;
                }
                case WRITE_USER_PACKAGE_RESTRICTIONS: {
                    final Runnable r = (Runnable) msg.obj;
                    r.run();
                    return true;
                }
            }
            return false;
        }
    };

    public static Pair<PackageManagerService, IPackageManager> main(Context context,
            Installer installer, @NonNull DomainVerificationService domainVerificationService,
            boolean factoryTest) {
@@ -1446,7 +1473,8 @@ public class PackageManagerService implements PackageSender, TestUtilityService
        HandlerThread backgroundThread = new ServiceThread("PackageManagerBg",
                Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
        backgroundThread.start();
        Handler backgroundHandler = new Handler(backgroundThread.getLooper());
        Handler backgroundHandler = new Handler(backgroundThread.getLooper(),
                BACKGROUND_HANDLER_CALLBACK);

        PackageManagerServiceInjector injector = new PackageManagerServiceInjector(
                context, lock, installer, installLock, new PackageAbiHelperImpl(),
@@ -1460,7 +1488,8 @@ public class PackageManagerService implements PackageSender, TestUtilityService
                (i, pm) -> new Settings(Environment.getDataDirectory(),
                        RuntimePermissionsPersistence.createInstance(),
                        i.getPermissionManagerServiceInternal(),
                        domainVerificationService, backgroundHandler, lock),
                        domainVerificationService, backgroundHandler,
                        lock),
                (i, pm) -> AppsFilterImpl.create(i,
                        i.getLocalService(PackageManagerInternal.class)),
                (i, pm) -> (PlatformCompat) ServiceManager.getService("platform_compat"),
@@ -1638,6 +1667,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService
        mUserNeedsBadging = new UserNeedsBadgingCache(mUserManager);
        mDomainVerificationManager = injector.getDomainVerificationManagerInternal();
        mHandler = injector.getHandler();
        mBackgroundHandler = injector.getBackgroundHandler();
        mSharedLibraries = injector.getSharedLibrariesImpl();

        mApexManager = testParams.apexManager;
@@ -1828,6 +1858,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService
        mMoveCallbacks = new MovePackageHelper.MoveCallbacks(FgThread.get().getLooper());
        mViewCompiler = injector.getViewCompiler();
        mSharedLibraries = mInjector.getSharedLibrariesImpl();
        mBackgroundHandler = injector.getBackgroundHandler();

        mContext.getSystemService(DisplayManager.class)
                .getDisplay(Display.DEFAULT_DISPLAY).getMetrics(mMetrics);
@@ -2902,9 +2933,9 @@ public class PackageManagerService implements PackageSender, TestUtilityService
            mPackageUsage.writeNow(mSettings.getPackagesLocked());

            if (mHandler.hasMessages(WRITE_SETTINGS)
                    || mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)
                    || mBackgroundHandler.hasMessages(WRITE_DIRTY_PACKAGE_RESTRICTIONS)
                    || mHandler.hasMessages(WRITE_PACKAGE_LIST)) {
                writeSettings();
                writeSettings(/*sync=*/true);
            }
        }
    }
@@ -3968,7 +3999,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService
        synchronized (mDirtyUsers) {
            mDirtyUsers.remove(userId);
            if (mDirtyUsers.isEmpty()) {
                mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS);
                mBackgroundHandler.removeMessages(WRITE_DIRTY_PACKAGE_RESTRICTIONS);
            }
        }
    }
@@ -6867,9 +6898,14 @@ public class PackageManagerService implements PackageSender, TestUtilityService
     * TODO: In the meantime, can this be moved to a schedule call?
     * TODO(b/182523293): This should be removed once we finish migration of permission storage.
     */
    void writeSettingsLPrTEMP() {
    void writeSettingsLPrTEMP(boolean sync) {
        mPermissionManager.writeLegacyPermissionsTEMP(mSettings.mPermissions);
        mSettings.writeLPr(mLiveComputer);
        mSettings.writeLPr(mLiveComputer, sync);
    }

    // Default async version.
    void writeSettingsLPrTEMP() {
        writeSettingsLPrTEMP(/*sync=*/false);
    }

    @Override
+316 −209
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import static android.os.Process.PACKAGE_INFO_GID;
import static android.os.Process.SYSTEM_UID;

import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;
import static com.android.server.pm.PackageManagerService.WRITE_USER_PACKAGE_RESTRICTIONS;
import static com.android.server.pm.SharedUidMigration.BEST_EFFORT;

import android.annotation.NonNull;
@@ -56,7 +57,6 @@ import android.net.Uri;
import android.os.Binder;
import android.os.Build;
import android.os.CreateAppDataArgs;
import android.os.Environment;
import android.os.FileUtils;
import android.os.Handler;
import android.os.Message;
@@ -376,6 +376,13 @@ public final class Settings implements Watchable, Snappable {
    /** The top level directory in configfs for sdcardfs to push the package->uid,userId mappings */
    private final File mKernelMappingFilename;

    // Lock for user package restrictions operations.
    private final Object mPackageRestrictionsLock = new Object();

    // Pending write operations.
    @GuardedBy("mPackageRestrictionsLock")
    private final SparseIntArray mPendingAsyncPackageRestrictionsWrites = new SparseIntArray();

    /** Map from package name to settings */
    @Watched
    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
@@ -1476,31 +1483,46 @@ public final class Settings implements Watchable, Snappable {
        return (userId == UserHandle.USER_ALL) ? null : mDefaultBrowserApp.removeReturnOld(userId);
    }

    private File getUserPackagesStateFile(int userId) {
        // TODO: Implement a cleaner solution when adding tests.
    private File getUserSystemDirectory(int userId) {
        // This instead of Environment.getUserSystemDirectory(userId) to support testing.
        File userDir = new File(new File(mSystemDir, "users"), Integer.toString(userId));
        return new File(userDir, "package-restrictions.xml");
        return new File(new File(mSystemDir, "users"), Integer.toString(userId));
    }

    private File getUserRuntimePermissionsFile(int userId) {
        // TODO: Implement a cleaner solution when adding tests.
        // This instead of Environment.getUserSystemDirectory(userId) to support testing.
        File userDir = new File(new File(mSystemDir, "users"), Integer.toString(userId));
        return new File(userDir, RUNTIME_PERMISSIONS_FILE_NAME);
    // The method itself does not have to be guarded, but the file does.
    @GuardedBy("mPackageRestrictionsLock")
    private File getUserPackagesStateFile(int userId) {
        return new File(getUserSystemDirectory(userId), "package-restrictions.xml");
    }

    // The method itself does not have to be guarded, but the file does.
    @GuardedBy("mPackageRestrictionsLock")
    private File getUserPackagesStateBackupFile(int userId) {
        return new File(Environment.getUserSystemDirectory(userId),
                "package-restrictions-backup.xml");
        return new File(getUserSystemDirectory(userId), "package-restrictions-backup.xml");
    }

    private File getUserRuntimePermissionsFile(int userId) {
        return new File(getUserSystemDirectory(userId), RUNTIME_PERMISSIONS_FILE_NAME);
    }

    // Default version is writing restrictions asynchronously.
    void writeAllUsersPackageRestrictionsLPr() {
        writeAllUsersPackageRestrictionsLPr(/*sync=*/false);
    }

    void writeAllUsersPackageRestrictionsLPr(boolean sync) {
        List<UserInfo> users = getAllUsers(UserManagerService.getInstance());
        if (users == null) return;

        if (sync) {
            // Cancel all pending per-user writes.
            synchronized (mPackageRestrictionsLock) {
                mPendingAsyncPackageRestrictionsWrites.clear();
            }
            mHandler.removeMessages(WRITE_USER_PACKAGE_RESTRICTIONS);
        }

        for (UserInfo user : users) {
            writePackageRestrictionsLPr(user.id);
            writePackageRestrictionsLPr(user.id, sync);
        }
    }

@@ -1691,6 +1713,8 @@ public final class Settings implements Watchable, Snappable {
            Log.i(TAG, "Reading package restrictions for user=" + userId);
        }
        FileInputStream str = null;

        synchronized (mPackageRestrictionsLock) {
            File userPackagesStateFile = getUserPackagesStateFile(userId);
            File backupFile = getUserPackagesStateBackupFile(userId);
            if (backupFile.exists()) {
@@ -1712,9 +1736,20 @@ public final class Settings implements Watchable, Snappable {
                }
            }

            if (str == null && userPackagesStateFile.exists()) {
                try {
                    str = new FileInputStream(userPackagesStateFile);
                    if (DEBUG_MU) Log.i(TAG, "Reading " + userPackagesStateFile);
                } catch (java.io.IOException e) {
                    mReadMessages.append("Error reading: " + e.toString());
                    PackageManagerService.reportSettingsProblem(Log.ERROR,
                            "Error reading settings: " + e);
                    Slog.wtf(TAG, "Error reading package manager stopped packages", e);
                }
            }
        }

        if (str == null) {
                if (!userPackagesStateFile.exists()) {
            mReadMessages.append("No stopped packages file found\n");
            PackageManagerService.reportSettingsProblem(Log.INFO,
                    "No stopped packages file; "
@@ -1745,9 +1780,8 @@ public final class Settings implements Watchable, Snappable {
            }
            return;
        }
                str = new FileInputStream(userPackagesStateFile);
                if (DEBUG_MU) Log.i(TAG, "Reading " + userPackagesStateFile);
            }

        try {
            final TypedXmlPullParser parser = Xml.resolvePullParser(str);

            int type;
@@ -2070,18 +2104,62 @@ public final class Settings implements Watchable, Snappable {
        }
    }

    // Default version is writing restrictions asynchronously.
    void writePackageRestrictionsLPr(int userId) {
        writePackageRestrictionsLPr(userId, /*sync=*/false);
    }

    void writePackageRestrictionsLPr(int userId, boolean sync) {
        invalidatePackageCache();

        final long startTime = SystemClock.uptimeMillis();

        if (sync) {
            writePackageRestrictions(userId, startTime, sync);
        } else {
            if (DEBUG_MU) {
            Log.i(TAG, "Writing package restrictions for user=" + userId);
                Log.i(TAG, "Scheduling deferred IO sync for user=" + userId);
            }
            synchronized (mPackageRestrictionsLock) {
                int pending = mPendingAsyncPackageRestrictionsWrites.get(userId, 0) + 1;
                mPendingAsyncPackageRestrictionsWrites.put(userId, pending);
            }
            Runnable r = () -> writePackageRestrictions(userId, startTime, sync);
            mHandler.obtainMessage(WRITE_USER_PACKAGE_RESTRICTIONS, r).sendToTarget();
        }
    }

    void writePackageRestrictions(Integer[] userIds) {
        invalidatePackageCache();
        final long startTime = SystemClock.uptimeMillis();
        for (int userId : userIds) {
            writePackageRestrictions(userId, startTime, /*sync=*/true);
        }
    }

    void writePackageRestrictions(int userId, long startTime, boolean sync) {
        if (DEBUG_MU) {
            Log.i(TAG, "Writing package restrictions for user=" + userId);
        }

        final File userPackagesStateFile;
        final File backupFile;
        final FileOutputStream fstr;

        synchronized (mPackageRestrictionsLock) {
            if (!sync) {
                int pending = mPendingAsyncPackageRestrictionsWrites.get(userId, 0) - 1;
                if (pending < 0) {
                    Log.i(TAG, "Cancel writing package restrictions for user=" + userId);
                    return;
                }
                mPendingAsyncPackageRestrictionsWrites.put(userId, pending);
            }

            // Keep the old stopped packages around until we know the new ones have
            // been successfully written.
        File userPackagesStateFile = getUserPackagesStateFile(userId);
        File backupFile = getUserPackagesStateBackupFile(userId);
            userPackagesStateFile = getUserPackagesStateFile(userId);
            backupFile = getUserPackagesStateBackupFile(userId);
            new File(userPackagesStateFile.getParent()).mkdirs();
            if (userPackagesStateFile.exists()) {
                // Presence of backup settings file indicates that we failed
@@ -2102,10 +2180,26 @@ public final class Settings implements Watchable, Snappable {
            }

            try {
            final FileOutputStream fstr = new FileOutputStream(userPackagesStateFile);
                fstr = new FileOutputStream(userPackagesStateFile);
                // File is created, set permissions.
                FileUtils.setPermissions(userPackagesStateFile.toString(),
                        FileUtils.S_IRUSR | FileUtils.S_IWUSR
                                | FileUtils.S_IRGRP | FileUtils.S_IWGRP,
                        -1, -1);
            } catch (java.io.IOException e) {
                Slog.wtf(PackageManagerService.TAG,
                        "Unable to write package manager user packages state, "
                                + " current changes will be lost at reboot", e);
                return;
            }
        }

        try {
            synchronized (mLock) {
                final TypedXmlSerializer serializer = Xml.resolveSerializer(fstr);
                serializer.startDocument(null, true);
            serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
                serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output",
                        true);

                serializer.startTag(null, TAG_PACKAGE_RESTRICTIONS);

@@ -2224,18 +2318,26 @@ public final class Settings implements Watchable, Snappable {
                serializer.endTag(null, TAG_PACKAGE_RESTRICTIONS);

                serializer.endDocument();
            }

            fstr.flush();
            FileUtils.sync(fstr);
            fstr.close();
            IoUtils.closeQuietly(fstr);

            // New settings successfully written, old ones are no longer
            // needed.
            backupFile.delete();
            synchronized (mPackageRestrictionsLock) {
                // File is created, set permissions.
                FileUtils.setPermissions(userPackagesStateFile.toString(),
                        FileUtils.S_IRUSR | FileUtils.S_IWUSR
                                | FileUtils.S_IRGRP | FileUtils.S_IWGRP,
                        -1, -1);
                // New settings successfully written, old ones are no longer needed.
                backupFile.delete();
            }

            if (DEBUG_MU) {
                Log.i(TAG, "New settings successfully written for user=" + userId + ": "
                        + userPackagesStateFile);
            }

            com.android.internal.logging.EventLogTags.writeCommitSysConfigFile(
                    "package-user-" + userId, SystemClock.uptimeMillis() - startTime);
@@ -2453,7 +2555,7 @@ public final class Settings implements Watchable, Snappable {
        }
    }

    void writeLPr(@NonNull Computer computer) {
    void writeLPr(@NonNull Computer computer, boolean sync) {
        //Debug.startMethodTracing("/data/system/packageprof", 8 * 1024 * 1024);

        final long startTime = SystemClock.uptimeMillis();
@@ -2578,7 +2680,7 @@ public final class Settings implements Watchable, Snappable {

            writeKernelMappingLPr();
            writePackageListLPr();
            writeAllUsersPackageRestrictionsLPr();
            writeAllUsersPackageRestrictionsLPr(sync);
            writeAllRuntimePermissionsLPr();
            com.android.internal.logging.EventLogTags.writeCommitSysConfigFile(
                    "package", SystemClock.uptimeMillis() - startTime);
@@ -3213,7 +3315,7 @@ public final class Settings implements Watchable, Snappable {
            mBackupStoppedPackagesFilename.delete();
            mStoppedPackagesFilename.delete();
            // Migrate to new file format
            writePackageRestrictionsLPr(UserHandle.USER_SYSTEM);
            writePackageRestrictionsLPr(UserHandle.USER_SYSTEM, /*sync=*/true);
        } else {
            for (UserInfo user : users) {
                readPackageRestrictionsLPr(user.id, originalFirstInstallTimes);
@@ -4284,10 +4386,15 @@ public final class Settings implements Watchable, Snappable {
            entry.getValue().removeUser(userId);
        }
        mPreferredActivities.remove(userId);

        synchronized (mPackageRestrictionsLock) {
            File file = getUserPackagesStateFile(userId);
            file.delete();
            file = getUserPackagesStateBackupFile(userId);
            file.delete();
            mPendingAsyncPackageRestrictionsWrites.delete(userId);
        }

        removeCrossProfileIntentFiltersLPw(userId);

        mRuntimePermissionsPersistence.onUserRemoved(userId);
@@ -4332,7 +4439,7 @@ public final class Settings implements Watchable, Snappable {
        if (mVerifierDeviceIdentity == null) {
            mVerifierDeviceIdentity = VerifierDeviceIdentity.generate();

            writeLPr(computer);
            writeLPr(computer, /*sync=*/false);
        }

        return mVerifierDeviceIdentity;
+221 −25

File changed.

Preview size limit exceeded, changes collapsed.