Change Chromecast casting icon color

I've just extended MediaRouteActionProvider like this:

    public class ThemeableMediaRouteActionProvider extends MediaRouteActionProvider {
    public ThemeableMediaRouteActionProvider(Context context) {
        super(context);
    }

    @Override
    public MediaRouteButton onCreateMediaRouteButton() {
        MediaRouteButton button = super.onCreateMediaRouteButton();
        colorWorkaroundForCastIcon(button);
        return button;
    }

    @Nullable
    @Override
    public MediaRouteButton getMediaRouteButton() {
        MediaRouteButton button = super.getMediaRouteButton();
        colorWorkaroundForCastIcon(button);
        return button;
    }

    private void colorWorkaroundForCastIcon(MediaRouteButton button) {
        if (button == null) return;
        Context castContext = new ContextThemeWrapper(getContext(), androidx.mediarouter.R.style.Theme_MediaRouter);

        TypedArray a = castContext.obtainStyledAttributes(null, androidx.mediarouter.R.styleable.MediaRouteButton, androidx.mediarouter.R.attr.mediaRouteButtonStyle, 0);
        Drawable drawable = a.getDrawable(androidx.mediarouter.R.styleable.MediaRouteButton_externalRouteEnabledDrawable);
        a.recycle();
        DrawableCompat.setTint(drawable, getContext().getResources().getColor(R.color.primary));
        drawable.setState(button.getDrawableState());
        button.setRemoteIndicatorDrawable(drawable);
    }
}

R.color.primary is what color i wanted.

then just replace actionProviderClass in menu from MediaRouteActionProvider to your like that:

<item
    android:id="@+id/media_route_menu_item"
    android:title="@string/media_route_menu_title"
    bwq:actionProviderClass="tv.test.playback.chromecast.ThemeableMediaRouteActionProvider"
    bwq:showAsAction="always">
</item>

I extended MediaRouteButton. See code below. Then I can just call applyTint() and it applies the color to all states of the RemoteIndicatorDrawable

public class ColorableMediaRouteButton extends MediaRouteButton {

    protected Drawable mRemoteIndicatorDrawable;

    public ColorableMediaRouteButton(Context context) {
        super(context);
    }

    public ColorableMediaRouteButton(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public ColorableMediaRouteButton(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public void setRemoteIndicatorDrawable(Drawable d) {
        mRemoteIndicatorDrawable = d;
        super.setRemoteIndicatorDrawable(d);
    }

    public void applyTint(int color) {
        Drawable wrapDrawable = DrawableCompat.wrap(mRemoteIndicatorDrawable);
        DrawableCompat.setTint(wrapDrawable, color);
    }
}

If you have a one color for the cast icon for a view use a theme for the fragment or activity.

<item name="mediaRouteButtonTint">@color/red</item>

If you want to programmatically set the color use the following code.

<menu xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:app="http://schemas.android.com/apk/res-auto">
    <item
        android:id="@+id/menu_item"
        android:title="@string/media_route_menu_title"
        app:actionProviderClass="androidx.mediarouter.app.MediaRouteActionProvider" />
</menu>
import androidx.core.content.ContextCompat
import androidx.appcompat.view.ContextThemeWrapper
import androidx.core.graphics.drawable.DrawableCompat

...

override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater?) {
    val tintColor = ContextCompat.getColor(context, R.color.my_color)
    val item = menu.findItem(R.id.menu_item)
    val button = item.actionView
    val castContext = ContextThemeWrapper(context, androidx.mediarouter.R.style.Theme_MediaRouter)
    val attrs = castContext.obtainStyledAttributes(null, androidx.mediarouter.R.styleable.MediaRouteButton, androidx.mediarouter.R.attr.mediaRouteButtonStyle, 0)
    val drawable = attrs.getDrawable(androidx.mediarouter.R.styleable.MediaRouteButton_externalRouteEnabledDrawable)
    attrs.recycle()
    DrawableCompat.setTint(drawable, tintColor)
    drawable.state = button.getDrawableState()
    button.setRemoteIndicatorDrawable(drawable)