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

Commit b776e397 authored by Julia Reynolds's avatar Julia Reynolds
Browse files

Synchronize managed services approval list

Some requests to read/write the list come in on other threads and
could cause system process to crash (esp when in the process of saving
the policy file)

Test: reboot, use device, change approval list in settings. take bugreport
Fixes: 132976941
Change-Id: I282d1e763079da1fee2c96266be39e6ef3b131ed
parent a0b4b173
Loading
Loading
Loading
Loading
+206 −174
Original line number Diff line number Diff line
@@ -196,6 +196,7 @@ abstract public class ManagedServices {

    public void dump(PrintWriter pw, DumpFilter filter) {
        pw.println("    Allowed " + getCaption() + "s:");
        synchronized (mApproved) {
            final int N = mApproved.size();
            for (int i = 0; i < N; i++) {
                final int userId = mApproved.keyAt(i);
@@ -212,6 +213,7 @@ abstract public class ManagedServices {
                    }
                }
            }
        }

        pw.println("    All " + getCaption() + "s (" + mEnabledServicesForCurrentProfiles.size()
                + ") enabled for current profiles:");
@@ -240,6 +242,7 @@ abstract public class ManagedServices {

    public void dump(ProtoOutputStream proto, DumpFilter filter) {
        proto.write(ManagedServicesProto.CAPTION, getCaption());
        synchronized (mApproved) {
            final int N = mApproved.size();
            for (int i = 0; i < N; i++) {
                final int userId = mApproved.keyAt(i);
@@ -261,6 +264,7 @@ abstract public class ManagedServices {
                    }
                }
            }
        }

        for (ComponentName cmpt : mEnabledServicesForCurrentProfiles) {
            if (filter != null && !filter.matches(cmpt)) continue;
@@ -315,6 +319,7 @@ abstract public class ManagedServices {
            trimApprovedListsAccordingToInstalledServices(userId);
        }

        synchronized (mApproved) {
            final int N = mApproved.size();
            for (int i = 0; i < N; i++) {
                final int approvedUserId = mApproved.keyAt(i);
@@ -339,13 +344,15 @@ abstract public class ManagedServices {
                            if (!forBackup && isPrimary) {
                                // Also write values to settings, for observers who haven't migrated yet
                                Settings.Secure.putStringForUser(mContext.getContentResolver(),
                                    getConfig().secureSettingName, allowedItems, approvedUserId);
                                        getConfig().secureSettingName, allowedItems,
                                        approvedUserId);
                            }

                        }
                    }
                }
            }
        }

        writeExtraXmlTags(out);

@@ -440,6 +447,7 @@ abstract public class ManagedServices {
        if (TextUtils.isEmpty(approved)) {
            approved = "";
        }
        synchronized (mApproved) {
            ArrayMap<Boolean, ArraySet<String>> approvedByType = mApproved.get(userId);
            if (approvedByType == null) {
                approvedByType = new ArrayMap<>();
@@ -460,6 +468,7 @@ abstract public class ManagedServices {
                }
            }
        }
    }

    protected boolean isComponentEnabledForPackage(String pkg) {
        return mEnabledServicesPackageNames.contains(pkg);
@@ -469,6 +478,7 @@ abstract public class ManagedServices {
            boolean isPrimary, boolean enabled) {
        Slog.i(TAG,
                (enabled ? " Allowing " : "Disallowing ") + mConfig.caption + " " + pkgOrComponent);
        synchronized (mApproved) {
            ArrayMap<Boolean, ArraySet<String>> allowedByType = mApproved.get(userId);
            if (allowedByType == null) {
                allowedByType = new ArrayMap<>();
@@ -488,6 +498,7 @@ abstract public class ManagedServices {
                    approved.remove(approvedItem);
                }
            }
        }

        rebindServices(false, userId);
    }
@@ -504,14 +515,17 @@ abstract public class ManagedServices {
    }

    protected String getApproved(int userId, boolean primary) {
        synchronized (mApproved) {
            final ArrayMap<Boolean, ArraySet<String>> allowedByType =
                    mApproved.getOrDefault(userId, new ArrayMap<>());
            ArraySet<String> approved = allowedByType.getOrDefault(primary, new ArraySet<>());
            return String.join(ENABLED_SERVICES_SEPARATOR, approved);
        }
    }

    protected List<ComponentName> getAllowedComponents(int userId) {
        final List<ComponentName> allowedComponents = new ArrayList<>();
        synchronized (mApproved) {
            final ArrayMap<Boolean, ArraySet<String>> allowedByType =
                    mApproved.getOrDefault(userId, new ArrayMap<>());
            for (int i = 0; i < allowedByType.size(); i++) {
@@ -523,11 +537,13 @@ abstract public class ManagedServices {
                    }
                }
            }
        }
        return allowedComponents;
    }

    protected List<String> getAllowedPackages(int userId) {
        final List<String> allowedPackages = new ArrayList<>();
        synchronized (mApproved) {
            final ArrayMap<Boolean, ArraySet<String>> allowedByType =
                    mApproved.getOrDefault(userId, new ArrayMap<>());
            for (int i = 0; i < allowedByType.size(); i++) {
@@ -539,10 +555,12 @@ abstract public class ManagedServices {
                    }
                }
            }
        }
        return allowedPackages;
    }

    protected boolean isPackageOrComponentAllowed(String pkgOrComponent, int userId) {
        synchronized (mApproved) {
            ArrayMap<Boolean, ArraySet<String>> allowedByType =
                    mApproved.getOrDefault(userId, new ArrayMap<>());
            for (int i = 0; i < allowedByType.size(); i++) {
@@ -551,6 +569,7 @@ abstract public class ManagedServices {
                    return true;
                }
            }
        }
        return false;
    }

@@ -558,6 +577,7 @@ abstract public class ManagedServices {
        if (pkg == null) {
            return false;
        }
        synchronized (mApproved) {
            ArrayMap<Boolean, ArraySet<String>> allowedByType =
                    mApproved.getOrDefault(userId, new ArrayMap<>());
            for (int i = 0; i < allowedByType.size(); i++) {
@@ -575,6 +595,7 @@ abstract public class ManagedServices {
                    }
                }
            }
        }
        return false;
    }

@@ -616,7 +637,9 @@ abstract public class ManagedServices {

    public void onUserRemoved(int user) {
        Slog.i(TAG, "Removing approved services for removed user " + user);
        synchronized (mApproved) {
            mApproved.remove(user);
        }
        rebindServices(true, user);
    }

@@ -797,6 +820,7 @@ abstract public class ManagedServices {

    protected Set<String> getAllowedPackages() {
        final Set<String> allowedPackages = new ArraySet<>();
        synchronized (mApproved) {
            for (int k = 0; k < mApproved.size(); k++) {
                ArrayMap<Boolean, ArraySet<String>> allowedByType = mApproved.valueAt(k);
                for (int i = 0; i < allowedByType.size(); i++) {
@@ -809,10 +833,12 @@ abstract public class ManagedServices {
                    }
                }
            }
        }
        return allowedPackages;
    }

    private void trimApprovedListsAccordingToInstalledServices(int userId) {
        synchronized (mApproved) {
            final ArrayMap<Boolean, ArraySet<String>> approvedByType = mApproved.get(userId);
            if (approvedByType == null) {
                return;
@@ -834,10 +860,13 @@ abstract public class ManagedServices {
                }
            }
        }
    }

    private boolean removeUninstalledItemsFromApprovedLists(int uninstalledUserId, String pkg) {
        boolean removed = false;
        final ArrayMap<Boolean, ArraySet<String>> approvedByType = mApproved.get(uninstalledUserId);
        synchronized (mApproved) {
            final ArrayMap<Boolean, ArraySet<String>> approvedByType = mApproved.get(
                    uninstalledUserId);
            if (approvedByType != null) {
                int M = approvedByType.size();
                for (int j = 0; j < M; j++) {
@@ -856,6 +885,7 @@ abstract public class ManagedServices {
                    }
                }
            }
        }
        return removed;
    }

@@ -887,6 +917,7 @@ abstract public class ManagedServices {

        for (int i = 0; i < nUserIds; ++i) {
            final int userId = userIds.get(i);
            synchronized (mApproved) {
                final ArrayMap<Boolean, ArraySet<String>> approvedLists = mApproved.get(userId);
                if (approvedLists != null) {
                    final int N = approvedLists.size();
@@ -901,6 +932,7 @@ abstract public class ManagedServices {
                    }
                }
            }
        }
        return componentsByUser;
    }