summaryrefslogtreecommitdiff
path: root/androidx/media/MockMediaLibraryService2.java
diff options
context:
space:
mode:
Diffstat (limited to 'androidx/media/MockMediaLibraryService2.java')
-rw-r--r--androidx/media/MockMediaLibraryService2.java237
1 files changed, 237 insertions, 0 deletions
diff --git a/androidx/media/MockMediaLibraryService2.java b/androidx/media/MockMediaLibraryService2.java
new file mode 100644
index 00000000..8f5d5bba
--- /dev/null
+++ b/androidx/media/MockMediaLibraryService2.java
@@ -0,0 +1,237 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.media;
+
+import static org.junit.Assert.assertEquals;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.os.Bundle;
+import android.util.Log;
+
+import androidx.media.MediaLibraryService2.MediaLibrarySession.MediaLibrarySessionCallback;
+import androidx.media.MediaSession2.ControllerInfo;
+import androidx.media.MediaSession2.SessionCallback;
+import androidx.media.TestUtils.SyncHandler;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+import javax.annotation.concurrent.GuardedBy;
+
+/**
+ * Mock implementation of {@link MediaLibraryService2} for testing.
+ */
+public class MockMediaLibraryService2 extends MediaLibraryService2 {
+ // Keep in sync with the AndroidManifest.xml
+ public static final String ID = "TestLibrary";
+
+ public static final String ROOT_ID = "rootId";
+ public static final Bundle EXTRAS = new Bundle();
+
+ public static final String MEDIA_ID_GET_ITEM = "media_id_get_item";
+
+ public static final String PARENT_ID = "parent_id";
+ public static final String PARENT_ID_NO_CHILDREN = "parent_id_no_children";
+ public static final String PARENT_ID_ERROR = "parent_id_error";
+
+ public static final List<MediaItem2> GET_CHILDREN_RESULT = new ArrayList<>();
+ public static final int CHILDREN_COUNT = 100;
+
+ public static final String SEARCH_QUERY = "search_query";
+ public static final String SEARCH_QUERY_TAKES_TIME = "search_query_takes_time";
+ public static final int SEARCH_TIME_IN_MS = 5000;
+ public static final String SEARCH_QUERY_EMPTY_RESULT = "search_query_empty_result";
+
+ public static final List<MediaItem2> SEARCH_RESULT = new ArrayList<>();
+ public static final int SEARCH_RESULT_COUNT = 50;
+
+ // TODO(jaewan): Uncomment here after DataSourceDesc.builder is ready.
+// private static final DataSourceDesc DATA_SOURCE_DESC =
+// new DataSourceDesc.Builder().setDataSource(new FileDescriptor()).build();
+ private static final DataSourceDesc DATA_SOURCE_DESC = null;
+
+ private static final String TAG = "MockMediaLibrarySvc2";
+
+ static {
+ EXTRAS.putString(ROOT_ID, ROOT_ID);
+ }
+ @GuardedBy("MockMediaLibraryService2.class")
+ private static SessionToken2 sToken;
+
+ private MediaLibrarySession mSession;
+
+ public MockMediaLibraryService2() {
+ super();
+ GET_CHILDREN_RESULT.clear();
+ String getChildrenMediaIdPrefix = "get_children_media_id_";
+ for (int i = 0; i < CHILDREN_COUNT; i++) {
+ GET_CHILDREN_RESULT.add(createMediaItem(getChildrenMediaIdPrefix + i));
+ }
+
+ SEARCH_RESULT.clear();
+ String getSearchResultMediaIdPrefix = "get_search_result_media_id_";
+ for (int i = 0; i < SEARCH_RESULT_COUNT; i++) {
+ SEARCH_RESULT.add(createMediaItem(getSearchResultMediaIdPrefix + i));
+ }
+ }
+
+ @Override
+ public void onCreate() {
+ TestServiceRegistry.getInstance().setServiceInstance(this);
+ super.onCreate();
+ }
+
+ @Override
+ public MediaLibrarySession onCreateSession(String sessionId) {
+ final MockPlayer player = new MockPlayer(1);
+ final SyncHandler handler = (SyncHandler) TestServiceRegistry.getInstance().getHandler();
+ final Executor executor = new Executor() {
+ @Override
+ public void execute(Runnable runnable) {
+ handler.post(runnable);
+ }
+ };
+ SessionCallback callback = TestServiceRegistry.getInstance().getSessionCallback();
+ MediaLibrarySessionCallback librarySessionCallback;
+ if (callback instanceof MediaLibrarySessionCallback) {
+ librarySessionCallback = (MediaLibrarySessionCallback) callback;
+ } else {
+ // Callback hasn't set. Use default callback
+ librarySessionCallback = new TestLibrarySessionCallback();
+ }
+ mSession = new MediaLibrarySession.Builder(MockMediaLibraryService2.this, executor,
+ librarySessionCallback).setPlayer(player).setId(sessionId).build();
+ return mSession;
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ TestServiceRegistry.getInstance().cleanUp();
+ }
+
+ public static SessionToken2 getToken(Context context) {
+ synchronized (MockMediaLibraryService2.class) {
+ if (sToken == null) {
+ sToken = new SessionToken2(context, new ComponentName(
+ context.getPackageName(), MockMediaLibraryService2.class.getName()));
+ assertEquals(SessionToken2.TYPE_LIBRARY_SERVICE, sToken.getType());
+ }
+ return sToken;
+ }
+ }
+
+ private class TestLibrarySessionCallback extends MediaLibrarySessionCallback {
+ @Override
+ public LibraryRoot onGetLibraryRoot(MediaLibrarySession session, ControllerInfo controller,
+ Bundle rootHints) {
+ return new LibraryRoot(ROOT_ID, EXTRAS);
+ }
+
+ @Override
+ public MediaItem2 onGetItem(MediaLibrarySession session, ControllerInfo controller,
+ String mediaId) {
+ if (MEDIA_ID_GET_ITEM.equals(mediaId)) {
+ return createMediaItem(mediaId);
+ } else {
+ return null;
+ }
+ }
+
+ @Override
+ public List<MediaItem2> onGetChildren(MediaLibrarySession session,
+ ControllerInfo controller, String parentId, int page, int pageSize, Bundle extras) {
+ if (PARENT_ID.equals(parentId)) {
+ return getPaginatedResult(GET_CHILDREN_RESULT, page, pageSize);
+ } else if (PARENT_ID_ERROR.equals(parentId)) {
+ return null;
+ }
+ // Includes the case of PARENT_ID_NO_CHILDREN.
+ return new ArrayList<>();
+ }
+
+ @Override
+ public void onSearch(MediaLibrarySession session, final ControllerInfo controllerInfo,
+ final String query, final Bundle extras) {
+ if (SEARCH_QUERY.equals(query)) {
+ mSession.notifySearchResultChanged(controllerInfo, query, SEARCH_RESULT_COUNT,
+ extras);
+ } else if (SEARCH_QUERY_TAKES_TIME.equals(query)) {
+ // Searching takes some time. Notify after 5 seconds.
+ Executors.newSingleThreadScheduledExecutor().schedule(new Runnable() {
+ @Override
+ public void run() {
+ mSession.notifySearchResultChanged(
+ controllerInfo, query, SEARCH_RESULT_COUNT, extras);
+ }
+ }, SEARCH_TIME_IN_MS, TimeUnit.MILLISECONDS);
+ } else if (SEARCH_QUERY_EMPTY_RESULT.equals(query)) {
+ mSession.notifySearchResultChanged(controllerInfo, query, 0, extras);
+ } else {
+ // TODO: For the error case, how should we notify the browser?
+ }
+ }
+
+ @Override
+ public List<MediaItem2> onGetSearchResult(MediaLibrarySession session,
+ ControllerInfo controllerInfo, String query, int page, int pageSize,
+ Bundle extras) {
+ if (SEARCH_QUERY.equals(query)) {
+ return getPaginatedResult(SEARCH_RESULT, page, pageSize);
+ } else {
+ return null;
+ }
+ }
+ }
+
+ private List<MediaItem2> getPaginatedResult(List<MediaItem2> items, int page, int pageSize) {
+ if (items == null) {
+ return null;
+ } else if (items.size() == 0) {
+ return new ArrayList<>();
+ }
+
+ final int totalItemCount = items.size();
+ int fromIndex = (page - 1) * pageSize;
+ int toIndex = Math.min(page * pageSize, totalItemCount);
+
+ List<MediaItem2> paginatedResult = new ArrayList<>();
+ try {
+ // The case of (fromIndex >= totalItemCount) will throw exception below.
+ paginatedResult = items.subList(fromIndex, toIndex);
+ } catch (IndexOutOfBoundsException | IllegalArgumentException ex) {
+ Log.d(TAG, "Result is empty for given pagination arguments: totalItemCount="
+ + totalItemCount + ", page=" + page + ", pageSize=" + pageSize, ex);
+ }
+ return paginatedResult;
+ }
+
+ private MediaItem2 createMediaItem(String mediaId) {
+ Context context = MockMediaLibraryService2.this;
+ return new MediaItem2.Builder(0 /* Flags */)
+ .setMediaId(mediaId)
+ .setDataSourceDesc(DATA_SOURCE_DESC)
+ .setMetadata(new MediaMetadata2.Builder()
+ .putString(MediaMetadata2.METADATA_KEY_MEDIA_ID, mediaId)
+ .build())
+ .build();
+ }
+}