111417b1cfde8f1749905f2d735623af9214148afJeff Brown/*
211417b1cfde8f1749905f2d735623af9214148afJeff Brown * Copyright (C) 2013 The Android Open Source Project
311417b1cfde8f1749905f2d735623af9214148afJeff Brown *
411417b1cfde8f1749905f2d735623af9214148afJeff Brown * Licensed under the Apache License, Version 2.0 (the "License");
511417b1cfde8f1749905f2d735623af9214148afJeff Brown * you may not use this file except in compliance with the License.
611417b1cfde8f1749905f2d735623af9214148afJeff Brown * You may obtain a copy of the License at
711417b1cfde8f1749905f2d735623af9214148afJeff Brown *
811417b1cfde8f1749905f2d735623af9214148afJeff Brown *      http://www.apache.org/licenses/LICENSE-2.0
911417b1cfde8f1749905f2d735623af9214148afJeff Brown *
1011417b1cfde8f1749905f2d735623af9214148afJeff Brown * Unless required by applicable law or agreed to in writing, software
1111417b1cfde8f1749905f2d735623af9214148afJeff Brown * distributed under the License is distributed on an "AS IS" BASIS,
1211417b1cfde8f1749905f2d735623af9214148afJeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1311417b1cfde8f1749905f2d735623af9214148afJeff Brown * See the License for the specific language governing permissions and
1411417b1cfde8f1749905f2d735623af9214148afJeff Brown * limitations under the License.
1511417b1cfde8f1749905f2d735623af9214148afJeff Brown */
1611417b1cfde8f1749905f2d735623af9214148afJeff Brownpackage android.support.v7.media;
1711417b1cfde8f1749905f2d735623af9214148afJeff Brown
1811417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.content.IntentFilter;
1911417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.os.Bundle;
20429c3b17b88ebd8c4512e9179fd9d48333c0979eTor Norbyeimport android.support.annotation.NonNull;
21429c3b17b88ebd8c4512e9179fd9d48333c0979eTor Norbyeimport android.support.annotation.Nullable;
2211417b1cfde8f1749905f2d735623af9214148afJeff Brown
2311417b1cfde8f1749905f2d735623af9214148afJeff Brownimport java.util.ArrayList;
2411417b1cfde8f1749905f2d735623af9214148afJeff Brownimport java.util.Arrays;
257599feee523c7b7d33576ae5825e43e3d62cbcbeJeff Brownimport java.util.Collection;
2611417b1cfde8f1749905f2d735623af9214148afJeff Brownimport java.util.Collections;
2711417b1cfde8f1749905f2d735623af9214148afJeff Brownimport java.util.List;
2811417b1cfde8f1749905f2d735623af9214148afJeff Brown
2911417b1cfde8f1749905f2d735623af9214148afJeff Brown/**
3011417b1cfde8f1749905f2d735623af9214148afJeff Brown * Describes the capabilities of routes that applications would like to discover and use.
3111417b1cfde8f1749905f2d735623af9214148afJeff Brown * <p>
3211417b1cfde8f1749905f2d735623af9214148afJeff Brown * This object is immutable once created using a {@link Builder} instance.
3311417b1cfde8f1749905f2d735623af9214148afJeff Brown * </p>
3411417b1cfde8f1749905f2d735623af9214148afJeff Brown *
3511417b1cfde8f1749905f2d735623af9214148afJeff Brown * <h3>Example</h3>
3611417b1cfde8f1749905f2d735623af9214148afJeff Brown * <pre>
3711417b1cfde8f1749905f2d735623af9214148afJeff Brown * MediaRouteSelector selectorBuilder = new MediaRouteSelector.Builder()
3811417b1cfde8f1749905f2d735623af9214148afJeff Brown *         .addControlCategory(MediaControlIntent.CATEGORY_LIVE_VIDEO)
3911417b1cfde8f1749905f2d735623af9214148afJeff Brown *         .addControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)
4011417b1cfde8f1749905f2d735623af9214148afJeff Brown *         .build();
4111417b1cfde8f1749905f2d735623af9214148afJeff Brown *
4211417b1cfde8f1749905f2d735623af9214148afJeff Brown * MediaRouter router = MediaRouter.getInstance(context);
43f03da4a9e6cc02251c2f804eb6f25da61821d6a7Jeff Brown * router.addCallback(selector, callback, MediaRouter.CALLBACK_FLAG_REQUEST_DISCOVERY);
4411417b1cfde8f1749905f2d735623af9214148afJeff Brown * </pre>
4511417b1cfde8f1749905f2d735623af9214148afJeff Brown */
4611417b1cfde8f1749905f2d735623af9214148afJeff Brownpublic final class MediaRouteSelector {
47e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikas    static final String KEY_CONTROL_CATEGORIES = "controlCategories";
4811417b1cfde8f1749905f2d735623af9214148afJeff Brown
4911417b1cfde8f1749905f2d735623af9214148afJeff Brown    private final Bundle mBundle;
50e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikas    List<String> mControlCategories;
5111417b1cfde8f1749905f2d735623af9214148afJeff Brown
5211417b1cfde8f1749905f2d735623af9214148afJeff Brown    /**
5311417b1cfde8f1749905f2d735623af9214148afJeff Brown     * An empty media route selector that will not match any routes.
5411417b1cfde8f1749905f2d735623af9214148afJeff Brown     */
5511417b1cfde8f1749905f2d735623af9214148afJeff Brown    public static final MediaRouteSelector EMPTY = new MediaRouteSelector(new Bundle(), null);
5611417b1cfde8f1749905f2d735623af9214148afJeff Brown
57e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikas    MediaRouteSelector(Bundle bundle, List<String> controlCategories) {
5811417b1cfde8f1749905f2d735623af9214148afJeff Brown        mBundle = bundle;
5911417b1cfde8f1749905f2d735623af9214148afJeff Brown        mControlCategories = controlCategories;
6011417b1cfde8f1749905f2d735623af9214148afJeff Brown    }
6111417b1cfde8f1749905f2d735623af9214148afJeff Brown
6211417b1cfde8f1749905f2d735623af9214148afJeff Brown    /**
6311417b1cfde8f1749905f2d735623af9214148afJeff Brown     * Gets the list of {@link MediaControlIntent media control categories} in the selector.
6411417b1cfde8f1749905f2d735623af9214148afJeff Brown     *
6511417b1cfde8f1749905f2d735623af9214148afJeff Brown     * @return The list of categories.
6611417b1cfde8f1749905f2d735623af9214148afJeff Brown     */
6711417b1cfde8f1749905f2d735623af9214148afJeff Brown    public List<String> getControlCategories() {
6811417b1cfde8f1749905f2d735623af9214148afJeff Brown        ensureControlCategories();
6911417b1cfde8f1749905f2d735623af9214148afJeff Brown        return mControlCategories;
7011417b1cfde8f1749905f2d735623af9214148afJeff Brown    }
7111417b1cfde8f1749905f2d735623af9214148afJeff Brown
72e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikas    void ensureControlCategories() {
7311417b1cfde8f1749905f2d735623af9214148afJeff Brown        if (mControlCategories == null) {
7411417b1cfde8f1749905f2d735623af9214148afJeff Brown            mControlCategories = mBundle.getStringArrayList(KEY_CONTROL_CATEGORIES);
7511417b1cfde8f1749905f2d735623af9214148afJeff Brown            if (mControlCategories == null || mControlCategories.isEmpty()) {
7611417b1cfde8f1749905f2d735623af9214148afJeff Brown                mControlCategories = Collections.<String>emptyList();
7711417b1cfde8f1749905f2d735623af9214148afJeff Brown            }
7811417b1cfde8f1749905f2d735623af9214148afJeff Brown        }
7911417b1cfde8f1749905f2d735623af9214148afJeff Brown    }
8011417b1cfde8f1749905f2d735623af9214148afJeff Brown
8111417b1cfde8f1749905f2d735623af9214148afJeff Brown    /**
8211417b1cfde8f1749905f2d735623af9214148afJeff Brown     * Returns true if the selector contains the specified category.
8311417b1cfde8f1749905f2d735623af9214148afJeff Brown     *
8411417b1cfde8f1749905f2d735623af9214148afJeff Brown     * @param category The category to check.
8511417b1cfde8f1749905f2d735623af9214148afJeff Brown     * @return True if the category is present.
8611417b1cfde8f1749905f2d735623af9214148afJeff Brown     */
8711417b1cfde8f1749905f2d735623af9214148afJeff Brown    public boolean hasControlCategory(String category) {
8811417b1cfde8f1749905f2d735623af9214148afJeff Brown        if (category != null) {
8911417b1cfde8f1749905f2d735623af9214148afJeff Brown            ensureControlCategories();
9011417b1cfde8f1749905f2d735623af9214148afJeff Brown            final int categoryCount = mControlCategories.size();
9111417b1cfde8f1749905f2d735623af9214148afJeff Brown            for (int i = 0; i < categoryCount; i++) {
9211417b1cfde8f1749905f2d735623af9214148afJeff Brown                if (mControlCategories.get(i).equals(category)) {
9311417b1cfde8f1749905f2d735623af9214148afJeff Brown                    return true;
9411417b1cfde8f1749905f2d735623af9214148afJeff Brown                }
9511417b1cfde8f1749905f2d735623af9214148afJeff Brown            }
9611417b1cfde8f1749905f2d735623af9214148afJeff Brown        }
9711417b1cfde8f1749905f2d735623af9214148afJeff Brown        return false;
9811417b1cfde8f1749905f2d735623af9214148afJeff Brown    }
9911417b1cfde8f1749905f2d735623af9214148afJeff Brown
10011417b1cfde8f1749905f2d735623af9214148afJeff Brown    /**
10111417b1cfde8f1749905f2d735623af9214148afJeff Brown     * Returns true if the selector matches at least one of the specified control filters.
10211417b1cfde8f1749905f2d735623af9214148afJeff Brown     *
10311417b1cfde8f1749905f2d735623af9214148afJeff Brown     * @param filters The list of control filters to consider.
10411417b1cfde8f1749905f2d735623af9214148afJeff Brown     * @return True if a match is found.
10511417b1cfde8f1749905f2d735623af9214148afJeff Brown     */
10611417b1cfde8f1749905f2d735623af9214148afJeff Brown    public boolean matchesControlFilters(List<IntentFilter> filters) {
10711417b1cfde8f1749905f2d735623af9214148afJeff Brown        if (filters != null) {
10811417b1cfde8f1749905f2d735623af9214148afJeff Brown            ensureControlCategories();
10911417b1cfde8f1749905f2d735623af9214148afJeff Brown            final int categoryCount = mControlCategories.size();
11011417b1cfde8f1749905f2d735623af9214148afJeff Brown            if (categoryCount != 0) {
11111417b1cfde8f1749905f2d735623af9214148afJeff Brown                final int filterCount = filters.size();
11211417b1cfde8f1749905f2d735623af9214148afJeff Brown                for (int i = 0; i < filterCount; i++) {
11311417b1cfde8f1749905f2d735623af9214148afJeff Brown                    final IntentFilter filter = filters.get(i);
11411417b1cfde8f1749905f2d735623af9214148afJeff Brown                    if (filter != null) {
11511417b1cfde8f1749905f2d735623af9214148afJeff Brown                        for (int j = 0; j < categoryCount; j++) {
11611417b1cfde8f1749905f2d735623af9214148afJeff Brown                            if (filter.hasCategory(mControlCategories.get(j))) {
11711417b1cfde8f1749905f2d735623af9214148afJeff Brown                                return true;
11811417b1cfde8f1749905f2d735623af9214148afJeff Brown                            }
11911417b1cfde8f1749905f2d735623af9214148afJeff Brown                        }
12011417b1cfde8f1749905f2d735623af9214148afJeff Brown                    }
12111417b1cfde8f1749905f2d735623af9214148afJeff Brown                }
12211417b1cfde8f1749905f2d735623af9214148afJeff Brown            }
12311417b1cfde8f1749905f2d735623af9214148afJeff Brown        }
12411417b1cfde8f1749905f2d735623af9214148afJeff Brown        return false;
12511417b1cfde8f1749905f2d735623af9214148afJeff Brown    }
12611417b1cfde8f1749905f2d735623af9214148afJeff Brown
12711417b1cfde8f1749905f2d735623af9214148afJeff Brown    /**
12811417b1cfde8f1749905f2d735623af9214148afJeff Brown     * Returns true if this selector contains all of the capabilities described
12911417b1cfde8f1749905f2d735623af9214148afJeff Brown     * by the specified selector.
13011417b1cfde8f1749905f2d735623af9214148afJeff Brown     *
13111417b1cfde8f1749905f2d735623af9214148afJeff Brown     * @param selector The selector to be examined.
13211417b1cfde8f1749905f2d735623af9214148afJeff Brown     * @return True if this selector contains all of the capabilities described
13311417b1cfde8f1749905f2d735623af9214148afJeff Brown     * by the specified selector.
13411417b1cfde8f1749905f2d735623af9214148afJeff Brown     */
13511417b1cfde8f1749905f2d735623af9214148afJeff Brown    public boolean contains(MediaRouteSelector selector) {
13611417b1cfde8f1749905f2d735623af9214148afJeff Brown        if (selector != null) {
13711417b1cfde8f1749905f2d735623af9214148afJeff Brown            ensureControlCategories();
13811417b1cfde8f1749905f2d735623af9214148afJeff Brown            selector.ensureControlCategories();
13911417b1cfde8f1749905f2d735623af9214148afJeff Brown            return mControlCategories.containsAll(selector.mControlCategories);
14011417b1cfde8f1749905f2d735623af9214148afJeff Brown        }
14111417b1cfde8f1749905f2d735623af9214148afJeff Brown        return false;
14211417b1cfde8f1749905f2d735623af9214148afJeff Brown    }
14311417b1cfde8f1749905f2d735623af9214148afJeff Brown
14411417b1cfde8f1749905f2d735623af9214148afJeff Brown    /**
14511417b1cfde8f1749905f2d735623af9214148afJeff Brown     * Returns true if the selector does not specify any capabilities.
14611417b1cfde8f1749905f2d735623af9214148afJeff Brown     */
14711417b1cfde8f1749905f2d735623af9214148afJeff Brown    public boolean isEmpty() {
14811417b1cfde8f1749905f2d735623af9214148afJeff Brown        ensureControlCategories();
14911417b1cfde8f1749905f2d735623af9214148afJeff Brown        return mControlCategories.isEmpty();
15011417b1cfde8f1749905f2d735623af9214148afJeff Brown    }
15111417b1cfde8f1749905f2d735623af9214148afJeff Brown
15211417b1cfde8f1749905f2d735623af9214148afJeff Brown    /**
15311417b1cfde8f1749905f2d735623af9214148afJeff Brown     * Returns true if the selector has all of the required fields.
15411417b1cfde8f1749905f2d735623af9214148afJeff Brown     */
15511417b1cfde8f1749905f2d735623af9214148afJeff Brown    public boolean isValid() {
15611417b1cfde8f1749905f2d735623af9214148afJeff Brown        ensureControlCategories();
15711417b1cfde8f1749905f2d735623af9214148afJeff Brown        if (mControlCategories.contains(null)) {
15811417b1cfde8f1749905f2d735623af9214148afJeff Brown            return false;
15911417b1cfde8f1749905f2d735623af9214148afJeff Brown        }
16011417b1cfde8f1749905f2d735623af9214148afJeff Brown        return true;
16111417b1cfde8f1749905f2d735623af9214148afJeff Brown    }
16211417b1cfde8f1749905f2d735623af9214148afJeff Brown
16311417b1cfde8f1749905f2d735623af9214148afJeff Brown    @Override
16411417b1cfde8f1749905f2d735623af9214148afJeff Brown    public boolean equals(Object o) {
16511417b1cfde8f1749905f2d735623af9214148afJeff Brown        if (o instanceof MediaRouteSelector) {
16611417b1cfde8f1749905f2d735623af9214148afJeff Brown            MediaRouteSelector other = (MediaRouteSelector)o;
16711417b1cfde8f1749905f2d735623af9214148afJeff Brown            ensureControlCategories();
16811417b1cfde8f1749905f2d735623af9214148afJeff Brown            other.ensureControlCategories();
16911417b1cfde8f1749905f2d735623af9214148afJeff Brown            return mControlCategories.equals(other.mControlCategories);
17011417b1cfde8f1749905f2d735623af9214148afJeff Brown        }
17111417b1cfde8f1749905f2d735623af9214148afJeff Brown        return false;
17211417b1cfde8f1749905f2d735623af9214148afJeff Brown    }
17311417b1cfde8f1749905f2d735623af9214148afJeff Brown
17411417b1cfde8f1749905f2d735623af9214148afJeff Brown    @Override
17511417b1cfde8f1749905f2d735623af9214148afJeff Brown    public int hashCode() {
17611417b1cfde8f1749905f2d735623af9214148afJeff Brown        ensureControlCategories();
17711417b1cfde8f1749905f2d735623af9214148afJeff Brown        return mControlCategories.hashCode();
17811417b1cfde8f1749905f2d735623af9214148afJeff Brown    }
17911417b1cfde8f1749905f2d735623af9214148afJeff Brown
18011417b1cfde8f1749905f2d735623af9214148afJeff Brown    @Override
18111417b1cfde8f1749905f2d735623af9214148afJeff Brown    public String toString() {
18211417b1cfde8f1749905f2d735623af9214148afJeff Brown        StringBuilder result = new StringBuilder();
18311417b1cfde8f1749905f2d735623af9214148afJeff Brown        result.append("MediaRouteSelector{ ");
18411417b1cfde8f1749905f2d735623af9214148afJeff Brown        result.append("controlCategories=").append(
18511417b1cfde8f1749905f2d735623af9214148afJeff Brown                Arrays.toString(getControlCategories().toArray()));
18611417b1cfde8f1749905f2d735623af9214148afJeff Brown        result.append(" }");
18711417b1cfde8f1749905f2d735623af9214148afJeff Brown        return result.toString();
18811417b1cfde8f1749905f2d735623af9214148afJeff Brown    }
18911417b1cfde8f1749905f2d735623af9214148afJeff Brown
19011417b1cfde8f1749905f2d735623af9214148afJeff Brown    /**
19111417b1cfde8f1749905f2d735623af9214148afJeff Brown     * Converts this object to a bundle for serialization.
19211417b1cfde8f1749905f2d735623af9214148afJeff Brown     *
19311417b1cfde8f1749905f2d735623af9214148afJeff Brown     * @return The contents of the object represented as a bundle.
19411417b1cfde8f1749905f2d735623af9214148afJeff Brown     */
19511417b1cfde8f1749905f2d735623af9214148afJeff Brown    public Bundle asBundle() {
19611417b1cfde8f1749905f2d735623af9214148afJeff Brown        return mBundle;
19711417b1cfde8f1749905f2d735623af9214148afJeff Brown    }
19811417b1cfde8f1749905f2d735623af9214148afJeff Brown
19911417b1cfde8f1749905f2d735623af9214148afJeff Brown    /**
20011417b1cfde8f1749905f2d735623af9214148afJeff Brown     * Creates an instance from a bundle.
20111417b1cfde8f1749905f2d735623af9214148afJeff Brown     *
20211417b1cfde8f1749905f2d735623af9214148afJeff Brown     * @param bundle The bundle, or null if none.
20311417b1cfde8f1749905f2d735623af9214148afJeff Brown     * @return The new instance, or null if the bundle was null.
20411417b1cfde8f1749905f2d735623af9214148afJeff Brown     */
205429c3b17b88ebd8c4512e9179fd9d48333c0979eTor Norbye    public static MediaRouteSelector fromBundle(@Nullable Bundle bundle) {
20611417b1cfde8f1749905f2d735623af9214148afJeff Brown        return bundle != null ? new MediaRouteSelector(bundle, null) : null;
20711417b1cfde8f1749905f2d735623af9214148afJeff Brown    }
20811417b1cfde8f1749905f2d735623af9214148afJeff Brown
20911417b1cfde8f1749905f2d735623af9214148afJeff Brown    /**
21011417b1cfde8f1749905f2d735623af9214148afJeff Brown     * Builder for {@link MediaRouteSelector media route selectors}.
21111417b1cfde8f1749905f2d735623af9214148afJeff Brown     */
21211417b1cfde8f1749905f2d735623af9214148afJeff Brown    public static final class Builder {
21311417b1cfde8f1749905f2d735623af9214148afJeff Brown        private ArrayList<String> mControlCategories;
21411417b1cfde8f1749905f2d735623af9214148afJeff Brown
21511417b1cfde8f1749905f2d735623af9214148afJeff Brown        /**
21611417b1cfde8f1749905f2d735623af9214148afJeff Brown         * Creates an empty media route selector builder.
21711417b1cfde8f1749905f2d735623af9214148afJeff Brown         */
21811417b1cfde8f1749905f2d735623af9214148afJeff Brown        public Builder() {
21911417b1cfde8f1749905f2d735623af9214148afJeff Brown        }
22011417b1cfde8f1749905f2d735623af9214148afJeff Brown
22111417b1cfde8f1749905f2d735623af9214148afJeff Brown        /**
22211417b1cfde8f1749905f2d735623af9214148afJeff Brown         * Creates a media route selector descriptor builder whose initial contents are
22311417b1cfde8f1749905f2d735623af9214148afJeff Brown         * copied from an existing selector.
22411417b1cfde8f1749905f2d735623af9214148afJeff Brown         */
225429c3b17b88ebd8c4512e9179fd9d48333c0979eTor Norbye        public Builder(@NonNull MediaRouteSelector selector) {
22611417b1cfde8f1749905f2d735623af9214148afJeff Brown            if (selector == null) {
22711417b1cfde8f1749905f2d735623af9214148afJeff Brown                throw new IllegalArgumentException("selector must not be null");
22811417b1cfde8f1749905f2d735623af9214148afJeff Brown            }
22911417b1cfde8f1749905f2d735623af9214148afJeff Brown
23011417b1cfde8f1749905f2d735623af9214148afJeff Brown            selector.ensureControlCategories();
23111417b1cfde8f1749905f2d735623af9214148afJeff Brown            if (!selector.mControlCategories.isEmpty()) {
23211417b1cfde8f1749905f2d735623af9214148afJeff Brown                mControlCategories = new ArrayList<String>(selector.mControlCategories);
23311417b1cfde8f1749905f2d735623af9214148afJeff Brown            }
23411417b1cfde8f1749905f2d735623af9214148afJeff Brown        }
23511417b1cfde8f1749905f2d735623af9214148afJeff Brown
23611417b1cfde8f1749905f2d735623af9214148afJeff Brown        /**
23711417b1cfde8f1749905f2d735623af9214148afJeff Brown         * Adds a {@link MediaControlIntent media control category} to the builder.
23811417b1cfde8f1749905f2d735623af9214148afJeff Brown         *
23911417b1cfde8f1749905f2d735623af9214148afJeff Brown         * @param category The category to add to the set of desired capabilities, such as
24011417b1cfde8f1749905f2d735623af9214148afJeff Brown         * {@link MediaControlIntent#CATEGORY_LIVE_AUDIO}.
24111417b1cfde8f1749905f2d735623af9214148afJeff Brown         * @return The builder instance for chaining.
24211417b1cfde8f1749905f2d735623af9214148afJeff Brown         */
243429c3b17b88ebd8c4512e9179fd9d48333c0979eTor Norbye        @NonNull
244429c3b17b88ebd8c4512e9179fd9d48333c0979eTor Norbye        public Builder addControlCategory(@NonNull String category) {
24511417b1cfde8f1749905f2d735623af9214148afJeff Brown            if (category == null) {
24611417b1cfde8f1749905f2d735623af9214148afJeff Brown                throw new IllegalArgumentException("category must not be null");
24711417b1cfde8f1749905f2d735623af9214148afJeff Brown            }
24811417b1cfde8f1749905f2d735623af9214148afJeff Brown
24911417b1cfde8f1749905f2d735623af9214148afJeff Brown            if (mControlCategories == null) {
25011417b1cfde8f1749905f2d735623af9214148afJeff Brown                mControlCategories = new ArrayList<String>();
25111417b1cfde8f1749905f2d735623af9214148afJeff Brown            }
25211417b1cfde8f1749905f2d735623af9214148afJeff Brown            if (!mControlCategories.contains(category)) {
25311417b1cfde8f1749905f2d735623af9214148afJeff Brown                mControlCategories.add(category);
25411417b1cfde8f1749905f2d735623af9214148afJeff Brown            }
25511417b1cfde8f1749905f2d735623af9214148afJeff Brown            return this;
25611417b1cfde8f1749905f2d735623af9214148afJeff Brown        }
25711417b1cfde8f1749905f2d735623af9214148afJeff Brown
25811417b1cfde8f1749905f2d735623af9214148afJeff Brown        /**
25911417b1cfde8f1749905f2d735623af9214148afJeff Brown         * Adds a list of {@link MediaControlIntent media control categories} to the builder.
26011417b1cfde8f1749905f2d735623af9214148afJeff Brown         *
26111417b1cfde8f1749905f2d735623af9214148afJeff Brown         * @param categories The list categories to add to the set of desired capabilities,
26211417b1cfde8f1749905f2d735623af9214148afJeff Brown         * such as {@link MediaControlIntent#CATEGORY_LIVE_AUDIO}.
26311417b1cfde8f1749905f2d735623af9214148afJeff Brown         * @return The builder instance for chaining.
26411417b1cfde8f1749905f2d735623af9214148afJeff Brown         */
265429c3b17b88ebd8c4512e9179fd9d48333c0979eTor Norbye        @NonNull
266429c3b17b88ebd8c4512e9179fd9d48333c0979eTor Norbye        public Builder addControlCategories(@NonNull Collection<String> categories) {
26711417b1cfde8f1749905f2d735623af9214148afJeff Brown            if (categories == null) {
26811417b1cfde8f1749905f2d735623af9214148afJeff Brown                throw new IllegalArgumentException("categories must not be null");
26911417b1cfde8f1749905f2d735623af9214148afJeff Brown            }
27011417b1cfde8f1749905f2d735623af9214148afJeff Brown
2717599feee523c7b7d33576ae5825e43e3d62cbcbeJeff Brown            if (!categories.isEmpty()) {
2727599feee523c7b7d33576ae5825e43e3d62cbcbeJeff Brown                for (String category : categories) {
2737599feee523c7b7d33576ae5825e43e3d62cbcbeJeff Brown                    addControlCategory(category);
2747599feee523c7b7d33576ae5825e43e3d62cbcbeJeff Brown                }
27511417b1cfde8f1749905f2d735623af9214148afJeff Brown            }
27611417b1cfde8f1749905f2d735623af9214148afJeff Brown            return this;
27711417b1cfde8f1749905f2d735623af9214148afJeff Brown        }
27811417b1cfde8f1749905f2d735623af9214148afJeff Brown
27911417b1cfde8f1749905f2d735623af9214148afJeff Brown        /**
28011417b1cfde8f1749905f2d735623af9214148afJeff Brown         * Adds the contents of an existing media route selector to the builder.
28111417b1cfde8f1749905f2d735623af9214148afJeff Brown         *
28211417b1cfde8f1749905f2d735623af9214148afJeff Brown         * @param selector The media route selector whose contents are to be added.
28311417b1cfde8f1749905f2d735623af9214148afJeff Brown         * @return The builder instance for chaining.
28411417b1cfde8f1749905f2d735623af9214148afJeff Brown         */
285429c3b17b88ebd8c4512e9179fd9d48333c0979eTor Norbye        @NonNull
286429c3b17b88ebd8c4512e9179fd9d48333c0979eTor Norbye        public Builder addSelector(@NonNull MediaRouteSelector selector) {
28711417b1cfde8f1749905f2d735623af9214148afJeff Brown            if (selector == null) {
28811417b1cfde8f1749905f2d735623af9214148afJeff Brown                throw new IllegalArgumentException("selector must not be null");
28911417b1cfde8f1749905f2d735623af9214148afJeff Brown            }
29011417b1cfde8f1749905f2d735623af9214148afJeff Brown
29111417b1cfde8f1749905f2d735623af9214148afJeff Brown            addControlCategories(selector.getControlCategories());
29211417b1cfde8f1749905f2d735623af9214148afJeff Brown            return this;
29311417b1cfde8f1749905f2d735623af9214148afJeff Brown        }
29411417b1cfde8f1749905f2d735623af9214148afJeff Brown
29511417b1cfde8f1749905f2d735623af9214148afJeff Brown        /**
29611417b1cfde8f1749905f2d735623af9214148afJeff Brown         * Builds the {@link MediaRouteSelector media route selector}.
29711417b1cfde8f1749905f2d735623af9214148afJeff Brown         */
298429c3b17b88ebd8c4512e9179fd9d48333c0979eTor Norbye        @NonNull
29911417b1cfde8f1749905f2d735623af9214148afJeff Brown        public MediaRouteSelector build() {
30011417b1cfde8f1749905f2d735623af9214148afJeff Brown            if (mControlCategories == null) {
30111417b1cfde8f1749905f2d735623af9214148afJeff Brown                return EMPTY;
30211417b1cfde8f1749905f2d735623af9214148afJeff Brown            }
30311417b1cfde8f1749905f2d735623af9214148afJeff Brown            Bundle bundle = new Bundle();
30411417b1cfde8f1749905f2d735623af9214148afJeff Brown            bundle.putStringArrayList(KEY_CONTROL_CATEGORIES, mControlCategories);
30511417b1cfde8f1749905f2d735623af9214148afJeff Brown            return new MediaRouteSelector(bundle, mControlCategories);
30611417b1cfde8f1749905f2d735623af9214148afJeff Brown        }
30711417b1cfde8f1749905f2d735623af9214148afJeff Brown    }
30811417b1cfde8f1749905f2d735623af9214148afJeff Brown}