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;
2011417b1cfde8f1749905f2d735623af9214148afJeff Brown
2111417b1cfde8f1749905f2d735623af9214148afJeff Brownimport java.util.ArrayList;
2211417b1cfde8f1749905f2d735623af9214148afJeff Brownimport java.util.Arrays;
237599feee523c7b7d33576ae5825e43e3d62cbcbeJeff Brownimport java.util.Collection;
2411417b1cfde8f1749905f2d735623af9214148afJeff Brownimport java.util.Collections;
2511417b1cfde8f1749905f2d735623af9214148afJeff Brownimport java.util.List;
2611417b1cfde8f1749905f2d735623af9214148afJeff Brown
2711417b1cfde8f1749905f2d735623af9214148afJeff Brown/**
2811417b1cfde8f1749905f2d735623af9214148afJeff Brown * Describes the state of a media route provider and the routes that it publishes.
2911417b1cfde8f1749905f2d735623af9214148afJeff Brown * <p>
3011417b1cfde8f1749905f2d735623af9214148afJeff Brown * This object is immutable once created using a {@link Builder} instance.
3111417b1cfde8f1749905f2d735623af9214148afJeff Brown * </p>
3211417b1cfde8f1749905f2d735623af9214148afJeff Brown */
3311417b1cfde8f1749905f2d735623af9214148afJeff Brownpublic final class MediaRouteProviderDescriptor {
3411417b1cfde8f1749905f2d735623af9214148afJeff Brown    private static final String KEY_ROUTES = "routes";
3511417b1cfde8f1749905f2d735623af9214148afJeff Brown
3611417b1cfde8f1749905f2d735623af9214148afJeff Brown    private final Bundle mBundle;
3711417b1cfde8f1749905f2d735623af9214148afJeff Brown    private List<MediaRouteDescriptor> mRoutes;
3811417b1cfde8f1749905f2d735623af9214148afJeff Brown
3911417b1cfde8f1749905f2d735623af9214148afJeff Brown    private MediaRouteProviderDescriptor(Bundle bundle,
40d11aa1784335270b8d85e385f2c8be79ee6a586cJeff Brown            List<MediaRouteDescriptor> routes) {
4111417b1cfde8f1749905f2d735623af9214148afJeff Brown        mBundle = bundle;
4211417b1cfde8f1749905f2d735623af9214148afJeff Brown        mRoutes = routes;
4311417b1cfde8f1749905f2d735623af9214148afJeff Brown    }
4411417b1cfde8f1749905f2d735623af9214148afJeff Brown
4511417b1cfde8f1749905f2d735623af9214148afJeff Brown    /**
4611417b1cfde8f1749905f2d735623af9214148afJeff Brown     * Gets the list of all routes that this provider has published.
4711417b1cfde8f1749905f2d735623af9214148afJeff Brown     */
4811417b1cfde8f1749905f2d735623af9214148afJeff Brown    public List<MediaRouteDescriptor> getRoutes() {
4911417b1cfde8f1749905f2d735623af9214148afJeff Brown        ensureRoutes();
5011417b1cfde8f1749905f2d735623af9214148afJeff Brown        return mRoutes;
5111417b1cfde8f1749905f2d735623af9214148afJeff Brown    }
5211417b1cfde8f1749905f2d735623af9214148afJeff Brown
5311417b1cfde8f1749905f2d735623af9214148afJeff Brown    private void ensureRoutes() {
5411417b1cfde8f1749905f2d735623af9214148afJeff Brown        if (mRoutes == null) {
5511417b1cfde8f1749905f2d735623af9214148afJeff Brown            ArrayList<Bundle> routeBundles = mBundle.<Bundle>getParcelableArrayList(KEY_ROUTES);
5611417b1cfde8f1749905f2d735623af9214148afJeff Brown            if (routeBundles == null || routeBundles.isEmpty()) {
5711417b1cfde8f1749905f2d735623af9214148afJeff Brown                mRoutes = Collections.<MediaRouteDescriptor>emptyList();
5811417b1cfde8f1749905f2d735623af9214148afJeff Brown            } else {
5911417b1cfde8f1749905f2d735623af9214148afJeff Brown                final int count = routeBundles.size();
6011417b1cfde8f1749905f2d735623af9214148afJeff Brown                mRoutes = new ArrayList<MediaRouteDescriptor>(count);
6111417b1cfde8f1749905f2d735623af9214148afJeff Brown                for (int i = 0; i < count; i++) {
6211417b1cfde8f1749905f2d735623af9214148afJeff Brown                    mRoutes.add(MediaRouteDescriptor.fromBundle(routeBundles.get(i)));
6311417b1cfde8f1749905f2d735623af9214148afJeff Brown                }
6411417b1cfde8f1749905f2d735623af9214148afJeff Brown            }
6511417b1cfde8f1749905f2d735623af9214148afJeff Brown        }
6611417b1cfde8f1749905f2d735623af9214148afJeff Brown    }
6711417b1cfde8f1749905f2d735623af9214148afJeff Brown
6811417b1cfde8f1749905f2d735623af9214148afJeff Brown    /**
6911417b1cfde8f1749905f2d735623af9214148afJeff Brown     * Returns true if the route provider descriptor and all of the routes that
7011417b1cfde8f1749905f2d735623af9214148afJeff Brown     * it contains have all of the required fields.
7111417b1cfde8f1749905f2d735623af9214148afJeff Brown     * <p>
7211417b1cfde8f1749905f2d735623af9214148afJeff Brown     * This verification is deep.  If the provider descriptor is known to be
7311417b1cfde8f1749905f2d735623af9214148afJeff Brown     * valid then it is not necessary to call {@link #isValid} on each of its routes.
7411417b1cfde8f1749905f2d735623af9214148afJeff Brown     * </p>
7511417b1cfde8f1749905f2d735623af9214148afJeff Brown     */
7611417b1cfde8f1749905f2d735623af9214148afJeff Brown    public boolean isValid() {
7711417b1cfde8f1749905f2d735623af9214148afJeff Brown        ensureRoutes();
7811417b1cfde8f1749905f2d735623af9214148afJeff Brown        final int routeCount = mRoutes.size();
7911417b1cfde8f1749905f2d735623af9214148afJeff Brown        for (int i = 0; i < routeCount; i++) {
8011417b1cfde8f1749905f2d735623af9214148afJeff Brown            MediaRouteDescriptor route = mRoutes.get(i);
8111417b1cfde8f1749905f2d735623af9214148afJeff Brown            if (route == null || !route.isValid()) {
8211417b1cfde8f1749905f2d735623af9214148afJeff Brown                return false;
8311417b1cfde8f1749905f2d735623af9214148afJeff Brown            }
8411417b1cfde8f1749905f2d735623af9214148afJeff Brown        }
8511417b1cfde8f1749905f2d735623af9214148afJeff Brown        return true;
8611417b1cfde8f1749905f2d735623af9214148afJeff Brown    }
8711417b1cfde8f1749905f2d735623af9214148afJeff Brown
8811417b1cfde8f1749905f2d735623af9214148afJeff Brown    @Override
8911417b1cfde8f1749905f2d735623af9214148afJeff Brown    public String toString() {
9011417b1cfde8f1749905f2d735623af9214148afJeff Brown        StringBuilder result = new StringBuilder();
9111417b1cfde8f1749905f2d735623af9214148afJeff Brown        result.append("MediaRouteProviderDescriptor{ ");
92d11aa1784335270b8d85e385f2c8be79ee6a586cJeff Brown        result.append("routes=").append(
9311417b1cfde8f1749905f2d735623af9214148afJeff Brown                Arrays.toString(getRoutes().toArray()));
9411417b1cfde8f1749905f2d735623af9214148afJeff Brown        result.append(", isValid=").append(isValid());
953d4c9459ed77f732dd3ba602713af6ebf9280c8cJeff Brown        result.append(" }");
9611417b1cfde8f1749905f2d735623af9214148afJeff Brown        return result.toString();
9711417b1cfde8f1749905f2d735623af9214148afJeff Brown    }
9811417b1cfde8f1749905f2d735623af9214148afJeff Brown
9911417b1cfde8f1749905f2d735623af9214148afJeff Brown    /**
10011417b1cfde8f1749905f2d735623af9214148afJeff Brown     * Converts this object to a bundle for serialization.
10111417b1cfde8f1749905f2d735623af9214148afJeff Brown     *
10211417b1cfde8f1749905f2d735623af9214148afJeff Brown     * @return The contents of the object represented as a bundle.
10311417b1cfde8f1749905f2d735623af9214148afJeff Brown     */
10411417b1cfde8f1749905f2d735623af9214148afJeff Brown    public Bundle asBundle() {
10511417b1cfde8f1749905f2d735623af9214148afJeff Brown        return mBundle;
10611417b1cfde8f1749905f2d735623af9214148afJeff Brown    }
10711417b1cfde8f1749905f2d735623af9214148afJeff Brown
10811417b1cfde8f1749905f2d735623af9214148afJeff Brown    /**
10911417b1cfde8f1749905f2d735623af9214148afJeff Brown     * Creates an instance from a bundle.
11011417b1cfde8f1749905f2d735623af9214148afJeff Brown     *
11111417b1cfde8f1749905f2d735623af9214148afJeff Brown     * @param bundle The bundle, or null if none.
11211417b1cfde8f1749905f2d735623af9214148afJeff Brown     * @return The new instance, or null if the bundle was null.
11311417b1cfde8f1749905f2d735623af9214148afJeff Brown     */
11411417b1cfde8f1749905f2d735623af9214148afJeff Brown    public static MediaRouteProviderDescriptor fromBundle(Bundle bundle) {
115d11aa1784335270b8d85e385f2c8be79ee6a586cJeff Brown        return bundle != null ? new MediaRouteProviderDescriptor(bundle, null) : null;
11611417b1cfde8f1749905f2d735623af9214148afJeff Brown    }
11711417b1cfde8f1749905f2d735623af9214148afJeff Brown
11811417b1cfde8f1749905f2d735623af9214148afJeff Brown    /**
11911417b1cfde8f1749905f2d735623af9214148afJeff Brown     * Builder for {@link MediaRouteProviderDescriptor media route provider descriptors}.
12011417b1cfde8f1749905f2d735623af9214148afJeff Brown     */
12111417b1cfde8f1749905f2d735623af9214148afJeff Brown    public static final class Builder {
12211417b1cfde8f1749905f2d735623af9214148afJeff Brown        private final Bundle mBundle;
12311417b1cfde8f1749905f2d735623af9214148afJeff Brown        private ArrayList<MediaRouteDescriptor> mRoutes;
12411417b1cfde8f1749905f2d735623af9214148afJeff Brown
12511417b1cfde8f1749905f2d735623af9214148afJeff Brown        /**
12611417b1cfde8f1749905f2d735623af9214148afJeff Brown         * Creates an empty media route provider descriptor builder.
12711417b1cfde8f1749905f2d735623af9214148afJeff Brown         */
12811417b1cfde8f1749905f2d735623af9214148afJeff Brown        public Builder() {
12911417b1cfde8f1749905f2d735623af9214148afJeff Brown            mBundle = new Bundle();
13011417b1cfde8f1749905f2d735623af9214148afJeff Brown        }
13111417b1cfde8f1749905f2d735623af9214148afJeff Brown
13211417b1cfde8f1749905f2d735623af9214148afJeff Brown        /**
13311417b1cfde8f1749905f2d735623af9214148afJeff Brown         * Creates a media route provider descriptor builder whose initial contents are
13411417b1cfde8f1749905f2d735623af9214148afJeff Brown         * copied from an existing descriptor.
13511417b1cfde8f1749905f2d735623af9214148afJeff Brown         */
13611417b1cfde8f1749905f2d735623af9214148afJeff Brown        public Builder(MediaRouteProviderDescriptor descriptor) {
13711417b1cfde8f1749905f2d735623af9214148afJeff Brown            if (descriptor == null) {
13811417b1cfde8f1749905f2d735623af9214148afJeff Brown                throw new IllegalArgumentException("descriptor must not be null");
13911417b1cfde8f1749905f2d735623af9214148afJeff Brown            }
14011417b1cfde8f1749905f2d735623af9214148afJeff Brown
14111417b1cfde8f1749905f2d735623af9214148afJeff Brown            mBundle = new Bundle(descriptor.mBundle);
14211417b1cfde8f1749905f2d735623af9214148afJeff Brown
14311417b1cfde8f1749905f2d735623af9214148afJeff Brown            descriptor.ensureRoutes();
14411417b1cfde8f1749905f2d735623af9214148afJeff Brown            if (!descriptor.mRoutes.isEmpty()) {
14511417b1cfde8f1749905f2d735623af9214148afJeff Brown                mRoutes = new ArrayList<MediaRouteDescriptor>(descriptor.mRoutes);
14611417b1cfde8f1749905f2d735623af9214148afJeff Brown            }
14711417b1cfde8f1749905f2d735623af9214148afJeff Brown        }
14811417b1cfde8f1749905f2d735623af9214148afJeff Brown
14911417b1cfde8f1749905f2d735623af9214148afJeff Brown        /**
15011417b1cfde8f1749905f2d735623af9214148afJeff Brown         * Adds a route.
15111417b1cfde8f1749905f2d735623af9214148afJeff Brown         */
15211417b1cfde8f1749905f2d735623af9214148afJeff Brown        public Builder addRoute(MediaRouteDescriptor route) {
15311417b1cfde8f1749905f2d735623af9214148afJeff Brown            if (route == null) {
15411417b1cfde8f1749905f2d735623af9214148afJeff Brown                throw new IllegalArgumentException("route must not be null");
15511417b1cfde8f1749905f2d735623af9214148afJeff Brown            }
15611417b1cfde8f1749905f2d735623af9214148afJeff Brown
15711417b1cfde8f1749905f2d735623af9214148afJeff Brown            if (mRoutes == null) {
15811417b1cfde8f1749905f2d735623af9214148afJeff Brown                mRoutes = new ArrayList<MediaRouteDescriptor>();
15911417b1cfde8f1749905f2d735623af9214148afJeff Brown            } else if (mRoutes.contains(route)) {
16011417b1cfde8f1749905f2d735623af9214148afJeff Brown                throw new IllegalArgumentException("route descriptor already added");
16111417b1cfde8f1749905f2d735623af9214148afJeff Brown            }
16211417b1cfde8f1749905f2d735623af9214148afJeff Brown            mRoutes.add(route);
16311417b1cfde8f1749905f2d735623af9214148afJeff Brown            return this;
16411417b1cfde8f1749905f2d735623af9214148afJeff Brown        }
16511417b1cfde8f1749905f2d735623af9214148afJeff Brown
16611417b1cfde8f1749905f2d735623af9214148afJeff Brown        /**
16711417b1cfde8f1749905f2d735623af9214148afJeff Brown         * Adds a list of routes.
16811417b1cfde8f1749905f2d735623af9214148afJeff Brown         */
1697599feee523c7b7d33576ae5825e43e3d62cbcbeJeff Brown        public Builder addRoutes(Collection<MediaRouteDescriptor> routes) {
17011417b1cfde8f1749905f2d735623af9214148afJeff Brown            if (routes == null) {
17111417b1cfde8f1749905f2d735623af9214148afJeff Brown                throw new IllegalArgumentException("routes must not be null");
17211417b1cfde8f1749905f2d735623af9214148afJeff Brown            }
17311417b1cfde8f1749905f2d735623af9214148afJeff Brown
1747599feee523c7b7d33576ae5825e43e3d62cbcbeJeff Brown            if (!routes.isEmpty()) {
1757599feee523c7b7d33576ae5825e43e3d62cbcbeJeff Brown                for (MediaRouteDescriptor route : routes) {
1767599feee523c7b7d33576ae5825e43e3d62cbcbeJeff Brown                    addRoute(route);
1777599feee523c7b7d33576ae5825e43e3d62cbcbeJeff Brown                }
17811417b1cfde8f1749905f2d735623af9214148afJeff Brown            }
17911417b1cfde8f1749905f2d735623af9214148afJeff Brown            return this;
18011417b1cfde8f1749905f2d735623af9214148afJeff Brown        }
18111417b1cfde8f1749905f2d735623af9214148afJeff Brown
18211417b1cfde8f1749905f2d735623af9214148afJeff Brown        /**
18311417b1cfde8f1749905f2d735623af9214148afJeff Brown         * Builds the {@link MediaRouteProviderDescriptor media route provider descriptor}.
18411417b1cfde8f1749905f2d735623af9214148afJeff Brown         */
18511417b1cfde8f1749905f2d735623af9214148afJeff Brown        public MediaRouteProviderDescriptor build() {
18611417b1cfde8f1749905f2d735623af9214148afJeff Brown            if (mRoutes != null) {
18711417b1cfde8f1749905f2d735623af9214148afJeff Brown                final int count = mRoutes.size();
18811417b1cfde8f1749905f2d735623af9214148afJeff Brown                ArrayList<Bundle> routeBundles = new ArrayList<Bundle>(count);
18911417b1cfde8f1749905f2d735623af9214148afJeff Brown                for (int i = 0; i < count; i++) {
19011417b1cfde8f1749905f2d735623af9214148afJeff Brown                    routeBundles.add(mRoutes.get(i).asBundle());
19111417b1cfde8f1749905f2d735623af9214148afJeff Brown                }
19211417b1cfde8f1749905f2d735623af9214148afJeff Brown                mBundle.putParcelableArrayList(KEY_ROUTES, routeBundles);
19311417b1cfde8f1749905f2d735623af9214148afJeff Brown            }
194d11aa1784335270b8d85e385f2c8be79ee6a586cJeff Brown            return new MediaRouteProviderDescriptor(mBundle, mRoutes);
19511417b1cfde8f1749905f2d735623af9214148afJeff Brown        }
19611417b1cfde8f1749905f2d735623af9214148afJeff Brown    }
19711417b1cfde8f1749905f2d735623af9214148afJeff Brown}