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 com.android.media;
18
19import android.content.Context;
20import android.media.MediaBrowser2;
21import android.media.MediaBrowser2.BrowserCallback;
22import android.media.MediaController2;
23import android.media.MediaItem2;
24import android.media.SessionToken2;
25import android.media.update.MediaBrowser2Provider;
26import android.os.Bundle;
27import android.os.RemoteException;
28import android.text.TextUtils;
29import android.util.Log;
30
31import java.util.List;
32import java.util.concurrent.Executor;
33
34public class MediaBrowser2Impl extends MediaController2Impl implements MediaBrowser2Provider {
35    private final String TAG = "MediaBrowser2";
36    private final boolean DEBUG = true; // TODO(jaewan): change.
37
38    private final MediaBrowser2 mInstance;
39    private final MediaBrowser2.BrowserCallback mCallback;
40
41    public MediaBrowser2Impl(Context context, MediaBrowser2 instance, SessionToken2 token,
42            Executor executor, BrowserCallback callback) {
43        super(context, instance, token, executor, callback);
44        mInstance = instance;
45        mCallback = callback;
46    }
47
48    @Override MediaBrowser2 getInstance() {
49        return (MediaBrowser2) super.getInstance();
50    }
51
52    @Override
53    public void getLibraryRoot_impl(Bundle rootHints) {
54        final IMediaSession2 binder = getSessionBinder();
55        if (binder != null) {
56            try {
57                binder.getLibraryRoot(getControllerStub(), rootHints);
58            } catch (RemoteException e) {
59                // TODO(jaewan): Handle disconnect.
60                if (DEBUG) {
61                    Log.w(TAG, "Cannot connect to the service or the session is gone", e);
62                }
63            }
64        } else {
65            Log.w(TAG, "Session isn't active", new IllegalStateException());
66        }
67    }
68
69    @Override
70    public void subscribe_impl(String parentId, Bundle extras) {
71        if (parentId == null) {
72            throw new IllegalArgumentException("parentId shouldn't be null");
73        }
74
75        final IMediaSession2 binder = getSessionBinder();
76        if (binder != null) {
77            try {
78                binder.subscribe(getControllerStub(), parentId, extras);
79            } catch (RemoteException e) {
80                // TODO(jaewan): Handle disconnect.
81                if (DEBUG) {
82                    Log.w(TAG, "Cannot connect to the service or the session is gone", e);
83                }
84            }
85        } else {
86            Log.w(TAG, "Session isn't active", new IllegalStateException());
87        }
88    }
89
90    @Override
91    public void unsubscribe_impl(String parentId) {
92        if (parentId == null) {
93            throw new IllegalArgumentException("parentId shouldn't be null");
94        }
95
96        final IMediaSession2 binder = getSessionBinder();
97        if (binder != null) {
98            try {
99                binder.unsubscribe(getControllerStub(), parentId);
100            } catch (RemoteException e) {
101                // TODO(jaewan): Handle disconnect.
102                if (DEBUG) {
103                    Log.w(TAG, "Cannot connect to the service or the session is gone", e);
104                }
105            }
106        } else {
107            Log.w(TAG, "Session isn't active", new IllegalStateException());
108        }
109    }
110
111    @Override
112    public void getItem_impl(String mediaId) {
113        if (mediaId == null) {
114            throw new IllegalArgumentException("mediaId shouldn't be null");
115        }
116
117        final IMediaSession2 binder = getSessionBinder();
118        if (binder != null) {
119            try {
120                binder.getItem(getControllerStub(), mediaId);
121            } catch (RemoteException e) {
122                // TODO(jaewan): Handle disconnect.
123                if (DEBUG) {
124                    Log.w(TAG, "Cannot connect to the service or the session is gone", e);
125                }
126            }
127        } else {
128            Log.w(TAG, "Session isn't active", new IllegalStateException());
129        }
130    }
131
132    @Override
133    public void getChildren_impl(String parentId, int page, int pageSize, Bundle extras) {
134        if (parentId == null) {
135            throw new IllegalArgumentException("parentId shouldn't be null");
136        }
137        if (page < 1 || pageSize < 1) {
138            throw new IllegalArgumentException("Neither page nor pageSize should be less than 1");
139        }
140
141        final IMediaSession2 binder = getSessionBinder();
142        if (binder != null) {
143            try {
144                binder.getChildren(getControllerStub(), parentId, page, pageSize, extras);
145            } catch (RemoteException e) {
146                // TODO(jaewan): Handle disconnect.
147                if (DEBUG) {
148                    Log.w(TAG, "Cannot connect to the service or the session is gone", e);
149                }
150            }
151        } else {
152            Log.w(TAG, "Session isn't active", new IllegalStateException());
153        }
154    }
155
156    @Override
157    public void search_impl(String query, Bundle extras) {
158        if (TextUtils.isEmpty(query)) {
159            throw new IllegalArgumentException("query shouldn't be empty");
160        }
161        final IMediaSession2 binder = getSessionBinder();
162        if (binder != null) {
163            try {
164                binder.search(getControllerStub(), query, extras);
165            } catch (RemoteException e) {
166                // TODO(jaewan): Handle disconnect.
167                if (DEBUG) {
168                    Log.w(TAG, "Cannot connect to the service or the session is gone", e);
169                }
170            }
171        } else {
172            Log.w(TAG, "Session isn't active", new IllegalStateException());
173        }
174    }
175
176    @Override
177    public void getSearchResult_impl(String query, int page, int pageSize, Bundle extras) {
178        if (TextUtils.isEmpty(query)) {
179            throw new IllegalArgumentException("query shouldn't be empty");
180        }
181        if (page < 1 || pageSize < 1) {
182            throw new IllegalArgumentException("Neither page nor pageSize should be less than 1");
183        }
184        final IMediaSession2 binder = getSessionBinder();
185        if (binder != null) {
186            try {
187                binder.getSearchResult(getControllerStub(), query, page, pageSize, extras);
188            } catch (RemoteException e) {
189                // TODO(jaewan): Handle disconnect.
190                if (DEBUG) {
191                    Log.w(TAG, "Cannot connect to the service or the session is gone", e);
192                }
193            }
194        } else {
195            Log.w(TAG, "Session isn't active", new IllegalStateException());
196        }
197    }
198
199    public void onGetLibraryRootDone(
200            final Bundle rootHints, final String rootMediaId, final Bundle rootExtra) {
201        getCallbackExecutor().execute(() -> {
202            mCallback.onGetLibraryRootDone(getInstance(), rootHints, rootMediaId, rootExtra);
203        });
204    }
205
206    public void onGetItemDone(String mediaId, MediaItem2 item) {
207        getCallbackExecutor().execute(() -> {
208            mCallback.onGetItemDone(getInstance(), mediaId, item);
209        });
210    }
211
212    public void onGetChildrenDone(String parentId, int page, int pageSize, List<MediaItem2> result,
213            Bundle extras) {
214        getCallbackExecutor().execute(() -> {
215            mCallback.onGetChildrenDone(getInstance(), parentId, page, pageSize, result, extras);
216        });
217    }
218
219    public void onSearchResultChanged(String query, int itemCount, Bundle extras) {
220        getCallbackExecutor().execute(() -> {
221            mCallback.onSearchResultChanged(getInstance(), query, itemCount, extras);
222        });
223    }
224
225    public void onGetSearchResultDone(String query, int page, int pageSize, List<MediaItem2> result,
226            Bundle extras) {
227        getCallbackExecutor().execute(() -> {
228            mCallback.onGetSearchResultDone(getInstance(), query, page, pageSize, result, extras);
229        });
230    }
231
232    public void onChildrenChanged(final String parentId, int itemCount, final Bundle extras) {
233        getCallbackExecutor().execute(() -> {
234            mCallback.onChildrenChanged(getInstance(), parentId, itemCount, extras);
235        });
236    }
237}
238