Home | History | Annotate | Download | only in app
      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