Home | History | Annotate | Download | only in media
      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.media;
     18 
     19 import android.content.Context;
     20 import android.content.Intent;
     21 import android.media.browse.MediaBrowser;
     22 import android.media.session.MediaSession;
     23 import android.os.Bundle;
     24 import android.os.IBinder;
     25 import android.os.Parcel;
     26 import android.service.media.MediaBrowserService;
     27 
     28 import androidx.annotation.RequiresApi;
     29 
     30 import java.util.ArrayList;
     31 import java.util.List;
     32 
     33 @RequiresApi(21)
     34 class MediaBrowserServiceCompatApi21 {
     35 
     36     public static Object createService(Context context, ServiceCompatProxy serviceProxy) {
     37         return new MediaBrowserServiceAdaptor(context, serviceProxy);
     38     }
     39 
     40     public static void onCreate(Object serviceObj) {
     41         ((MediaBrowserService) serviceObj).onCreate();
     42     }
     43 
     44     public static IBinder onBind(Object serviceObj, Intent intent) {
     45         return ((MediaBrowserService) serviceObj).onBind(intent);
     46     }
     47 
     48     public static void setSessionToken(Object serviceObj, Object token) {
     49         ((MediaBrowserService) serviceObj).setSessionToken((MediaSession.Token) token);
     50     }
     51 
     52     public static void notifyChildrenChanged(Object serviceObj, String parentId) {
     53         ((MediaBrowserService) serviceObj).notifyChildrenChanged(parentId);
     54     }
     55 
     56     public interface ServiceCompatProxy {
     57         BrowserRoot onGetRoot(String clientPackageName, int clientUid, Bundle rootHints);
     58         void onLoadChildren(String parentId, ResultWrapper<List<Parcel>> result);
     59     }
     60 
     61     static class ResultWrapper<T> {
     62         MediaBrowserService.Result mResultObj;
     63 
     64         ResultWrapper(MediaBrowserService.Result result) {
     65             mResultObj = result;
     66         }
     67 
     68         public void sendResult(T result) {
     69             if (result instanceof List) {
     70                 mResultObj.sendResult(parcelListToItemList((List<Parcel>)result));
     71             } else if (result instanceof Parcel) {
     72                 Parcel parcel = (Parcel) result;
     73                 parcel.setDataPosition(0);
     74                 mResultObj.sendResult(MediaBrowser.MediaItem.CREATOR.createFromParcel(parcel));
     75                 parcel.recycle();
     76             } else {
     77                 // The result is null or an invalid instance.
     78                 mResultObj.sendResult(null);
     79             }
     80         }
     81 
     82         public void detach() {
     83             mResultObj.detach();
     84         }
     85 
     86         List<MediaBrowser.MediaItem> parcelListToItemList(List<Parcel> parcelList) {
     87             if (parcelList == null) {
     88                 return null;
     89             }
     90             List<MediaBrowser.MediaItem> items = new ArrayList<>();
     91             for (Parcel parcel : parcelList) {
     92                 parcel.setDataPosition(0);
     93                 items.add(MediaBrowser.MediaItem.CREATOR.createFromParcel(parcel));
     94                 parcel.recycle();
     95             }
     96             return items;
     97         }
     98     }
     99 
    100     static class BrowserRoot {
    101         final String mRootId;
    102         final Bundle mExtras;
    103 
    104         BrowserRoot(String rootId, Bundle extras) {
    105             mRootId = rootId;
    106             mExtras = extras;
    107         }
    108     }
    109 
    110     static class MediaBrowserServiceAdaptor extends MediaBrowserService {
    111         final ServiceCompatProxy mServiceProxy;
    112 
    113         MediaBrowserServiceAdaptor(Context context, ServiceCompatProxy serviceWrapper) {
    114             attachBaseContext(context);
    115             mServiceProxy = serviceWrapper;
    116         }
    117 
    118         @Override
    119         public MediaBrowserService.BrowserRoot onGetRoot(String clientPackageName, int clientUid,
    120                 Bundle rootHints) {
    121             MediaBrowserServiceCompatApi21.BrowserRoot browserRoot = mServiceProxy.onGetRoot(
    122                     clientPackageName, clientUid, rootHints == null ? null : new Bundle(rootHints));
    123             return browserRoot == null ? null : new MediaBrowserService.BrowserRoot(
    124                     browserRoot.mRootId, browserRoot.mExtras);
    125         }
    126 
    127         @Override
    128         public void onLoadChildren(String parentId, Result<List<MediaBrowser.MediaItem>> result) {
    129             mServiceProxy.onLoadChildren(parentId, new ResultWrapper<List<Parcel>>(result));
    130         }
    131     }
    132 
    133     private MediaBrowserServiceCompatApi21() {
    134     }
    135 }
    136