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

Commit 334e4e88 authored by Iván Budnik's avatar Iván Budnik
Browse files

Sanitize system route types to TYPE_UNKNOWN for non-system providers

Non-system route providers should not be able to publish routes of any
system route type (e.g. wired headset, bluetooth, etc). The routing
framework will treat any route from a non-system route provider with a
system route type as TYPE_UNKNOWN and log a warning.

Ideally, we should introduce a compat change on the next API bump to just
rethrow a SecurityException instead of switching the route type.

Bug: 347499404
Test: atest CtsMediaBetterTogetherTestCases and manually via
MediaRouting demo app
Flag: EXEMPT bugfix

Change-Id: I482b315fd3eba48a5b10e877fec3754e051826d4
parent ee6d33f4
Loading
Loading
Loading
Loading
+29 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SuppressLint;
import android.annotation.TestApi;
import android.net.Uri;
import android.os.Bundle;
@@ -813,6 +814,34 @@ public final class MediaRoute2Info implements Parcelable {
                || mAllowedPackages.contains(packageName);
    }

    /**
     * Returns whether this route's type can only be published by the system route provider.
     *
     * @see #isSystemRoute()
     * @hide
     */
    // The default case catches all other types.
    @SuppressLint("SwitchIntDef")
    public boolean isSystemRouteType() {
        return switch (mType) {
            case TYPE_BUILTIN_SPEAKER,
                            TYPE_BLUETOOTH_A2DP,
                            TYPE_DOCK,
                            TYPE_BLE_HEADSET,
                            TYPE_HEARING_AID,
                            TYPE_HDMI,
                            TYPE_HDMI_ARC,
                            TYPE_HDMI_EARC,
                            TYPE_USB_ACCESSORY,
                            TYPE_USB_DEVICE,
                            TYPE_USB_HEADSET,
                            TYPE_WIRED_HEADPHONES,
                            TYPE_WIRED_HEADSET ->
                    true;
            default -> false;
        };
    }

    /** Returns the route suitability status. */
    @SuitabilityStatus
    @FlaggedApi(FLAG_ENABLE_BUILT_IN_SPEAKER_ROUTE_SUITABILITY_STATUSES)
+19 −3
Original line number Diff line number Diff line
@@ -475,9 +475,25 @@ public abstract class MediaRoute2ProviderService extends Service {
     */
    public final void notifyRoutes(@NonNull Collection<MediaRoute2Info> routes) {
        Objects.requireNonNull(routes, "routes must not be null");
        mProviderInfo = new MediaRoute2ProviderInfo.Builder()
                .addRoutes(routes)
                .build();
        List<MediaRoute2Info> sanitizedRoutes = new ArrayList<>(routes.size());

        for (MediaRoute2Info route : routes) {
            if (route.isSystemRouteType()) {
                Log.w(
                        TAG,
                        "Attempting to add a system route type from a non-system route "
                                + "provider. Overriding type to TYPE_UNKNOWN. Route: "
                                + route);
                sanitizedRoutes.add(
                        new MediaRoute2Info.Builder(route)
                                .setType(MediaRoute2Info.TYPE_UNKNOWN)
                                .build());
            } else {
                sanitizedRoutes.add(route);
            }
        }

        mProviderInfo = new MediaRoute2ProviderInfo.Builder().addRoutes(sanitizedRoutes).build();
        schedulePublishState();
    }

+7 −0
Original line number Diff line number Diff line
@@ -839,6 +839,13 @@ final class MediaRoute2ProviderServiceProxy extends MediaRoute2Provider {
                                    + "Disallowed route: "
                                    + route);
                }

                if (route.isSystemRouteType()) {
                    throw new SecurityException(
                            "Only the system is allowed to publish routes with system route types. "
                                    + "Disallowed route: "
                                    + route);
                }
            }

            Connection connection = mConnectionRef.get();