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
17package androidx.media;
18
19import android.content.Context;
20import android.media.browse.MediaBrowser;
21import android.os.Bundle;
22import android.os.Parcel;
23import android.service.media.MediaBrowserService;
24import android.util.Log;
25
26import androidx.annotation.RequiresApi;
27
28import java.lang.reflect.Field;
29import java.util.ArrayList;
30import java.util.List;
31
32@RequiresApi(26)
33class MediaBrowserServiceCompatApi26 {
34    private static final String TAG = "MBSCompatApi26";
35
36    private static Field sResultFlags;
37    static {
38        try {
39            sResultFlags = MediaBrowserService.Result.class.getDeclaredField("mFlags");
40            sResultFlags.setAccessible(true);
41        } catch (NoSuchFieldException e) {
42            Log.w(TAG, e);
43        }
44    }
45
46    public static Object createService(Context context, ServiceCompatProxy serviceProxy) {
47        return new MediaBrowserServiceAdaptor(context, serviceProxy);
48    }
49
50    public static void notifyChildrenChanged(Object serviceObj, String parentId, Bundle options) {
51        ((MediaBrowserService) serviceObj).notifyChildrenChanged(parentId, options);
52    }
53
54    public static Bundle getBrowserRootHints(Object serviceObj) {
55        return ((MediaBrowserService) serviceObj).getBrowserRootHints();
56    }
57
58    public interface ServiceCompatProxy extends MediaBrowserServiceCompatApi23.ServiceCompatProxy {
59        void onLoadChildren(String parentId, ResultWrapper result, Bundle options);
60    }
61
62    static class ResultWrapper {
63        MediaBrowserService.Result mResultObj;
64
65        ResultWrapper(MediaBrowserService.Result result) {
66            mResultObj = result;
67        }
68
69        public void sendResult(List<Parcel> result, int flags) {
70            try {
71                sResultFlags.setInt(mResultObj, flags);
72            } catch (IllegalAccessException e) {
73                Log.w(TAG, e);
74            }
75            mResultObj.sendResult(parcelListToItemList(result));
76        }
77
78        public void detach() {
79            mResultObj.detach();
80        }
81
82        List<MediaBrowser.MediaItem> parcelListToItemList(List<Parcel> parcelList) {
83            if (parcelList == null) {
84                return null;
85            }
86            List<MediaBrowser.MediaItem> items = new ArrayList<>();
87            for (Parcel parcel : parcelList) {
88                parcel.setDataPosition(0);
89                items.add(MediaBrowser.MediaItem.CREATOR.createFromParcel(parcel));
90                parcel.recycle();
91            }
92            return items;
93        }
94    }
95
96    static class MediaBrowserServiceAdaptor extends
97            MediaBrowserServiceCompatApi23.MediaBrowserServiceAdaptor {
98        MediaBrowserServiceAdaptor(Context context, ServiceCompatProxy serviceWrapper) {
99            super(context, serviceWrapper);
100        }
101
102        @Override
103        public void onLoadChildren(String parentId, Result<List<MediaBrowser.MediaItem>> result,
104                Bundle options) {
105            ((ServiceCompatProxy) mServiceProxy).onLoadChildren(
106                    parentId, new ResultWrapper(result), options);
107        }
108    }
109
110    private MediaBrowserServiceCompatApi26() {
111    }
112}
113