1692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim/* 2692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * Copyright 2018 The Android Open Source Project 3692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * 4692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * Licensed under the Apache License, Version 2.0 (the "License"); 5692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * you may not use this file except in compliance with the License. 6692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * You may obtain a copy of the License at 7692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * 8692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * http://www.apache.org/licenses/LICENSE-2.0 9692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * 10692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * Unless required by applicable law or agreed to in writing, software 11692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * distributed under the License is distributed on an "AS IS" BASIS, 12692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * See the License for the specific language governing permissions and 14692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * limitations under the License. 15692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim */ 16692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limpackage com.android.support.mediarouter.media; 17692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 18692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limimport android.os.Bundle; 19692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 20692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limimport java.util.ArrayList; 21692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limimport java.util.Arrays; 22692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limimport java.util.Collection; 23692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limimport java.util.Collections; 24692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limimport java.util.List; 25692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 26692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim/** 27692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * Describes the state of a media route provider and the routes that it publishes. 28692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * <p> 29692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * This object is immutable once created using a {@link Builder} instance. 30692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * </p> 31692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim */ 32692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limpublic final class MediaRouteProviderDescriptor { 33692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim private static final String KEY_ROUTES = "routes"; 34692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 35692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim private final Bundle mBundle; 36692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim private List<MediaRouteDescriptor> mRoutes; 37692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 38692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim private MediaRouteProviderDescriptor(Bundle bundle, List<MediaRouteDescriptor> routes) { 39692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mBundle = bundle; 40692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mRoutes = routes; 41692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 42692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 43692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim /** 44692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * Gets the list of all routes that this provider has published. 45692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim */ 46692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim public List<MediaRouteDescriptor> getRoutes() { 47692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim ensureRoutes(); 48692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim return mRoutes; 49692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 50692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 51692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim private void ensureRoutes() { 52692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (mRoutes == null) { 53692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim ArrayList<Bundle> routeBundles = mBundle.<Bundle>getParcelableArrayList(KEY_ROUTES); 54692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (routeBundles == null || routeBundles.isEmpty()) { 55692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mRoutes = Collections.<MediaRouteDescriptor>emptyList(); 56692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } else { 57692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim final int count = routeBundles.size(); 58692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mRoutes = new ArrayList<MediaRouteDescriptor>(count); 59692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim for (int i = 0; i < count; i++) { 60692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mRoutes.add(MediaRouteDescriptor.fromBundle(routeBundles.get(i))); 61692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 62692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 63692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 64692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 65692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 66692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim /** 67692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * Returns true if the route provider descriptor and all of the routes that 68692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * it contains have all of the required fields. 69692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * <p> 70692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * This verification is deep. If the provider descriptor is known to be 71692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * valid then it is not necessary to call {@link #isValid} on each of its routes. 72692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * </p> 73692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim */ 74692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim public boolean isValid() { 75692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim ensureRoutes(); 76692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim final int routeCount = mRoutes.size(); 77692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim for (int i = 0; i < routeCount; i++) { 78692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim MediaRouteDescriptor route = mRoutes.get(i); 79692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (route == null || !route.isValid()) { 80692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim return false; 81692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 82692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 83692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim return true; 84692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 85692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 86692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim @Override 87692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim public String toString() { 88692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim StringBuilder result = new StringBuilder(); 89692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim result.append("MediaRouteProviderDescriptor{ "); 90692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim result.append("routes=").append( 91692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim Arrays.toString(getRoutes().toArray())); 92692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim result.append(", isValid=").append(isValid()); 93692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim result.append(" }"); 94692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim return result.toString(); 95692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 96692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 97692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim /** 98692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * Converts this object to a bundle for serialization. 99692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * 100692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * @return The contents of the object represented as a bundle. 101692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim */ 102692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim public Bundle asBundle() { 103692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim return mBundle; 104692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 105692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 106692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim /** 107692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * Creates an instance from a bundle. 108692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * 109692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * @param bundle The bundle, or null if none. 110692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * @return The new instance, or null if the bundle was null. 111692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim */ 112692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim public static MediaRouteProviderDescriptor fromBundle(Bundle bundle) { 113692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim return bundle != null ? new MediaRouteProviderDescriptor(bundle, null) : null; 114692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 115692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 116692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim /** 117692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * Builder for {@link MediaRouteProviderDescriptor media route provider descriptors}. 118692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim */ 119692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim public static final class Builder { 120692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim private final Bundle mBundle; 121692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim private ArrayList<MediaRouteDescriptor> mRoutes; 122692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 123692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim /** 124692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * Creates an empty media route provider descriptor builder. 125692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim */ 126692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim public Builder() { 127692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mBundle = new Bundle(); 128692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 129692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 130692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim /** 131692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * Creates a media route provider descriptor builder whose initial contents are 132692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * copied from an existing descriptor. 133692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim */ 134692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim public Builder(MediaRouteProviderDescriptor descriptor) { 135692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (descriptor == null) { 136692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim throw new IllegalArgumentException("descriptor must not be null"); 137692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 138692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 139692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mBundle = new Bundle(descriptor.mBundle); 140692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 141692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim descriptor.ensureRoutes(); 142692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (!descriptor.mRoutes.isEmpty()) { 143692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mRoutes = new ArrayList<MediaRouteDescriptor>(descriptor.mRoutes); 144692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 145692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 146692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 147692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim /** 148692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * Adds a route. 149692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim */ 150692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim public Builder addRoute(MediaRouteDescriptor route) { 151692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (route == null) { 152692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim throw new IllegalArgumentException("route must not be null"); 153692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 154692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 155692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (mRoutes == null) { 156692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mRoutes = new ArrayList<MediaRouteDescriptor>(); 157692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } else if (mRoutes.contains(route)) { 158692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim throw new IllegalArgumentException("route descriptor already added"); 159692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 160692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mRoutes.add(route); 161692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim return this; 162692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 163692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 164692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim /** 165692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * Adds a list of routes. 166692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim */ 167692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim public Builder addRoutes(Collection<MediaRouteDescriptor> routes) { 168692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (routes == null) { 169692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim throw new IllegalArgumentException("routes must not be null"); 170692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 171692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 172692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (!routes.isEmpty()) { 173692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim for (MediaRouteDescriptor route : routes) { 174692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim addRoute(route); 175692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 176692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 177692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim return this; 178692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 179692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 180692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim /** 181692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * Sets the list of routes. 182692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim */ 183692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim Builder setRoutes(Collection<MediaRouteDescriptor> routes) { 184692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (routes == null || routes.isEmpty()) { 185692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mRoutes = null; 186692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mBundle.remove(KEY_ROUTES); 187692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } else { 188692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mRoutes = new ArrayList<>(routes); 189692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 190692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim return this; 191692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 192692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 193692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim /** 194692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * Builds the {@link MediaRouteProviderDescriptor media route provider descriptor}. 195692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim */ 196692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim public MediaRouteProviderDescriptor build() { 197692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (mRoutes != null) { 198692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim final int count = mRoutes.size(); 199692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim ArrayList<Bundle> routeBundles = new ArrayList<Bundle>(count); 200692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim for (int i = 0; i < count; i++) { 201692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim routeBundles.add(mRoutes.get(i).asBundle()); 202692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 203692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mBundle.putParcelableArrayList(KEY_ROUTES, routeBundles); 204692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 205692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim return new MediaRouteProviderDescriptor(mBundle, mRoutes); 206692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 207692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 208692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim}