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