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

Commit 50ddd585 authored by Tim Murray's avatar Tim Murray
Browse files

AppWidgetServiceImpl: add mWidgetPackages lock

JobScheduler calls isBoundWidgetPackage(), but this can be extremely
slow while AppWidgetService is doing any meaningful work, causing
problems for the rest of the system. Remove that serialization by
moving mWidgetPackages behind its own lock.

Test: atest CtsAppWidgetTestCases
Bug: 161866124

Change-Id: Idae7d16d375dfd41f802ad193fa1ec939093c67a
parent dae30aff
Loading
Loading
Loading
Loading
+26 −19
Original line number Diff line number Diff line
@@ -222,6 +222,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku

    private final SparseIntArray mLoadedUserIds = new SparseIntArray();

    private final Object mWidgetPackagesLock = new Object();
    private final SparseArray<ArraySet<String>> mWidgetPackages = new SparseArray<>();

    private BackupRestoreController mBackupRestoreController;
@@ -2941,11 +2942,13 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
        if (widget.provider == null) return;

        int userId = widget.provider.getUserId();
        synchronized (mWidgetPackagesLock) {
            ArraySet<String> packages = mWidgetPackages.get(userId);
            if (packages == null) {
                mWidgetPackages.put(userId, packages = new ArraySet<String>());
            }
            packages.add(widget.provider.info.provider.getPackageName());
        }

        // If we are adding a widget it might be for a provider that
        // is currently masked, if so mask the widget.
@@ -2972,6 +2975,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku

        final int userId = widget.provider.getUserId();
        final String packageName = widget.provider.info.provider.getPackageName();
        synchronized (mWidgetPackagesLock) {
            ArraySet<String> packages = mWidgetPackages.get(userId);
            if (packages == null) {
                return;
@@ -2989,6 +2993,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
            }
            packages.remove(packageName);
        }
    }

    /**
     * Clears all widgets and associated cache of packages with bound widgets.
@@ -3000,15 +3005,17 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
    }

    private void onWidgetsClearedLocked() {
        synchronized (mWidgetPackagesLock) {
            mWidgetPackages.clear();
        }
    }

    @Override
    public boolean isBoundWidgetPackage(String packageName, int userId) {
        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
            throw new SecurityException("Only the system process can call this");
        }
        synchronized (mLock) {
        synchronized (mWidgetPackagesLock) {
            final ArraySet<String> packages = mWidgetPackages.get(userId);
            if (packages != null) {
                return packages.contains(packageName);