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

Commit 17de6f9a authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Enforce hard limits on hosts per package and widgets per host." into main

parents 0f50abb7 2a75f716
Loading
Loading
Loading
Loading
+49 −1
Original line number Diff line number Diff line
@@ -220,6 +220,15 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
    // See {@link Provider#pendingDeletedWidgetIds}.
    private static final String PENDING_DELETED_IDS_ATTR = "pending_deleted_ids";

    // Hard limit of number of hosts an app can create, note that the app that hosts the widgets
    // can have multiple instances of {@link AppWidgetHost}, typically in respect to different
    // surfaces in the host app.
    // @see AppWidgetHost
    // @see AppWidgetHost#mHostId
    private static final int MAX_NUMBER_OF_HOSTS_PER_PACKAGE = 20;
    // Hard limit of number of widgets can be pinned by a host.
    private static final int MAX_NUMBER_OF_WIDGETS_PER_HOST = 200;

    // Handles user and package related broadcasts.
    // See {@link #registerBroadcastReceiver}
    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@@ -2284,7 +2293,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
        if (host != null) {
            return host;
        }

        ensureHostCountBeforeAddLocked(id);
        host = new Host();
        host.id = id;
        mHosts.add(host);
@@ -2292,6 +2301,24 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
        return host;
    }

    /**
     * Ensures that the number of hosts for a package is less than the maximum number of hosts per
     * package. If the number of hosts is greater than the maximum number of hosts per package, then
     * removes the oldest host.
     */
    private void ensureHostCountBeforeAddLocked(@NonNull final HostId hostId) {
        final List<Host> hosts = new ArrayList<>();
        for (Host host : mHosts) {
            if (host.id.uid == hostId.uid
                    && host.id.packageName.equals(hostId.packageName)) {
                hosts.add(host);
            }
        }
        while (hosts.size() >= MAX_NUMBER_OF_HOSTS_PER_PACKAGE) {
            deleteHostLocked(hosts.remove(0));
        }
    }

    private void deleteHostLocked(Host host) {
        if (DEBUG) {
            Slog.i(TAG, "deleteHostLocked() " + host);
@@ -3582,11 +3609,32 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
        if (DEBUG) {
            Slog.i(TAG, "addWidgetLocked() " + widget);
        }
        ensureWidgetCountBeforeAddLocked(widget);
        mWidgets.add(widget);

        onWidgetProviderAddedOrChangedLocked(widget);
    }

    /**
     * Ensures that the widget count for the widget's host is not greater than the maximum
     * number of widgets per host. If the count is greater than the maximum, removes oldest widgets
     * from the host until the count is less than or equal to the maximum.
     */
    private void ensureWidgetCountBeforeAddLocked(@NonNull final Widget widget) {
        if (widget.host == null || widget.host.id == null) {
            return;
        }
        final List<Widget> widgetsInSameHost = new ArrayList<>();
        for (Widget w : mWidgets) {
            if (w.host != null && widget.host.id.equals(w.host.id)) {
                widgetsInSameHost.add(w);
            }
        }
        while (widgetsInSameHost.size() >= MAX_NUMBER_OF_WIDGETS_PER_HOST) {
            removeWidgetLocked(widgetsInSameHost.remove(0));
        }
    }

    /**
     * Checks if the provider is assigned and updates the mWidgetPackages to track packages
     * that have bound widgets.