1 /*
2  * Copyright (C) 2013 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package android.support.v7.media;
17 
18 import android.content.IntentFilter;
19 import android.os.Bundle;
20 
21 import java.util.ArrayList;
22 import java.util.Arrays;
23 import java.util.Collection;
24 import java.util.Collections;
25 import java.util.List;
26 
27 /**
28  * Describes the state of a media route provider and the routes that it publishes.
29  * <p>
30  * This object is immutable once created using a {@link Builder} instance.
31  * </p>
32  */
33 public final class MediaRouteProviderDescriptor {
34     private static final String KEY_ROUTES = "routes";
35 
36     private final Bundle mBundle;
37     private List<MediaRouteDescriptor> mRoutes;
38 
MediaRouteProviderDescriptor(Bundle bundle, List<MediaRouteDescriptor> routes)39     private MediaRouteProviderDescriptor(Bundle bundle,
40             List<MediaRouteDescriptor> routes) {
41         mBundle = bundle;
42         mRoutes = routes;
43     }
44 
45     /**
46      * Gets the list of all routes that this provider has published.
47      */
getRoutes()48     public List<MediaRouteDescriptor> getRoutes() {
49         ensureRoutes();
50         return mRoutes;
51     }
52 
ensureRoutes()53     private void ensureRoutes() {
54         if (mRoutes == null) {
55             ArrayList<Bundle> routeBundles = mBundle.<Bundle>getParcelableArrayList(KEY_ROUTES);
56             if (routeBundles == null || routeBundles.isEmpty()) {
57                 mRoutes = Collections.<MediaRouteDescriptor>emptyList();
58             } else {
59                 final int count = routeBundles.size();
60                 mRoutes = new ArrayList<MediaRouteDescriptor>(count);
61                 for (int i = 0; i < count; i++) {
62                     mRoutes.add(MediaRouteDescriptor.fromBundle(routeBundles.get(i)));
63                 }
64             }
65         }
66     }
67 
68     /**
69      * Returns true if the route provider descriptor and all of the routes that
70      * it contains have all of the required fields.
71      * <p>
72      * This verification is deep.  If the provider descriptor is known to be
73      * valid then it is not necessary to call {@link #isValid} on each of its routes.
74      * </p>
75      */
isValid()76     public boolean isValid() {
77         ensureRoutes();
78         final int routeCount = mRoutes.size();
79         for (int i = 0; i < routeCount; i++) {
80             MediaRouteDescriptor route = mRoutes.get(i);
81             if (route == null || !route.isValid()) {
82                 return false;
83             }
84         }
85         return true;
86     }
87 
88     @Override
toString()89     public String toString() {
90         StringBuilder result = new StringBuilder();
91         result.append("MediaRouteProviderDescriptor{ ");
92         result.append("routes=").append(
93                 Arrays.toString(getRoutes().toArray()));
94         result.append(", isValid=").append(isValid());
95         result.append(" }");
96         return result.toString();
97     }
98 
99     /**
100      * Converts this object to a bundle for serialization.
101      *
102      * @return The contents of the object represented as a bundle.
103      */
asBundle()104     public Bundle asBundle() {
105         return mBundle;
106     }
107 
108     /**
109      * Creates an instance from a bundle.
110      *
111      * @param bundle The bundle, or null if none.
112      * @return The new instance, or null if the bundle was null.
113      */
fromBundle(Bundle bundle)114     public static MediaRouteProviderDescriptor fromBundle(Bundle bundle) {
115         return bundle != null ? new MediaRouteProviderDescriptor(bundle, null) : null;
116     }
117 
118     /**
119      * Builder for {@link MediaRouteProviderDescriptor media route provider descriptors}.
120      */
121     public static final class Builder {
122         private final Bundle mBundle;
123         private ArrayList<MediaRouteDescriptor> mRoutes;
124 
125         /**
126          * Creates an empty media route provider descriptor builder.
127          */
Builder()128         public Builder() {
129             mBundle = new Bundle();
130         }
131 
132         /**
133          * Creates a media route provider descriptor builder whose initial contents are
134          * copied from an existing descriptor.
135          */
Builder(MediaRouteProviderDescriptor descriptor)136         public Builder(MediaRouteProviderDescriptor descriptor) {
137             if (descriptor == null) {
138                 throw new IllegalArgumentException("descriptor must not be null");
139             }
140 
141             mBundle = new Bundle(descriptor.mBundle);
142 
143             descriptor.ensureRoutes();
144             if (!descriptor.mRoutes.isEmpty()) {
145                 mRoutes = new ArrayList<MediaRouteDescriptor>(descriptor.mRoutes);
146             }
147         }
148 
149         /**
150          * Adds a route.
151          */
addRoute(MediaRouteDescriptor route)152         public Builder addRoute(MediaRouteDescriptor route) {
153             if (route == null) {
154                 throw new IllegalArgumentException("route must not be null");
155             }
156 
157             if (mRoutes == null) {
158                 mRoutes = new ArrayList<MediaRouteDescriptor>();
159             } else if (mRoutes.contains(route)) {
160                 throw new IllegalArgumentException("route descriptor already added");
161             }
162             mRoutes.add(route);
163             return this;
164         }
165 
166         /**
167          * Adds a list of routes.
168          */
addRoutes(Collection<MediaRouteDescriptor> routes)169         public Builder addRoutes(Collection<MediaRouteDescriptor> routes) {
170             if (routes == null) {
171                 throw new IllegalArgumentException("routes must not be null");
172             }
173 
174             if (!routes.isEmpty()) {
175                 for (MediaRouteDescriptor route : routes) {
176                     addRoute(route);
177                 }
178             }
179             return this;
180         }
181 
182         /**
183          * Builds the {@link MediaRouteProviderDescriptor media route provider descriptor}.
184          */
build()185         public MediaRouteProviderDescriptor build() {
186             if (mRoutes != null) {
187                 final int count = mRoutes.size();
188                 ArrayList<Bundle> routeBundles = new ArrayList<Bundle>(count);
189                 for (int i = 0; i < count; i++) {
190                     routeBundles.add(mRoutes.get(i).asBundle());
191                 }
192                 mBundle.putParcelableArrayList(KEY_ROUTES, routeBundles);
193             }
194             return new MediaRouteProviderDescriptor(mBundle, mRoutes);
195         }
196     }
197 }