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 17package android.support.v7.app; 18 19import android.os.Bundle; 20import android.support.v4.app.Fragment; 21import android.support.v7.media.MediaRouter; 22import android.support.v7.media.MediaRouteSelector; 23 24/** 25 * Media route discovery fragment. 26 * <p> 27 * This fragment takes care of registering a callback for media route discovery 28 * during the {@link Fragment#onStart onStart()} phase 29 * and removing it during the {@link Fragment#onStop onStop()} phase. 30 * </p><p> 31 * The application must supply a route selector to specify the kinds of routes 32 * to discover. The application may also override {@link #onCreateCallback} to 33 * provide the {@link MediaRouter} callback to register. 34 * </p><p> 35 * Note that the discovery callback makes the application be connected with all the 36 * {@link android.support.v7.media.MediaRouteProviderService media route provider services} 37 * while it is registered. 38 * </p> 39 */ 40public class MediaRouteDiscoveryFragment extends Fragment { 41 private final String ARGUMENT_SELECTOR = "selector"; 42 43 private MediaRouter mRouter; 44 private MediaRouteSelector mSelector; 45 private MediaRouter.Callback mCallback; 46 47 public MediaRouteDiscoveryFragment() { 48 } 49 50 /** 51 * Gets the media router instance. 52 */ 53 public MediaRouter getMediaRouter() { 54 ensureRouter(); 55 return mRouter; 56 } 57 58 private void ensureRouter() { 59 if (mRouter == null) { 60 mRouter = MediaRouter.getInstance(getContext()); 61 } 62 } 63 64 /** 65 * Gets the media route selector for filtering the routes to be discovered. 66 * 67 * @return The selector, never null. 68 */ 69 public MediaRouteSelector getRouteSelector() { 70 ensureRouteSelector(); 71 return mSelector; 72 } 73 74 /** 75 * Sets the media route selector for filtering the routes to be discovered. 76 * This method must be called before the fragment is added. 77 * 78 * @param selector The selector to set. 79 */ 80 public void setRouteSelector(MediaRouteSelector selector) { 81 if (selector == null) { 82 throw new IllegalArgumentException("selector must not be null"); 83 } 84 85 ensureRouteSelector(); 86 if (!mSelector.equals(selector)) { 87 mSelector = selector; 88 89 Bundle args = getArguments(); 90 if (args == null) { 91 args = new Bundle(); 92 } 93 args.putBundle(ARGUMENT_SELECTOR, selector.asBundle()); 94 setArguments(args); 95 96 if (mCallback != null) { 97 mRouter.removeCallback(mCallback); 98 mRouter.addCallback(mSelector, mCallback, onPrepareCallbackFlags()); 99 } 100 } 101 } 102 103 private void ensureRouteSelector() { 104 if (mSelector == null) { 105 Bundle args = getArguments(); 106 if (args != null) { 107 mSelector = MediaRouteSelector.fromBundle(args.getBundle(ARGUMENT_SELECTOR)); 108 } 109 if (mSelector == null) { 110 mSelector = MediaRouteSelector.EMPTY; 111 } 112 } 113 } 114 115 /** 116 * Called to create the {@link android.support.v7.media.MediaRouter.Callback callback} 117 * that will be registered. 118 * <p> 119 * The default callback does nothing. The application may override this method to 120 * supply its own callback. 121 * </p> 122 * 123 * @return The new callback, or null if no callback should be registered. 124 */ 125 public MediaRouter.Callback onCreateCallback() { 126 return new MediaRouter.Callback() { }; 127 } 128 129 /** 130 * Called to prepare the callback flags that will be used when the 131 * {@link android.support.v7.media.MediaRouter.Callback callback} is registered. 132 * <p> 133 * The default implementation returns {@link MediaRouter#CALLBACK_FLAG_REQUEST_DISCOVERY}. 134 * </p> 135 * 136 * @return The desired callback flags. 137 */ 138 public int onPrepareCallbackFlags() { 139 return MediaRouter.CALLBACK_FLAG_REQUEST_DISCOVERY; 140 } 141 142 @Override 143 public void onStart() { 144 super.onStart(); 145 146 ensureRouteSelector(); 147 ensureRouter(); 148 mCallback = onCreateCallback(); 149 if (mCallback != null) { 150 mRouter.addCallback(mSelector, mCallback, onPrepareCallbackFlags()); 151 } 152 } 153 154 @Override 155 public void onStop() { 156 if (mCallback != null) { 157 mRouter.removeCallback(mCallback); 158 mCallback = null; 159 } 160 161 super.onStop(); 162 } 163} 164