1900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim/* 2ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * Copyright 2018 The Android Open Source Project 3900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim * 4900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim * Licensed under the Apache License, Version 2.0 (the "License"); 5900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim * you may not use this file except in compliance with the License. 6900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim * You may obtain a copy of the License at 7900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim * 8900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim * http://www.apache.org/licenses/LICENSE-2.0 9900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim * 10900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim * Unless required by applicable law or agreed to in writing, software 11900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim * distributed under the License is distributed on an "AS IS" BASIS, 12900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim * See the License for the specific language governing permissions and 14900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim * limitations under the License. 15900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim */ 16900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim 17ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikaspackage androidx.media; 18900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim 19900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Limimport android.content.Context; 20900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Limimport android.media.browse.MediaBrowser; 21900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Limimport android.os.Bundle; 22900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Limimport android.os.Parcel; 23900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Limimport android.service.media.MediaBrowserService; 24900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Limimport android.util.Log; 25900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim 2689febf83e2bd3720923474006bcdf6c91a3b88f2Aurimas Liutikasimport androidx.annotation.RequiresApi; 2789febf83e2bd3720923474006bcdf6c91a3b88f2Aurimas Liutikas 28900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Limimport java.lang.reflect.Field; 29900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Limimport java.util.ArrayList; 30900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Limimport java.util.List; 31900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim 32676cb6f1bd11b891d635119dca90d67ad380cbd0Hyundo Moon@RequiresApi(26) 33676cb6f1bd11b891d635119dca90d67ad380cbd0Hyundo Moonclass MediaBrowserServiceCompatApi26 { 34676cb6f1bd11b891d635119dca90d67ad380cbd0Hyundo Moon private static final String TAG = "MBSCompatApi26"; 35900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim 36900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim private static Field sResultFlags; 37900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim static { 38900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim try { 39900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim sResultFlags = MediaBrowserService.Result.class.getDeclaredField("mFlags"); 40900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim sResultFlags.setAccessible(true); 41900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim } catch (NoSuchFieldException e) { 42900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim Log.w(TAG, e); 43900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim } 44900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim } 45900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim 46900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim public static Object createService(Context context, ServiceCompatProxy serviceProxy) { 47900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim return new MediaBrowserServiceAdaptor(context, serviceProxy); 48900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim } 49900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim 50900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim public static void notifyChildrenChanged(Object serviceObj, String parentId, Bundle options) { 51900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim ((MediaBrowserService) serviceObj).notifyChildrenChanged(parentId, options); 52900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim } 53900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim 54fda621da7916073852394d14fcd2cb37f202287dSungsoo Lim public static Bundle getBrowserRootHints(Object serviceObj) { 55fda621da7916073852394d14fcd2cb37f202287dSungsoo Lim return ((MediaBrowserService) serviceObj).getBrowserRootHints(); 56fda621da7916073852394d14fcd2cb37f202287dSungsoo Lim } 57fda621da7916073852394d14fcd2cb37f202287dSungsoo Lim 582e7d3a28e00195c160cc4f5668e2d7f64eb590daSungsoo Lim public interface ServiceCompatProxy extends MediaBrowserServiceCompatApi23.ServiceCompatProxy { 59900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim void onLoadChildren(String parentId, ResultWrapper result, Bundle options); 60900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim } 61900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim 62900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim static class ResultWrapper { 63900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim MediaBrowserService.Result mResultObj; 64900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim 65900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim ResultWrapper(MediaBrowserService.Result result) { 66900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim mResultObj = result; 67900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim } 68900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim 69900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim public void sendResult(List<Parcel> result, int flags) { 70900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim try { 71900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim sResultFlags.setInt(mResultObj, flags); 72900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim } catch (IllegalAccessException e) { 73900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim Log.w(TAG, e); 74900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim } 75900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim mResultObj.sendResult(parcelListToItemList(result)); 76900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim } 77900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim 78900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim public void detach() { 79900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim mResultObj.detach(); 80900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim } 81900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim 82900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim List<MediaBrowser.MediaItem> parcelListToItemList(List<Parcel> parcelList) { 83900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim if (parcelList == null) { 84900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim return null; 85900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim } 86900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim List<MediaBrowser.MediaItem> items = new ArrayList<>(); 87900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim for (Parcel parcel : parcelList) { 88900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim parcel.setDataPosition(0); 89900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim items.add(MediaBrowser.MediaItem.CREATOR.createFromParcel(parcel)); 90900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim parcel.recycle(); 91900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim } 92900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim return items; 93900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim } 94900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim } 95900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim 96900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim static class MediaBrowserServiceAdaptor extends 972e7d3a28e00195c160cc4f5668e2d7f64eb590daSungsoo Lim MediaBrowserServiceCompatApi23.MediaBrowserServiceAdaptor { 98900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim MediaBrowserServiceAdaptor(Context context, ServiceCompatProxy serviceWrapper) { 99900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim super(context, serviceWrapper); 100900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim } 101900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim 102900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim @Override 103900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim public void onLoadChildren(String parentId, Result<List<MediaBrowser.MediaItem>> result, 104900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim Bundle options) { 105900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim ((ServiceCompatProxy) mServiceProxy).onLoadChildren( 106900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim parentId, new ResultWrapper(result), options); 107900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim } 108900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim } 1090f4ca634bbc43ddff900c35f7d2a43b55d8c830dJake Wharton 1100f4ca634bbc43ddff900c35f7d2a43b55d8c830dJake Wharton private MediaBrowserServiceCompatApi26() { 1110f4ca634bbc43ddff900c35f7d2a43b55d8c830dJake Wharton } 112900e852d4f8b423ec2d8374f8e6743129e8f331bSungsoo Lim} 113