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 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 */ 48 public List<MediaRouteDescriptor> getRoutes() { 49 ensureRoutes(); 50 return mRoutes; 51 } 52 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 */ 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 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 }