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