MediaPlayer2Impl.java revision dc65cd723a46b20115939fb45cce37193b3779d3
14d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/*
24d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * Copyright 2018 The Android Open Source Project
34d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *
44d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * Licensed under the Apache License, Version 2.0 (the "License");
54d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * you may not use this file except in compliance with the License.
64d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * You may obtain a copy of the License at
74d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *
84d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *      http://www.apache.org/licenses/LICENSE-2.0
94d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *
104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * Unless required by applicable law or agreed to in writing, software
114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * distributed under the License is distributed on an "AS IS" BASIS,
124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * See the License for the specific language governing permissions and
144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * limitations under the License.
154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */
164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpackage androidx.media;
174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannimport static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP;
194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannimport android.annotation.TargetApi;
214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannimport android.graphics.SurfaceTexture;
224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannimport android.media.AudioAttributes;
234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannimport android.media.DeniedByServerException;
244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannimport android.media.MediaDataSource;
254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannimport android.media.MediaDrm;
264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannimport android.media.MediaFormat;
274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannimport android.media.MediaPlayer;
284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannimport android.media.MediaTimestamp;
294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannimport android.media.PlaybackParams;
304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannimport android.media.ResourceBusyException;
314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannimport android.media.SubtitleData;
324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannimport android.media.SyncParams;
334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannimport android.media.TimedMetaData;
344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannimport android.media.UnsupportedSchemeException;
354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannimport android.os.Build;
364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannimport android.os.Handler;
374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannimport android.os.HandlerThread;
384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannimport android.os.Looper;
394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannimport android.os.Parcel;
404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannimport android.os.PersistableBundle;
414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannimport android.util.ArrayMap;
424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannimport android.util.Log;
434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannimport android.util.Pair;
444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannimport android.view.Surface;
454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannimport androidx.annotation.GuardedBy;
474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannimport androidx.annotation.NonNull;
484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannimport androidx.annotation.Nullable;
494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannimport androidx.annotation.RestrictTo;
504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannimport androidx.core.util.Preconditions;
514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannimport java.io.IOException;
534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannimport java.nio.ByteOrder;
544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannimport java.util.ArrayDeque;
554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannimport java.util.ArrayList;
564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannimport java.util.Arrays;
574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannimport java.util.HashMap;
584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannimport java.util.List;
594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannimport java.util.Map;
604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannimport java.util.UUID;
614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannimport java.util.concurrent.Executor;
624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannimport java.util.concurrent.atomic.AtomicInteger;
634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/**
654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * @hide
664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */
674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann@TargetApi(Build.VERSION_CODES.P)
684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann@RestrictTo(LIBRARY_GROUP)
694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpublic final class MediaPlayer2Impl extends MediaPlayer2 {
704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    private static final String TAG = "MediaPlayer2Impl";
724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    private static final int SOURCE_STATE_ERROR = -1;
744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    private static final int SOURCE_STATE_INIT = 0;
754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    private static final int SOURCE_STATE_PREPARING = 1;
764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    private static final int SOURCE_STATE_PREPARED = 2;
774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    private static ArrayMap<Integer, Integer> sInfoEventMap;
794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    private static ArrayMap<Integer, Integer> sErrorEventMap;
804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    private static ArrayMap<Integer, Integer> sPrepareDrmStatusMap;
814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    static {
834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        sInfoEventMap = new ArrayMap<>();
844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        sInfoEventMap.put(MediaPlayer.MEDIA_INFO_UNKNOWN, MEDIA_INFO_UNKNOWN);
854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        sInfoEventMap.put(2 /*MediaPlayer.MEDIA_INFO_STARTED_AS_NEXT*/, MEDIA_INFO_STARTED_AS_NEXT);
864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        sInfoEventMap.put(
874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START, MEDIA_INFO_VIDEO_RENDERING_START);
884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        sInfoEventMap.put(
894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                MediaPlayer.MEDIA_INFO_VIDEO_TRACK_LAGGING, MEDIA_INFO_VIDEO_TRACK_LAGGING);
904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        sInfoEventMap.put(MediaPlayer.MEDIA_INFO_BUFFERING_START, MEDIA_INFO_BUFFERING_START);
914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        sInfoEventMap.put(MediaPlayer.MEDIA_INFO_BUFFERING_END, MEDIA_INFO_BUFFERING_END);
924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        sInfoEventMap.put(MediaPlayer.MEDIA_INFO_BAD_INTERLEAVING, MEDIA_INFO_BAD_INTERLEAVING);
934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        sInfoEventMap.put(MediaPlayer.MEDIA_INFO_NOT_SEEKABLE, MEDIA_INFO_NOT_SEEKABLE);
944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        sInfoEventMap.put(MediaPlayer.MEDIA_INFO_METADATA_UPDATE, MEDIA_INFO_METADATA_UPDATE);
954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        sInfoEventMap.put(MediaPlayer.MEDIA_INFO_AUDIO_NOT_PLAYING, MEDIA_INFO_AUDIO_NOT_PLAYING);
964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        sInfoEventMap.put(MediaPlayer.MEDIA_INFO_VIDEO_NOT_PLAYING, MEDIA_INFO_VIDEO_NOT_PLAYING);
974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        sInfoEventMap.put(
984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                MediaPlayer.MEDIA_INFO_UNSUPPORTED_SUBTITLE, MEDIA_INFO_UNSUPPORTED_SUBTITLE);
994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        sInfoEventMap.put(MediaPlayer.MEDIA_INFO_SUBTITLE_TIMED_OUT, MEDIA_INFO_SUBTITLE_TIMED_OUT);
1004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
1014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        sErrorEventMap = new ArrayMap<>();
1024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        sErrorEventMap.put(MediaPlayer.MEDIA_ERROR_UNKNOWN, MEDIA_ERROR_UNKNOWN);
1034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        sErrorEventMap.put(
1044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                MediaPlayer.MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK,
1054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK);
1064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        sErrorEventMap.put(MediaPlayer.MEDIA_ERROR_IO, MEDIA_ERROR_IO);
1074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        sErrorEventMap.put(MediaPlayer.MEDIA_ERROR_MALFORMED, MEDIA_ERROR_MALFORMED);
1084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        sErrorEventMap.put(MediaPlayer.MEDIA_ERROR_UNSUPPORTED, MEDIA_ERROR_UNSUPPORTED);
1094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        sErrorEventMap.put(MediaPlayer.MEDIA_ERROR_TIMED_OUT, MEDIA_ERROR_TIMED_OUT);
1104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
1114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        sPrepareDrmStatusMap = new ArrayMap<>();
1124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        sPrepareDrmStatusMap.put(
1134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                MediaPlayer.PREPARE_DRM_STATUS_SUCCESS, PREPARE_DRM_STATUS_SUCCESS);
1144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        sPrepareDrmStatusMap.put(
1154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                MediaPlayer.PREPARE_DRM_STATUS_PROVISIONING_NETWORK_ERROR,
1164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                PREPARE_DRM_STATUS_PROVISIONING_NETWORK_ERROR);
1174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        sPrepareDrmStatusMap.put(
1184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                MediaPlayer.PREPARE_DRM_STATUS_PROVISIONING_SERVER_ERROR,
1194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                PREPARE_DRM_STATUS_PROVISIONING_SERVER_ERROR);
1204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        sPrepareDrmStatusMap.put(
1214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                MediaPlayer.PREPARE_DRM_STATUS_PROVISIONING_SERVER_ERROR,
1224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                PREPARE_DRM_STATUS_PROVISIONING_SERVER_ERROR);
1234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
1244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
1254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    private MediaPlayerSourceQueue mPlayer;
1264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
1274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    private HandlerThread mHandlerThread;
1284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    private final Handler mTaskHandler;
1294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    private final Object mTaskLock = new Object();
1304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    @GuardedBy("mTaskLock")
1314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    private final ArrayDeque<Task> mPendingTasks = new ArrayDeque<>();
1324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    @GuardedBy("mTaskLock")
1334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    private Task mCurrentTask;
1344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
1354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    private final Object mLock = new Object();
1364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    //--- guarded by |mLock| start
1374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    private AudioAttributesCompat mAudioAttributes;
1384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    private ArrayList<Pair<Executor, MediaPlayer2EventCallback>> mMp2EventCallbackRecords =
1394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            new ArrayList<>();
1404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    private ArrayMap<PlayerEventCallback, Executor> mPlayerEventCallbackMap =
1414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            new ArrayMap<>();
1424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    private ArrayList<Pair<Executor, DrmEventCallback>> mDrmEventCallbackRecords =
1434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            new ArrayList<>();
1444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    //--- guarded by |mLock| end
1454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
1464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    private void handleDataSourceError(final DataSourceError err) {
1474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        if (err == null) {
1484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            return;
1494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
1504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        notifyMediaPlayer2Event(new Mp2EventNotifier() {
1514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            @Override
1524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            public void notify(MediaPlayer2EventCallback callback) {
1534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                callback.onError(MediaPlayer2Impl.this, err.mDSD, err.mWhat, err.mExtra);
1544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
1554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        });
1564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
1574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
1584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    /**
1594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * Default constructor.
1604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * <p>When done with the MediaPlayer2Impl, you should call  {@link #close()},
1614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * to free the resources. If not released, too many MediaPlayer2Impl instances may
1624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * result in an exception.</p>
1634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     */
1644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    public MediaPlayer2Impl() {
1654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        mHandlerThread = new HandlerThread("MediaPlayer2TaskThread");
1664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        mHandlerThread.start();
1674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        Looper looper = mHandlerThread.getLooper();
1684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        mTaskHandler = new Handler(looper);
1694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
1704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        // TODO: To make sure MediaPlayer1 listeners work, the caller thread should have a looper.
1714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        // Fix the framework or document this behavior.
1724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        mPlayer = new MediaPlayerSourceQueue();
1734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
1744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
1754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    /**
1764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * Releases the resources held by this {@code MediaPlayer2} object.
1774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     *
1784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * It is considered good practice to call this method when you're
1794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * done using the MediaPlayer2. In particular, whenever an Activity
1804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * of an application is paused (its onPause() method is called),
1814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * or stopped (its onStop() method is called), this method should be
1824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * invoked to release the MediaPlayer2 object, unless the application
1834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * has a special need to keep the object around. In addition to
1844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * unnecessary resources (such as memory and instances of codecs)
1854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * being held, failure to call this method immediately if a
1864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * MediaPlayer2 object is no longer needed may also lead to
1874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * continuous battery consumption for mobile devices, and playback
1884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * failure for other applications if no multiple instances of the
1894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * same codec are supported on a device. Even if multiple instances
1904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * of the same codec are supported, some performance degradation
1914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * may be expected when unnecessary multiple instances are used
1924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * at the same time.
1934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     *
1944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * {@code close()} may be safely called after a prior {@code close()}.
1954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * This class implements the Java {@code AutoCloseable} interface and
1964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * may be used with try-with-resources.
1974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     */
1984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    @Override
1994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    public void close() {
2004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        mPlayer.release();
2014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
2024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
2034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    /**
2044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * Starts or resumes playback. If playback had previously been paused,
2054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * playback will continue from where it was paused. If playback had
2064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * been stopped, or never started before, playback will start at the
2074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * beginning.
2084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     *
2094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @throws IllegalStateException if it is called in an invalid state
2104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     */
2114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    @Override
2124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    public void play() {
2134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        addTask(new Task(CALL_COMPLETED_PLAY, false) {
2144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            @Override
2154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            void process() {
2164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                mPlayer.play();
2174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
2184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        });
2194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
2204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
2214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    /**
2224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * Prepares the player for playback, asynchronously.
2234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     *
2244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * After setting the datasource and the display surface, you need to either
2254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * call prepare(). For streams, you should call prepare(),
2264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * which returns immediately, rather than blocking until enough data has been
2274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * buffered.
2284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     *
2294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @throws IllegalStateException if it is called in an invalid state
2304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     */
2314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    @Override
2324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    public void prepare() {
2334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        addTask(new Task(CALL_COMPLETED_PREPARE, true) {
2344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            @Override
2354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            void process() throws IOException {
2364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                mPlayer.prepareAsync();
2374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
2384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        });
2394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
2404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
2414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    /**
2424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * Pauses playback. Call play() to resume.
2434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     *
2444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @throws IllegalStateException if the internal player engine has not been initialized.
2454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     */
2464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    @Override
2474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    public void pause() {
2484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        addTask(new Task(CALL_COMPLETED_PAUSE, false) {
2494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            @Override
2504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            void process() {
2514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                mPlayer.pause();
2524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
2534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        });
2544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
2554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
2564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    /**
2574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * Tries to play next data source if applicable.
2584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     *
2594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @throws IllegalStateException if it is called in an invalid state
2604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     */
2614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    @Override
2624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    public void skipToNext() {
2634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        addTask(new Task(CALL_COMPLETED_SKIP_TO_NEXT, false) {
2644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            @Override
2654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            void process() {
2664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                // TODO: switch to next data source and play
2674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
2684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        });
2694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
2704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
2714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    /**
2724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * Gets the current playback position.
2734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     *
2744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @return the current position in milliseconds
2754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     */
2764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    @Override
2774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    public long getCurrentPosition() {
2784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        return mPlayer.getCurrentPosition();
2794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
2804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
2814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    /**
2824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * Gets the duration of the file.
2834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     *
2844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @return the duration in milliseconds, if no duration is available
2854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * (for example, if streaming live content), -1 is returned.
2864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     */
2874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    @Override
2884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    public long getDuration() {
2894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        return mPlayer.getDuration();
2904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
2914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
2924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    /**
2934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * Gets the current buffered media source position received through progressive downloading.
2944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * The received buffering percentage indicates how much of the content has been buffered
2954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * or played. For example a buffering update of 80 percent when half the content
2964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * has already been played indicates that the next 30 percent of the
2974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * content to play has been buffered.
2984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     *
2994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @return the current buffered media source position in milliseconds
3004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     */
3014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    @Override
3024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    public long getBufferedPosition() {
3034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        // Use cached buffered percent for now.
3044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        return mPlayer.getBufferedPosition();
3054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
3064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
3074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    @Override
3084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    public @PlayerState int getPlayerState() {
3094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        return mPlayer.getPlayerState();
3104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
3114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
3124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    /**
3134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * Gets the current buffering state of the player.
3144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * During buffering, see {@link #getBufferedPosition()} for the quantifying the amount already
3154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * buffered.
3164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     */
3174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    @Override
3184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    public @BuffState int getBufferingState() {
3194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        return  mPlayer.getBufferingState();
3204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
3214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
3224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    /**
3234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * Sets the audio attributes for this MediaPlayer2.
3244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * See {@link AudioAttributes} for how to build and configure an instance of this class.
3254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * You must call this method before {@link #prepare()} in order
3264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * for the audio attributes to become effective thereafter.
3274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @param attributes a non-null set of audio attributes
3284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @throws IllegalArgumentException if the attributes are null or invalid.
3294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     */
3304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    @Override
3314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    public void setAudioAttributes(@NonNull final AudioAttributesCompat attributes) {
3324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        addTask(new Task(CALL_COMPLETED_SET_AUDIO_ATTRIBUTES, false) {
3334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            @Override
3344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            void process() {
3354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                AudioAttributes attr;
3364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                synchronized (mLock) {
3374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    mAudioAttributes = attributes;
3384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    attr = (AudioAttributes) mAudioAttributes.unwrap();
3394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                }
3404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                mPlayer.setAudioAttributes(attr);
3414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
3424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        });
3434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
3444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
3454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    @Override
3464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    public @NonNull AudioAttributesCompat getAudioAttributes() {
3474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        synchronized (mLock) {
3484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            return mAudioAttributes;
3494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
3504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
3514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
3524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    /**
3534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * Sets the data source as described by a DataSourceDesc.
3544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     *
3554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @param dsd the descriptor of data source you want to play
3564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @throws IllegalStateException if it is called in an invalid state
3574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @throws NullPointerException if dsd is null
3584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     */
3594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    @Override
3604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    public void setDataSource(@NonNull final DataSourceDesc dsd) {
3614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        addTask(new Task(CALL_COMPLETED_SET_DATA_SOURCE, false) {
3624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            @Override
3634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            void process() {
3644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                Preconditions.checkNotNull(dsd, "the DataSourceDesc cannot be null");
3654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                // TODO: setDataSource could update exist data source
3664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                try {
3674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    mPlayer.setFirst(dsd);
3684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                } catch (IOException e) {
3694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    Log.e(TAG, "process: setDataSource", e);
3704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                }
3714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
3724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        });
3734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
3744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
3754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    /**
3764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * Sets a single data source as described by a DataSourceDesc which will be played
3774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * after current data source is finished.
3784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     *
3794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @param dsd the descriptor of data source you want to play after current one
3804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @throws IllegalStateException if it is called in an invalid state
3814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @throws NullPointerException if dsd is null
3824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     */
3834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    @Override
3844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    public void setNextDataSource(@NonNull final DataSourceDesc dsd) {
3854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        addTask(new Task(CALL_COMPLETED_SET_NEXT_DATA_SOURCE, false) {
3864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            @Override
3874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            void process() {
3884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                Preconditions.checkNotNull(dsd, "the DataSourceDesc cannot be null");
3894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                handleDataSourceError(mPlayer.setNext(dsd));
3904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
3914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        });
3924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
3934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
3944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    /**
3954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * Sets a list of data sources to be played sequentially after current data source is done.
3964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     *
3974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @param dsds the list of data sources you want to play after current one
3984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @throws IllegalStateException if it is called in an invalid state
3994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @throws IllegalArgumentException if dsds is null or empty, or contains null DataSourceDesc
4004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     */
4014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    @Override
4024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    public void setNextDataSources(@NonNull final List<DataSourceDesc> dsds) {
4034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        addTask(new Task(CALL_COMPLETED_SET_NEXT_DATA_SOURCES, false) {
4044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            @Override
4054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            void process() {
4064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                if (dsds == null || dsds.size() == 0) {
4074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    throw new IllegalArgumentException("data source list cannot be null or empty.");
4084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                }
4094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                for (DataSourceDesc dsd : dsds) {
4104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    if (dsd == null) {
4114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        throw new IllegalArgumentException(
4124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                                "DataSourceDesc in the source list cannot be null.");
4134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    }
4144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                }
4154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                handleDataSourceError(mPlayer.setNextMultiple(dsds));
4164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
4174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        });
4184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
4194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
4204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    @Override
4214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    public @NonNull DataSourceDesc getCurrentDataSource() {
4224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        return mPlayer.getFirst().getDSD();
4234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
4244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
4254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    /**
4264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * Configures the player to loop on the current data source.
4274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @param loop true if the current data source is meant to loop.
4284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     */
4294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    @Override
4304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    public void loopCurrent(final boolean loop) {
4314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        addTask(new Task(CALL_COMPLETED_LOOP_CURRENT, false) {
4324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            @Override
4334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            void process() {
4344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                mPlayer.setLooping(loop);
4354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
4364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        });
4374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
4384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
4394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    /**
4404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * Sets the playback speed.
4414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * A value of 1.0f is the default playback value.
4424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * A negative value indicates reverse playback, check {@link #isReversePlaybackSupported()}
4434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * before using negative values.<br>
4444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * After changing the playback speed, it is recommended to query the actual speed supported
4454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * by the player, see {@link #getPlaybackSpeed()}.
4464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @param speed the desired playback speed
4474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     */
4484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    @Override
4494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    public void setPlaybackSpeed(final float speed) {
4504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        addTask(new Task(CALL_COMPLETED_SET_PLAYBACK_SPEED, false) {
4514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            @Override
4524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            void process() {
4534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                setPlaybackParamsInternal(getPlaybackParams().setSpeed(speed));
4544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
4554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        });
4564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
4574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
4584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    /**
4594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * Returns the actual playback speed to be used by the player when playing.
4604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * Note that it may differ from the speed set in {@link #setPlaybackSpeed(float)}.
4614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @return the actual playback speed
4624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     */
4634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    @Override
4644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    public float getPlaybackSpeed() {
4654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        return getPlaybackParams().getSpeed();
4664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
4674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
4684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    /**
4694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * Indicates whether reverse playback is supported.
4704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * Reverse playback is indicated by negative playback speeds, see
4714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * {@link #setPlaybackSpeed(float)}.
4724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @return true if reverse playback is supported.
4734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     */
4744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    @Override
4754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    public boolean isReversePlaybackSupported() {
4764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        return false;
4774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
4784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
4794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    /**
4804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * Sets the volume of the audio of the media to play, expressed as a linear multiplier
4814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * on the audio samples.
4824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * Note that this volume is specific to the player, and is separate from stream volume
4834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * used across the platform.<br>
4844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * A value of 0.0f indicates muting, a value of 1.0f is the nominal unattenuated and unamplified
4854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * gain. See {@link #getMaxPlayerVolume()} for the volume range supported by this player.
4864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @param volume a value between 0.0f and {@link #getMaxPlayerVolume()}.
4874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     */
4884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    @Override
4894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    public void setPlayerVolume(final float volume) {
4904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        addTask(new Task(CALL_COMPLETED_SET_PLAYER_VOLUME, false) {
4914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            @Override
4924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            void process() {
4934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                mPlayer.setVolume(volume);
4944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
4954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        });
4964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
4974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
4984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    /**
4994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * Returns the current volume of this player to this player.
5004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * Note that it does not take into account the associated stream volume.
5014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @return the player volume.
5024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     */
5034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    @Override
5044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    public float getPlayerVolume() {
5054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        return mPlayer.getVolume();
5064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
5074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
5084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    /**
5094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @return the maximum volume that can be used in {@link #setPlayerVolume(float)}.
5104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     */
5114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    @Override
5124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    public float getMaxPlayerVolume() {
5134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        return 1.0f;
5144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
5154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
5164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    /**
5174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * Adds a callback to be notified of events for this player.
5184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @param e the {@link Executor} to be used for the events.
5194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @param cb the callback to receive the events.
5204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     */
5214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    @Override
5224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    public void registerPlayerEventCallback(@NonNull Executor e,
5234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            @NonNull PlayerEventCallback cb) {
5244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        if (cb == null) {
5254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            throw new IllegalArgumentException("Illegal null PlayerEventCallback");
5264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
5274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        if (e == null) {
5284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            throw new IllegalArgumentException(
5294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    "Illegal null Executor for the PlayerEventCallback");
5304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
5314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        synchronized (mLock) {
5324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            mPlayerEventCallbackMap.put(cb, e);
5334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
5344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
5354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
5364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    /**
5374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * Removes a previously registered callback for player events
5384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @param cb the callback to remove
5394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     */
5404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    @Override
5414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    public void unregisterPlayerEventCallback(@NonNull PlayerEventCallback cb) {
5424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        if (cb == null) {
5434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            throw new IllegalArgumentException("Illegal null PlayerEventCallback");
5444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
5454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        synchronized (mLock) {
5464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            mPlayerEventCallbackMap.remove(cb);
5474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
5484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
5494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
5504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    @Override
5514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    public void notifyWhenCommandLabelReached(final Object label) {
5524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        addTask(new Task(CALL_COMPLETED_NOTIFY_WHEN_COMMAND_LABEL_REACHED, false) {
5534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            @Override
5544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            void process() {
5554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                notifyMediaPlayer2Event(new Mp2EventNotifier() {
5564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    @Override
5574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    public void notify(MediaPlayer2EventCallback cb) {
5584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        cb.onCommandLabelReached(MediaPlayer2Impl.this, label);
5594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    }
5604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                });
5614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
5624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        });
5634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
5644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
5654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    /**
5664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * Sets the {@link Surface} to be used as the sink for the video portion of
5674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * the media. Setting a Surface will un-set any Surface or SurfaceHolder that
5684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * was previously set. A null surface will result in only the audio track
5694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * being played.
5704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     *
5714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * If the Surface sends frames to a {@link SurfaceTexture}, the timestamps
5724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * returned from {@link SurfaceTexture#getTimestamp()} will have an
5734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * unspecified zero point.  These timestamps cannot be directly compared
5744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * between different media sources, different instances of the same media
5754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * source, or multiple runs of the same program.  The timestamp is normally
5764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * monotonically increasing and is unaffected by time-of-day adjustments,
5774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * but it is reset when the position is set.
5784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     *
5794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @param surface The {@link Surface} to be used for the video portion of
5804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * the media.
5814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @throws IllegalStateException if the internal player engine has not been
5824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * initialized or has been released.
5834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     */
5844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    @Override
5854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    public void setSurface(final Surface surface) {
5864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        addTask(new Task(CALL_COMPLETED_SET_SURFACE, false) {
5874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            @Override
5884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            void process() {
5894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                mPlayer.setSurface(surface);
5904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
5914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        });
5924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
5934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
5944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    /**
5954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * Discards all pending commands.
5964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     */
5974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    @Override
5984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    public void clearPendingCommands() {
5994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        synchronized (mTaskLock) {
6004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            mPendingTasks.clear();
6014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
6024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
6034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
6044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    private void addTask(Task task) {
6054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        synchronized (mTaskLock) {
6064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            mPendingTasks.add(task);
6074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            processPendingTask_l();
6084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
6094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
6104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
6114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    @GuardedBy("mTaskLock")
6124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    private void processPendingTask_l() {
6134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        if (mCurrentTask != null) {
6144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            return;
6154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
6164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        if (!mPendingTasks.isEmpty()) {
6174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            Task task = mPendingTasks.removeFirst();
6184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            mCurrentTask = task;
6194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            mTaskHandler.post(task);
6204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
6214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
6224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
6234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    private static void handleDataSource(MediaPlayerSource src)
6244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            throws IOException {
6254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        final DataSourceDesc dsd = src.getDSD();
6264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        Preconditions.checkNotNull(dsd, "the DataSourceDesc cannot be null");
6274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
6284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        MediaPlayer player = src.mPlayer;
6294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        switch (dsd.getType()) {
6304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            case DataSourceDesc.TYPE_CALLBACK:
6314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                player.setDataSource(new MediaDataSource() {
6324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    Media2DataSource mDataSource = dsd.getMedia2DataSource();
6334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    @Override
6344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    public int readAt(long position, byte[] buffer, int offset, int size)
6354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                            throws IOException {
6364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        return mDataSource.readAt(position, buffer, offset, size);
6374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    }
6384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
6394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    @Override
6404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    public long getSize() throws IOException {
6414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        return mDataSource.getSize();
6424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    }
6434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
6444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    @Override
6454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    public void close() throws IOException {
6464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        mDataSource.close();
6474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    }
6484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                });
6494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                break;
6504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
6514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            case DataSourceDesc.TYPE_FD:
6524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                player.setDataSource(
6534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        dsd.getFileDescriptor(),
6544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        dsd.getFileDescriptorOffset(),
6554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        dsd.getFileDescriptorLength());
6564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                break;
6574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
6584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            case DataSourceDesc.TYPE_URI:
6594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                player.setDataSource(
6604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        dsd.getUriContext(),
6614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        dsd.getUri(),
6624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        dsd.getUriHeaders(),
6634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        dsd.getUriCookies());
6644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                break;
6654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
6664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            default:
6674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                break;
6684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
6694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
6704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
6714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    /**
6724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * Returns the width of the video.
6734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     *
6744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @return the width of the video, or 0 if there is no video,
6754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * no display surface was set, or the width has not been determined
6764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * yet. The {@code MediaPlayer2EventCallback} can be registered via
6774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * {@link #setMediaPlayer2EventCallback(Executor, MediaPlayer2EventCallback)} to provide a
6784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * notification {@code MediaPlayer2EventCallback.onVideoSizeChanged} when the width
6794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * is available.
6804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     */
6814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    @Override
6824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    public int getVideoWidth() {
6834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        return mPlayer.getVideoWidth();
6844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
6854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
6864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    /**
6874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * Returns the height of the video.
6884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     *
6894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @return the height of the video, or 0 if there is no video,
6904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * no display surface was set, or the height has not been determined
6914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * yet. The {@code MediaPlayer2EventCallback} can be registered via
6924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * {@link #setMediaPlayer2EventCallback(Executor, MediaPlayer2EventCallback)} to provide a
6934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * notification {@code MediaPlayer2EventCallback.onVideoSizeChanged} when the height
6944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * is available.
6954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     */
6964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    @Override
6974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    public int getVideoHeight() {
6984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        return mPlayer.getVideoHeight();
6994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
7004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
7014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    @Override
7024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    public PersistableBundle getMetrics() {
7034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        return mPlayer.getMetrics();
7044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
7054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
7064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    /**
7074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * Sets playback rate using {@link PlaybackParams}. The object sets its internal
7084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * PlaybackParams to the input, except that the object remembers previous speed
7094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * when input speed is zero. This allows the object to resume at previous speed
7104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * when play() is called. Calling it before the object is prepared does not change
7114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * the object state. After the object is prepared, calling it with zero speed is
7124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * equivalent to calling pause(). After the object is prepared, calling it with
7134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * non-zero speed is equivalent to calling play().
7144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     *
7154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @param params the playback params.
7164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @throws IllegalStateException if the internal player engine has not been
7174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * initialized or has been released.
7184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @throws IllegalArgumentException if params is not supported.
7194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     */
7204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    @Override
7214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    public void setPlaybackParams(@NonNull final PlaybackParams params) {
7224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        addTask(new Task(CALL_COMPLETED_SET_PLAYBACK_PARAMS, false) {
7234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            @Override
7244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            void process() {
7254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                setPlaybackParamsInternal(params);
7264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
7274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        });
7284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
7294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
7304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    /**
7314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * Gets the playback params, containing the current playback rate.
7324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     *
7334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @return the playback params.
7344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @throws IllegalStateException if the internal player engine has not been
7354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * initialized.
7364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     */
7374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    @Override
7384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    @NonNull
7394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    public PlaybackParams getPlaybackParams() {
7404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        return mPlayer.getPlaybackParams();
7414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
7424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
7434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    /**
7444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * Sets A/V sync mode.
7454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     *
7464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @param params the A/V sync params to apply
7474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @throws IllegalStateException if the internal player engine has not been
7484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * initialized.
7494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @throws IllegalArgumentException if params are not supported.
7504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     */
7514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    @Override
7524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    public void setSyncParams(@NonNull final SyncParams params) {
7534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        addTask(new Task(CALL_COMPLETED_SET_SYNC_PARAMS, false) {
7544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            @Override
7554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            void process() {
7564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                mPlayer.setSyncParams(params);
7574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
7584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        });
7594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
7604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
7614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    /**
7624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * Gets the A/V sync mode.
7634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     *
7644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @return the A/V sync params
7654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @throws IllegalStateException if the internal player engine has not been
7664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     *                               initialized.
7674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     */
7684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    @Override
7694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    @NonNull
7704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    public SyncParams getSyncParams() {
7714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        return mPlayer.getSyncParams();
7724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
7734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
7744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    /**
7754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * Moves the media to specified time position by considering the given mode.
7764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * <p>
7774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * When seekTo is finished, the user will be notified via OnSeekComplete supplied by the user.
7784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * There is at most one active seekTo processed at any time. If there is a to-be-completed
7794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * seekTo, new seekTo requests will be queued in such a way that only the last request
7804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * is kept. When current seekTo is completed, the queued request will be processed if
7814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * that request is different from just-finished seekTo operation, i.e., the requested
7824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * position or mode is different.
7834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     *
7844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @param msec the offset in milliseconds from the start to seek to.
7854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * When seeking to the given time position, there is no guarantee that the data source
7864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * has a frame located at the position. When this happens, a frame nearby will be rendered.
7874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * If msec is negative, time position zero will be used.
7884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * If msec is larger than duration, duration will be used.
7894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @param mode the mode indicating where exactly to seek to.
7904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * Use {@link #SEEK_PREVIOUS_SYNC} if one wants to seek to a sync frame
7914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * that has a timestamp earlier than or the same as msec. Use
7924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * {@link #SEEK_NEXT_SYNC} if one wants to seek to a sync frame
7934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * that has a timestamp later than or the same as msec. Use
7944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * {@link #SEEK_CLOSEST_SYNC} if one wants to seek to a sync frame
7954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * that has a timestamp closest to or the same as msec. Use
7964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * {@link #SEEK_CLOSEST} if one wants to seek to a frame that may
7974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * or may not be a sync frame but is closest to or the same as msec.
7984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * {@link #SEEK_CLOSEST} often has larger performance overhead compared
7994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * to the other options if there is no sync frame located at msec.
8004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @throws IllegalStateException if the internal player engine has not been
8014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * initialized
8024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @throws IllegalArgumentException if the mode is invalid.
8034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     */
8044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    @Override
8054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    public void seekTo(final long msec, @SeekMode final int mode) {
8064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        addTask(new Task(CALL_COMPLETED_SEEK_TO, true) {
8074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            @Override
8084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            void process() {
8094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                mPlayer.seekTo(msec, mode);
8104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
8114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        });
8124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
8134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
8144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    /**
8154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * Get current playback position as a {@link MediaTimestamp}.
8164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * <p>
8174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * The MediaTimestamp represents how the media time correlates to the system time in
8184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * a linear fashion using an anchor and a clock rate. During regular playback, the media
8194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * time moves fairly constantly (though the anchor frame may be rebased to a current
8204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * system time, the linear correlation stays steady). Therefore, this method does not
8214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * need to be called often.
8224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * <p>
8234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * To help users get current playback position, this method always anchors the timestamp
8244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * to the current {@link System#nanoTime system time}, so
8254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * {@link MediaTimestamp#getAnchorMediaTimeUs} can be used as current playback position.
8264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     *
8274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @return a MediaTimestamp object if a timestamp is available, or {@code null} if no timestamp
8284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * is available, e.g. because the media player has not been initialized.
8294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @see MediaTimestamp
8304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     */
8314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    @Override
8324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    @Nullable
8334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    public MediaTimestamp getTimestamp() {
8344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        return mPlayer.getTimestamp();
8354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
8364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
8374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    /**
8384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * Resets the MediaPlayer2 to its uninitialized state. After calling
8394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * this method, you will have to initialize it again by setting the
8404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * data source and calling prepare().
8414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     */
8424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    @Override
8434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    public void reset() {
8444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        mPlayer.reset();
8454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        synchronized (mLock) {
8464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            mAudioAttributes = null;
8474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            mMp2EventCallbackRecords.clear();
8484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            mPlayerEventCallbackMap.clear();
8494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            mDrmEventCallbackRecords.clear();
8504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
8514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
8524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
8534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    /**
8544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * Sets the audio session ID.
8554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     *
8564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @param sessionId the audio session ID.
8574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * The audio session ID is a system wide unique identifier for the audio stream played by
8584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * this MediaPlayer2 instance.
8594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * The primary use of the audio session ID  is to associate audio effects to a particular
8604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * instance of MediaPlayer2: if an audio session ID is provided when creating an audio effect,
8614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * this effect will be applied only to the audio content of media players within the same
8624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * audio session and not to the output mix.
8634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * When created, a MediaPlayer2 instance automatically generates its own audio session ID.
8644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * However, it is possible to force this player to be part of an already existing audio session
8654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * by calling this method.
8664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * This method must be called before one of the overloaded <code> setDataSource </code> methods.
8674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @throws IllegalStateException if it is called in an invalid state
8684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @throws IllegalArgumentException if the sessionId is invalid.
8694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     */
8704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    @Override
8714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    public void setAudioSessionId(final int sessionId) {
8724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        addTask(new Task(CALL_COMPLETED_SET_AUDIO_SESSION_ID, false) {
8734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            @Override
8744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            void process() {
8754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                mPlayer.setAudioSessionId(sessionId);
8764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
8774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        });
8784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
8794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
8804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    @Override
8814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    public int getAudioSessionId() {
8824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        return mPlayer.getAudioSessionId();
8834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
8844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
8854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    /**
8864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * Attaches an auxiliary effect to the player. A typical auxiliary effect is a reverberation
8874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * effect which can be applied on any sound source that directs a certain amount of its
8884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * energy to this effect. This amount is defined by setAuxEffectSendLevel().
8894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * See {@link #setAuxEffectSendLevel(float)}.
8904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * <p>After creating an auxiliary effect (e.g.
8914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * {@link android.media.audiofx.EnvironmentalReverb}), retrieve its ID with
8924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * {@link android.media.audiofx.AudioEffect#getId()} and use it when calling this method
8934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * to attach the player to the effect.
8944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * <p>To detach the effect from the player, call this method with a null effect id.
8954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * <p>This method must be called after one of the overloaded <code> setDataSource </code>
8964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * methods.
8974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @param effectId system wide unique id of the effect to attach
8984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     */
8994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    @Override
9004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    public void attachAuxEffect(final int effectId) {
9014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        addTask(new Task(CALL_COMPLETED_ATTACH_AUX_EFFECT, false) {
9024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            @Override
9034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            void process() {
9044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                mPlayer.attachAuxEffect(effectId);
9054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
9064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        });
9074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
9084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
9094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    /**
9104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * Sets the send level of the player to the attached auxiliary effect.
9114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * See {@link #attachAuxEffect(int)}. The level value range is 0 to 1.0.
9124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * <p>By default the send level is 0, so even if an effect is attached to the player
9134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * this method must be called for the effect to be applied.
9144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * <p>Note that the passed level value is a raw scalar. UI controls should be scaled
9154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * logarithmically: the gain applied by audio framework ranges from -72dB to 0dB,
9164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * so an appropriate conversion from linear UI input x to level is:
9174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * x == 0 -> level = 0
9184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * 0 < x <= R -> level = 10^(72*(x-R)/20/R)
9194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @param level send level scalar
9204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     */
9214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    @Override
9224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    public void setAuxEffectSendLevel(final float level) {
9234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        addTask(new Task(CALL_COMPLETED_SET_AUX_EFFECT_SEND_LEVEL, false) {
9244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            @Override
9254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            void process() {
9264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                mPlayer.setAuxEffectSendLevel(level);
9274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
9284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        });
9294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
9304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
9314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    /**
9324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * Class for MediaPlayer2 to return each audio/video/subtitle track's metadata.
9334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     *
9344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @see MediaPlayer2#getTrackInfo
9354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     */
9364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    public static final class TrackInfoImpl extends TrackInfo {
9374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        final int mTrackType;
9384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        final MediaFormat mFormat;
9394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
9404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        /**
9414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         * Gets the track type.
9424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         * @return TrackType which indicates if the track is video, audio, timed text.
9434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         */
9444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        @Override
9454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        public int getTrackType() {
9464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            return mTrackType;
9474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
9484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
9494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        /**
9504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         * Gets the language code of the track.
9514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         * @return a language code in either way of ISO-639-1 or ISO-639-2.
9524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         * When the language is unknown or could not be determined,
9534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         * ISO-639-2 language code, "und", is returned.
9544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         */
9554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        @Override
9564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        public String getLanguage() {
9574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            String language = mFormat.getString(MediaFormat.KEY_LANGUAGE);
9584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            return language == null ? "und" : language;
9594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
9604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
9614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        /**
9624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         * Gets the {@link MediaFormat} of the track.  If the format is
9634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         * unknown or could not be determined, null is returned.
9644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         */
9654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        @Override
9664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        public MediaFormat getFormat() {
9674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            if (mTrackType == MEDIA_TRACK_TYPE_TIMEDTEXT
9684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    || mTrackType == MEDIA_TRACK_TYPE_SUBTITLE) {
9694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                return mFormat;
9704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
9714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            return null;
9724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
9734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
9744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        TrackInfoImpl(int type, MediaFormat format) {
9754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            mTrackType = type;
9764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            mFormat = format;
9774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
9784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
9794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        @Override
9804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        public String toString() {
9814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            StringBuilder out = new StringBuilder(128);
9824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            out.append(getClass().getName());
9834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            out.append('{');
9844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            switch (mTrackType) {
9854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                case MEDIA_TRACK_TYPE_VIDEO:
9864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    out.append("VIDEO");
9874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    break;
9884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                case MEDIA_TRACK_TYPE_AUDIO:
9894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    out.append("AUDIO");
9904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    break;
9914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                case MEDIA_TRACK_TYPE_TIMEDTEXT:
9924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    out.append("TIMEDTEXT");
9934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    break;
9944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                case MEDIA_TRACK_TYPE_SUBTITLE:
9954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    out.append("SUBTITLE");
9964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    break;
9974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                default:
9984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    out.append("UNKNOWN");
9994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    break;
10004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
10014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            out.append(", " + mFormat.toString());
10024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            out.append("}");
10034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            return out.toString();
10044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
10054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    };
10064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
10074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    /**
10084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * Returns a List of track information.
10094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     *
10104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @return List of track info. The total number of tracks is the array length.
10114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * Must be called again if an external timed text source has been added after
10124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * addTimedTextSource method is called.
10134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @throws IllegalStateException if it is called in an invalid state.
10144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     */
10154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    @Override
10164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    public List<TrackInfo> getTrackInfo() {
10174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        MediaPlayer.TrackInfo[] list = mPlayer.getTrackInfo();
10184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        List<TrackInfo> trackList = new ArrayList<>();
10194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        for (MediaPlayer.TrackInfo info : list) {
10204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            trackList.add(new TrackInfoImpl(info.getTrackType(), info.getFormat()));
10214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
10224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        return trackList;
10234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
10244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
10254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    /**
10264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * Returns the index of the audio, video, or subtitle track currently selected for playback,
10274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * The return value is an index into the array returned by {@link #getTrackInfo()}, and can
10284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * be used in calls to {@link #selectTrack(int)} or {@link #deselectTrack(int)}.
10294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     *
10304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @param trackType should be one of {@link TrackInfo#MEDIA_TRACK_TYPE_VIDEO},
10314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * {@link TrackInfo#MEDIA_TRACK_TYPE_AUDIO}, or
10324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * {@link TrackInfo#MEDIA_TRACK_TYPE_SUBTITLE}
10334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @return index of the audio, video, or subtitle track currently selected for playback;
10344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * a negative integer is returned when there is no selected track for {@code trackType} or
10354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * when {@code trackType} is not one of audio, video, or subtitle.
10364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @throws IllegalStateException if called after {@link #close()}
10374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     *
10384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @see #getTrackInfo()
10394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @see #selectTrack(int)
10404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @see #deselectTrack(int)
10414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     */
10424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    @Override
10434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    public int getSelectedTrack(int trackType) {
10444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        return mPlayer.getSelectedTrack(trackType);
10454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
10464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
10474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    /**
10484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * Selects a track.
10494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * <p>
10504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * If a MediaPlayer2 is in invalid state, it throws an IllegalStateException exception.
10514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * If a MediaPlayer2 is in <em>Started</em> state, the selected track is presented immediately.
10524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * If a MediaPlayer2 is not in Started state, it just marks the track to be played.
10534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * </p>
10544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * <p>
10554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * In any valid state, if it is called multiple times on the same type of track (ie. Video,
10564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * Audio, Timed Text), the most recent one will be chosen.
10574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * </p>
10584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * <p>
10594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * The first audio and video tracks are selected by default if available, even though
10604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * this method is not called. However, no timed text track will be selected until
10614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * this function is called.
10624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * </p>
10634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * <p>
10644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * Currently, only timed text tracks or audio tracks can be selected via this method.
10654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * In addition, the support for selecting an audio track at runtime is pretty limited
10664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * in that an audio track can only be selected in the <em>Prepared</em> state.
10674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * </p>
10684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     *
10694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @param index the index of the track to be selected. The valid range of the index
10704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * is 0..total number of track - 1. The total number of tracks as well as the type of
10714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * each individual track can be found by calling {@link #getTrackInfo()} method.
10724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @throws IllegalStateException if called in an invalid state.
10734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @see MediaPlayer2#getTrackInfo
10744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     */
10754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    @Override
10764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    public void selectTrack(final int index) {
10774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        addTask(new Task(CALL_COMPLETED_SELECT_TRACK, false) {
10784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            @Override
10794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            void process() {
10804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                mPlayer.selectTrack(index);
10814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
10824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        });
10834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
10844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
10854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    /**
10864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * Deselect a track.
10874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * <p>
10884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * Currently, the track must be a timed text track and no audio or video tracks can be
10894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * deselected. If the timed text track identified by index has not been
10904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * selected before, it throws an exception.
10914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * </p>
10924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     *
10934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @param index the index of the track to be deselected. The valid range of the index
10944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * is 0..total number of tracks - 1. The total number of tracks as well as the type of
10954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * each individual track can be found by calling {@link #getTrackInfo()} method.
10964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @throws IllegalStateException if called in an invalid state.
10974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @see MediaPlayer2#getTrackInfo
10984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     */
10994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    @Override
11004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    public void deselectTrack(final int index) {
11014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        addTask(new Task(CALL_COMPLETED_DESELECT_TRACK, false) {
11024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            @Override
11034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            void process() {
11044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                mPlayer.deselectTrack(index);
11054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
11064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        });
11074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
11084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
11094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    /**
11104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * Register a callback to be invoked when the media source is ready
11114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * for playback.
11124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     *
11134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @param eventCallback the callback that will be run
11144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @param executor the executor through which the callback should be invoked
11154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     */
11164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    @Override
11174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    public void setMediaPlayer2EventCallback(@NonNull Executor executor,
11184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            @NonNull MediaPlayer2EventCallback eventCallback) {
11194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        if (eventCallback == null) {
11204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            throw new IllegalArgumentException("Illegal null MediaPlayer2EventCallback");
11214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
11224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        if (executor == null) {
11234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            throw new IllegalArgumentException(
11244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    "Illegal null Executor for the MediaPlayer2EventCallback");
11254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
11264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        synchronized (mLock) {
11274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            mMp2EventCallbackRecords.add(new Pair(executor, eventCallback));
11284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
11294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
11304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
11314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    /**
11324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * Clears the {@link MediaPlayer2EventCallback}.
11334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     */
11344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    @Override
11354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    public void clearMediaPlayer2EventCallback() {
11364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        synchronized (mLock) {
11374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            mMp2EventCallbackRecords.clear();
11384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
11394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
11404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
11414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    // Modular DRM begin
11424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
11434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    /**
11444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * Register a callback to be invoked for configuration of the DRM object before
11454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * the session is created.
11464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * The callback will be invoked synchronously during the execution
11474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * of {@link #prepareDrm(UUID uuid)}.
11484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     *
11494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @param listener the callback that will be run
11504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     */
11514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    @Override
11524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    public void setOnDrmConfigHelper(final OnDrmConfigHelper listener) {
11534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        mPlayer.setOnDrmConfigHelper(new MediaPlayer.OnDrmConfigHelper() {
11544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            @Override
11554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            public void onDrmConfig(MediaPlayer mp) {
11564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                MediaPlayerSource src = mPlayer.getSourceForPlayer(mp);
11574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                DataSourceDesc dsd = src == null ? null : src.getDSD();
11584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                listener.onDrmConfig(MediaPlayer2Impl.this, dsd);
11594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
11604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        });
11614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
11624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
11634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    /**
11644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * Register a callback to be invoked when the media source is ready
11654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * for playback.
11664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     *
11674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @param eventCallback the callback that will be run
11684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @param executor the executor through which the callback should be invoked
11694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     */
11704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    @Override
11714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    public void setDrmEventCallback(@NonNull Executor executor,
11724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                                    @NonNull DrmEventCallback eventCallback) {
11734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        if (eventCallback == null) {
11744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            throw new IllegalArgumentException("Illegal null MediaPlayer2EventCallback");
11754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
11764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        if (executor == null) {
11774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            throw new IllegalArgumentException(
11784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    "Illegal null Executor for the MediaPlayer2EventCallback");
11794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
11804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        synchronized (mLock) {
11814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            mDrmEventCallbackRecords.add(new Pair(executor, eventCallback));
11824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
11834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
11844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
11854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    /**
11864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * Clears the {@link DrmEventCallback}.
11874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     */
11884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    @Override
11894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    public void clearDrmEventCallback() {
11904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        synchronized (mLock) {
11914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            mDrmEventCallbackRecords.clear();
11924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
11934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
11944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
11954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
11964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    /**
11974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * Retrieves the DRM Info associated with the current source
11984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     *
11994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @throws IllegalStateException if called before prepare()
12004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     */
12014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    @Override
12024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    public DrmInfo getDrmInfo() {
12034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        MediaPlayer.DrmInfo info = mPlayer.getDrmInfo();
12044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        return info == null ? null : new DrmInfoImpl(info.getPssh(), info.getSupportedSchemes());
12054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
12064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
12074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
12084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    /**
12094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * Prepares the DRM for the current source
12104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * <p>
12114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * If {@code OnDrmConfigHelper} is registered, it will be called during
12124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * preparation to allow configuration of the DRM properties before opening the
12134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * DRM session. Note that the callback is called synchronously in the thread that called
12144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * {@code prepareDrm}. It should be used only for a series of {@code getDrmPropertyString}
12154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * and {@code setDrmPropertyString} calls and refrain from any lengthy operation.
12164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * <p>
12174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * If the device has not been provisioned before, this call also provisions the device
12184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * which involves accessing the provisioning server and can take a variable time to
12194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * complete depending on the network connectivity.
12204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * If {@code OnDrmPreparedListener} is registered, prepareDrm() runs in non-blocking
12214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * mode by launching the provisioning in the background and returning. The listener
12224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * will be called when provisioning and preparation has finished. If a
12234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * {@code OnDrmPreparedListener} is not registered, prepareDrm() waits till provisioning
12244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * and preparation has finished, i.e., runs in blocking mode.
12254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * <p>
12264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * If {@code OnDrmPreparedListener} is registered, it is called to indicate the DRM
12274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * session being ready. The application should not make any assumption about its call
12284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * sequence (e.g., before or after prepareDrm returns), or the thread context that will
12294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * execute the listener (unless the listener is registered with a handler thread).
12304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * <p>
12314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     *
12324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @param uuid The UUID of the crypto scheme. If not known beforehand, it can be retrieved
12334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * from the source through {@code getDrmInfo} or registering a {@code onDrmInfoListener}.
12344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @throws IllegalStateException             if called before prepare(), or the DRM was
12354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     *                                           prepared already
12364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @throws UnsupportedSchemeException        if the crypto scheme is not supported
12374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @throws ResourceBusyException             if required DRM resources are in use
12384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @throws ProvisioningNetworkErrorException if provisioning is required but failed due to a
12394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     *                                           network error
12404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @throws ProvisioningServerErrorException  if provisioning is required but failed due to
12414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     *                                           the request denied by the provisioning server
12424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     */
12434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    @Override
12444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    public void prepareDrm(@NonNull UUID uuid)
12454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            throws UnsupportedSchemeException, ResourceBusyException,
12464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            ProvisioningNetworkErrorException, ProvisioningServerErrorException {
12474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        try {
12484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            mPlayer.prepareDrm(uuid);
12494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        } catch (MediaPlayer.ProvisioningNetworkErrorException e) {
12504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            throw new ProvisioningNetworkErrorException(e.getMessage());
12514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        } catch (MediaPlayer.ProvisioningServerErrorException e) {
12524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            throw new ProvisioningServerErrorException(e.getMessage());
12534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
12544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
12554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
12564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    /**
12574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * Releases the DRM session
12584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * <p>
12594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * The player has to have an active DRM session and be in stopped, or prepared
12604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * state before this call is made.
12614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * A {@code reset()} call will release the DRM session implicitly.
12624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     *
12634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @throws NoDrmSchemeException if there is no active DRM session to release
12644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     */
12654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    @Override
12664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    public void releaseDrm() throws NoDrmSchemeException {
12674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        try {
12684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            mPlayer.releaseDrm();
12694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        } catch (MediaPlayer.NoDrmSchemeException e) {
12704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            throw new NoDrmSchemeException(e.getMessage());
12714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
12724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
12734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
12744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
12754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    /**
12764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * A key request/response exchange occurs between the app and a license server
12774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * to obtain or release keys used to decrypt encrypted content.
12784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * <p>
12794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * getDrmKeyRequest() is used to obtain an opaque key request byte array that is
12804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * delivered to the license server.  The opaque key request byte array is returned
12814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * in KeyRequest.data.  The recommended URL to deliver the key request to is
12824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * returned in KeyRequest.defaultUrl.
12834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * <p>
12844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * After the app has received the key request response from the server,
12854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * it should deliver to the response to the DRM engine plugin using the method
12864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * {@link #provideDrmKeyResponse}.
12874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     *
12884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @param keySetId is the key-set identifier of the offline keys being released when keyType is
12894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * {@link MediaDrm#KEY_TYPE_RELEASE}. It should be set to null for other key requests, when
12904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * keyType is {@link MediaDrm#KEY_TYPE_STREAMING} or {@link MediaDrm#KEY_TYPE_OFFLINE}.
12914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     *
12924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @param initData is the container-specific initialization data when the keyType is
12934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * {@link MediaDrm#KEY_TYPE_STREAMING} or {@link MediaDrm#KEY_TYPE_OFFLINE}. Its meaning is
12944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * interpreted based on the mime type provided in the mimeType parameter.  It could
12954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * contain, for example, the content ID, key ID or other data obtained from the content
12964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * metadata that is required in generating the key request.
12974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * When the keyType is {@link MediaDrm#KEY_TYPE_RELEASE}, it should be set to null.
12984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     *
12994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @param mimeType identifies the mime type of the content
13004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     *
13014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @param keyType specifies the type of the request. The request may be to acquire
13024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * keys for streaming, {@link MediaDrm#KEY_TYPE_STREAMING}, or for offline content
13034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * {@link MediaDrm#KEY_TYPE_OFFLINE}, or to release previously acquired
13044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * keys ({@link MediaDrm#KEY_TYPE_RELEASE}), which are identified by a keySetId.
13054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     *
13064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @param optionalParameters are included in the key request message to
13074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * allow a client application to provide additional message parameters to the server.
13084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * This may be {@code null} if no additional parameters are to be sent.
13094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     *
13104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @throws NoDrmSchemeException if there is no active DRM session
13114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     */
13124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    @Override
13134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    @NonNull
13144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    public MediaDrm.KeyRequest getDrmKeyRequest(@Nullable byte[] keySetId,
13154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            @Nullable byte[] initData, @Nullable String mimeType, int keyType,
13164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            @Nullable Map<String, String> optionalParameters)
13174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            throws NoDrmSchemeException {
13184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        try {
13194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            return mPlayer.getKeyRequest(keySetId, initData, mimeType, keyType, optionalParameters);
13204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        } catch (MediaPlayer.NoDrmSchemeException e) {
13214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            throw new NoDrmSchemeException(e.getMessage());
13224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
13234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
13244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
13254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
13264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    /**
13274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * A key response is received from the license server by the app, then it is
13284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * provided to the DRM engine plugin using provideDrmKeyResponse. When the
13294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * response is for an offline key request, a key-set identifier is returned that
13304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * can be used to later restore the keys to a new session with the method
13314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * {@ link # restoreDrmKeys}.
13324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * When the response is for a streaming or release request, null is returned.
13334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     *
13344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @param keySetId When the response is for a release request, keySetId identifies
13354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * the saved key associated with the release request (i.e., the same keySetId
13364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * passed to the earlier {@ link #getDrmKeyRequest} call. It MUST be null when the
13374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * response is for either streaming or offline key requests.
13384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     *
13394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @param response the byte array response from the server
13404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     *
13414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @throws NoDrmSchemeException if there is no active DRM session
13424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @throws DeniedByServerException if the response indicates that the
13434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * server rejected the request
13444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     */
13454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    @Override
13464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    public byte[] provideDrmKeyResponse(@Nullable byte[] keySetId, @NonNull byte[] response)
13474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            throws NoDrmSchemeException, DeniedByServerException {
13484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        try {
13494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            return mPlayer.provideKeyResponse(keySetId, response);
13504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        } catch (MediaPlayer.NoDrmSchemeException e) {
13514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            throw new NoDrmSchemeException(e.getMessage());
13524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
13534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
13544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
13554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
13564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    /**
13574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * Restore persisted offline keys into a new session.  keySetId identifies the
13584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * keys to load, obtained from a prior call to {@link #provideDrmKeyResponse}.
13594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     *
13604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @param keySetId identifies the saved key set to restore
13614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     */
13624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    @Override
13634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    public void restoreDrmKeys(@NonNull final byte[] keySetId)
13644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            throws NoDrmSchemeException {
13654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        try {
13664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            mPlayer.restoreKeys(keySetId);
13674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        } catch (MediaPlayer.NoDrmSchemeException e) {
13684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            throw new NoDrmSchemeException(e.getMessage());
13694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
13704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
13714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
13724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
13734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    /**
13744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * Read a DRM engine plugin String property value, given the property name string.
13754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * <p>
13764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     *
13774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
13784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @param propertyName the property name
13794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     *
13804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * Standard fields names are:
13814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * {@link MediaDrm#PROPERTY_VENDOR}, {@link MediaDrm#PROPERTY_VERSION},
13824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * {@link MediaDrm#PROPERTY_DESCRIPTION}, {@link MediaDrm#PROPERTY_ALGORITHMS}
13834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     */
13844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    @Override
13854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    @NonNull
13864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    public String getDrmPropertyString(@NonNull String propertyName)
13874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            throws NoDrmSchemeException {
13884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        try {
13894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            return mPlayer.getDrmPropertyString(propertyName);
13904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        } catch (MediaPlayer.NoDrmSchemeException e) {
13914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            throw new NoDrmSchemeException(e.getMessage());
13924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
13934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
13944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
13954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
13964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    /**
13974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * Set a DRM engine plugin String property value.
13984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * <p>
13994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     *
14004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @param propertyName the property name
14014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * @param value the property value
14024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     *
14034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * Standard fields names are:
14044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * {@link MediaDrm#PROPERTY_VENDOR}, {@link MediaDrm#PROPERTY_VERSION},
14054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * {@link MediaDrm#PROPERTY_DESCRIPTION}, {@link MediaDrm#PROPERTY_ALGORITHMS}
14064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     */
14074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    @Override
14084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    public void setDrmPropertyString(@NonNull String propertyName,
14094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                                     @NonNull String value)
14104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            throws NoDrmSchemeException {
14114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        try {
14124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            mPlayer.setDrmPropertyString(propertyName, value);
14134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        } catch (MediaPlayer.NoDrmSchemeException e) {
14144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            throw new NoDrmSchemeException(e.getMessage());
14154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
14164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
14174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
14184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    private void setPlaybackParamsInternal(final PlaybackParams params) {
14194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        PlaybackParams current = mPlayer.getPlaybackParams();
14204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        mPlayer.setPlaybackParams(params);
14214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        if (current.getSpeed() != params.getSpeed()) {
14224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            notifyPlayerEvent(new PlayerEventNotifier() {
14234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                @Override
14244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                public void notify(PlayerEventCallback cb) {
14254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    cb.onPlaybackSpeedChanged(MediaPlayer2Impl.this, params.getSpeed());
14264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                }
14274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            });
14284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
14294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
14304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
14314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    private void notifyMediaPlayer2Event(final Mp2EventNotifier notifier) {
14324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        List<Pair<Executor, MediaPlayer2EventCallback>> records;
14334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        synchronized (mLock) {
14344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            records = new ArrayList<>(mMp2EventCallbackRecords);
14354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
14364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        for (final Pair<Executor, MediaPlayer2EventCallback> record : records) {
14374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            record.first.execute(new Runnable() {
14384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                @Override
14394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                public void run() {
14404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    notifier.notify(record.second);
14414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                }
14424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            });
14434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
14444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
14454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
14464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    private void notifyPlayerEvent(final PlayerEventNotifier notifier) {
14474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        ArrayMap<PlayerEventCallback, Executor> map;
14484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        synchronized (mLock) {
14494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            map = new ArrayMap<>(mPlayerEventCallbackMap);
14504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
14514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        final int callbackCount = map.size();
14524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        for (int i = 0; i < callbackCount; i++) {
14534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            final Executor executor = map.valueAt(i);
14544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            final PlayerEventCallback cb = map.keyAt(i);
14554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            executor.execute(new Runnable() {
14564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                @Override
14574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                public void run() {
14584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    notifier.notify(cb);
14594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                }
14604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            });
14614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
14624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
14634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
14644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    private void notifyDrmEvent(final DrmEventNotifier notifier) {
14654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        List<Pair<Executor, DrmEventCallback>> records;
14664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        synchronized (mLock) {
14674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            records = new ArrayList<>(mDrmEventCallbackRecords);
14684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
14694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        for (final Pair<Executor, DrmEventCallback> record : records) {
14704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            record.first.execute(new Runnable() {
14714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                @Override
14724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                public void run() {
14734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    notifier.notify(record.second);
14744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                }
14754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            });
14764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
14774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
14784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
14794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    private interface Mp2EventNotifier {
14804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        void notify(MediaPlayer2EventCallback callback);
14814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
14824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
14834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    private interface PlayerEventNotifier {
14844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        void notify(PlayerEventCallback callback);
14854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
14864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
14874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    private interface DrmEventNotifier {
14884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        void notify(DrmEventCallback callback);
14894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
14904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
14914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    private void setUpListeners(final MediaPlayerSource src) {
14924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        MediaPlayer p = src.mPlayer;
14934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        p.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
14944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            @Override
14954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            public void onPrepared(MediaPlayer mp) {
14964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                handleDataSourceError(mPlayer.onPrepared(mp));
14974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                notifyMediaPlayer2Event(new Mp2EventNotifier() {
14984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    @Override
14994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    public void notify(MediaPlayer2EventCallback callback) {
15004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        MediaPlayer2Impl mp2 = MediaPlayer2Impl.this;
15014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        DataSourceDesc dsd = src.getDSD();
15024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        callback.onInfo(mp2, dsd, MEDIA_INFO_PREPARED, 0);
15034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    }
15044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                });
15054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                notifyPlayerEvent(new PlayerEventNotifier() {
15064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    @Override
15074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    public void notify(PlayerEventCallback cb) {
15084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        cb.onMediaPrepared(MediaPlayer2Impl.this, src.getDSD());
15094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    }
15104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                });
15114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                synchronized (mTaskLock) {
15124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    if (mCurrentTask != null
15134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                            && mCurrentTask.mMediaCallType == CALL_COMPLETED_PREPARE
15144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                            && mCurrentTask.mDSD == src.getDSD()
15154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                            && mCurrentTask.mNeedToWaitForEventToComplete) {
15164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        mCurrentTask.sendCompleteNotification(CALL_STATUS_NO_ERROR);
15174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        mCurrentTask = null;
15184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        processPendingTask_l();
15194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    }
15204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                }
15214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
15224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        });
15234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        p.setOnVideoSizeChangedListener(new MediaPlayer.OnVideoSizeChangedListener() {
15244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            @Override
15254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            public void onVideoSizeChanged(MediaPlayer mp, final int width, final int height) {
15264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                notifyMediaPlayer2Event(new Mp2EventNotifier() {
15274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    @Override
15284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    public void notify(MediaPlayer2EventCallback cb) {
15294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        cb.onVideoSizeChanged(MediaPlayer2Impl.this, src.getDSD(), width, height);
15304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    }
15314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                });
15324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
15334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        });
15344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        p.setOnInfoListener(new MediaPlayer.OnInfoListener() {
15354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            @Override
15364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            public boolean onInfo(MediaPlayer mp, int what, int extra) {
15374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                switch (what) {
15384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    case MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START:
15394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        notifyMediaPlayer2Event(new Mp2EventNotifier() {
15404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                            @Override
15414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                            public void notify(MediaPlayer2EventCallback cb) {
15424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                                cb.onInfo(MediaPlayer2Impl.this, src.getDSD(),
15434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                                        MEDIA_INFO_VIDEO_RENDERING_START, 0);
15444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                            }
15454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        });
15464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        break;
15474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    case MediaPlayer.MEDIA_INFO_BUFFERING_START:
15484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        mPlayer.setBufferingState(mp, BUFFERING_STATE_BUFFERING_AND_STARVED);
15494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        break;
15504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    case MediaPlayer.MEDIA_INFO_BUFFERING_END:
15514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        mPlayer.setBufferingState(mp, BUFFERING_STATE_BUFFERING_AND_PLAYABLE);
15524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        break;
15534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                }
15544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                return false;
15554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
15564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        });
15574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        p.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
15584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            @Override
15594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            public void onCompletion(MediaPlayer mp) {
15604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                handleDataSourceError(mPlayer.onCompletion(mp));
15614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                notifyMediaPlayer2Event(new Mp2EventNotifier() {
15624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    @Override
15634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    public void notify(MediaPlayer2EventCallback cb) {
15644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        MediaPlayer2Impl mp2 = MediaPlayer2Impl.this;
15654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        DataSourceDesc dsd = src.getDSD();
15664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        cb.onInfo(mp2, dsd, MEDIA_INFO_PLAYBACK_COMPLETE, 0);
15674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    }
15684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                });
15694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
15704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        });
15714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        p.setOnErrorListener(new MediaPlayer.OnErrorListener() {
15724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            @Override
15734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            public boolean onError(MediaPlayer mp, final int what, final int extra) {
15744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                mPlayer.onError(mp);
15754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                notifyMediaPlayer2Event(new Mp2EventNotifier() {
15764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    @Override
15774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    public void notify(MediaPlayer2EventCallback cb) {
15784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        int w = sErrorEventMap.getOrDefault(what, MEDIA_ERROR_UNKNOWN);
15794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        cb.onError(MediaPlayer2Impl.this, src.getDSD(), w, extra);
15804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    }
15814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                });
15824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                return true;
15834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
15844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        });
15854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        p.setOnSeekCompleteListener(new MediaPlayer.OnSeekCompleteListener() {
15864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            @Override
15874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            public void onSeekComplete(MediaPlayer mp) {
15884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                synchronized (mTaskLock) {
15894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    if (mCurrentTask != null
15904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                            && mCurrentTask.mMediaCallType == CALL_COMPLETED_SEEK_TO
15914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                            && mCurrentTask.mNeedToWaitForEventToComplete) {
15924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        mCurrentTask.sendCompleteNotification(CALL_STATUS_NO_ERROR);
15934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        mCurrentTask = null;
15944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        processPendingTask_l();
15954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    }
15964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                }
15974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                final long seekPos = getCurrentPosition();
15984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                notifyPlayerEvent(new PlayerEventNotifier() {
15994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    @Override
16004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    public void notify(PlayerEventCallback cb) {
16014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        // TODO: The actual seeked position might be different from the
16024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        // requested position. Clarify which one is expected here.
16034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        cb.onSeekCompleted(MediaPlayer2Impl.this, seekPos);
16044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    }
16054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                });
16064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
16074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        });
16084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        p.setOnTimedMetaDataAvailableListener(
16094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                new MediaPlayer.OnTimedMetaDataAvailableListener() {
16104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    @Override
16114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    public void onTimedMetaDataAvailable(MediaPlayer mp, final TimedMetaData data) {
16124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        notifyMediaPlayer2Event(new Mp2EventNotifier() {
16134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                            @Override
16144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                            public void notify(MediaPlayer2EventCallback cb) {
16154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                                cb.onTimedMetaDataAvailable(
16164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                                        MediaPlayer2Impl.this, src.getDSD(), data);
16174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                            }
16184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        });
16194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    }
16204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                });
16214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        p.setOnInfoListener(new MediaPlayer.OnInfoListener() {
16224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            @Override
16234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            public boolean onInfo(MediaPlayer mp, final int what, final int extra) {
16244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                notifyMediaPlayer2Event(new Mp2EventNotifier() {
16254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    @Override
16264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    public void notify(MediaPlayer2EventCallback cb) {
16274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        int w = sInfoEventMap.getOrDefault(what, MEDIA_INFO_UNKNOWN);
16284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        cb.onInfo(MediaPlayer2Impl.this, src.getDSD(), w, extra);
16294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    }
16304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                });
16314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                return true;
16324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
16334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        });
16344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        p.setOnBufferingUpdateListener(new MediaPlayer.OnBufferingUpdateListener() {
16354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            @Override
16364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            public void onBufferingUpdate(MediaPlayer mp, final int percent) {
16374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                if (percent >= 100) {
16384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    mPlayer.setBufferingState(mp, BUFFERING_STATE_BUFFERING_COMPLETE);
16394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                }
16404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                src.mBufferedPercentage.set(percent);
16414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                notifyMediaPlayer2Event(new Mp2EventNotifier() {
16424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    @Override
16434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    public void notify(MediaPlayer2EventCallback cb) {
16444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        cb.onInfo(MediaPlayer2Impl.this, src.getDSD(),
16454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                                MEDIA_INFO_BUFFERING_UPDATE, percent);
16464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    }
16474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                });
16484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
16494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        });
16504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        p.setOnMediaTimeDiscontinuityListener(
16514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                new MediaPlayer.OnMediaTimeDiscontinuityListener() {
16524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    @Override
16534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    public void onMediaTimeDiscontinuity(
16544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                            MediaPlayer mp, final MediaTimestamp timestamp) {
16554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        notifyMediaPlayer2Event(new Mp2EventNotifier() {
16564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                            @Override
16574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                            public void notify(MediaPlayer2EventCallback cb) {
16584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                                cb.onMediaTimeDiscontinuity(
16594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                                        MediaPlayer2Impl.this, src.getDSD(), timestamp);
16604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                            }
16614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        });
16624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    }
16634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                });
16644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        p.setOnSubtitleDataListener(new MediaPlayer.OnSubtitleDataListener() {
16654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            @Override
16664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            public  void onSubtitleData(MediaPlayer mp, final SubtitleData data) {
16674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                notifyMediaPlayer2Event(new Mp2EventNotifier() {
16684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    @Override
16694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    public void notify(MediaPlayer2EventCallback cb) {
16704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        cb.onSubtitleData(MediaPlayer2Impl.this, src.getDSD(), data);
16714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    }
16724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                });
16734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
16744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        });
16754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        p.setOnDrmInfoListener(new MediaPlayer.OnDrmInfoListener() {
16764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            @Override
16774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            public void onDrmInfo(MediaPlayer mp, final MediaPlayer.DrmInfo drmInfo) {
16784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                notifyDrmEvent(new DrmEventNotifier() {
16794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    @Override
16804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    public void notify(DrmEventCallback cb) {
16814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        cb.onDrmInfo(MediaPlayer2Impl.this, src.getDSD(),
16824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                                new DrmInfoImpl(drmInfo.getPssh(), drmInfo.getSupportedSchemes()));
16834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    }
16844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                });
16854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
16864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        });
16874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        p.setOnDrmPreparedListener(new MediaPlayer.OnDrmPreparedListener() {
16884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            @Override
16894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            public void onDrmPrepared(MediaPlayer mp, final int status) {
16904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                notifyDrmEvent(new DrmEventNotifier() {
16914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    @Override
16924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    public void notify(DrmEventCallback cb) {
16934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        int s = sPrepareDrmStatusMap.getOrDefault(
16944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                                status, PREPARE_DRM_STATUS_PREPARATION_ERROR);
16954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        cb.onDrmPrepared(MediaPlayer2Impl.this, src.getDSD(), s);
16964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    }
16974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                });
16984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
16994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        });
17004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
17014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
17024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    /**
17034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * Encapsulates the DRM properties of the source.
17044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     */
17054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    public static final class DrmInfoImpl extends DrmInfo {
17064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        private Map<UUID, byte[]> mMapPssh;
17074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        private UUID[] mSupportedSchemes;
17084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
17094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        /**
17104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         * Returns the PSSH info of the data source for each supported DRM scheme.
17114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         */
17124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        @Override
17134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        public Map<UUID, byte[]> getPssh() {
17144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            return mMapPssh;
17154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
17164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
17174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        /**
17184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         * Returns the intersection of the data source and the device DRM schemes.
17194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         * It effectively identifies the subset of the source's DRM schemes which
17204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         * are supported by the device too.
17214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         */
17224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        @Override
17234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        public List<UUID> getSupportedSchemes() {
17244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            return Arrays.asList(mSupportedSchemes);
17254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
17264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
17274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        private DrmInfoImpl(Map<UUID, byte[]> pssh, UUID[] supportedSchemes) {
17284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            mMapPssh = pssh;
17294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            mSupportedSchemes = supportedSchemes;
17304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
17314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
17324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        private DrmInfoImpl(Parcel parcel) {
17334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            Log.v(TAG, "DrmInfoImpl(" + parcel + ") size " + parcel.dataSize());
17344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
17354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            int psshsize = parcel.readInt();
17364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            byte[] pssh = new byte[psshsize];
17374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            parcel.readByteArray(pssh);
17384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
17394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            Log.v(TAG, "DrmInfoImpl() PSSH: " + arrToHex(pssh));
17404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            mMapPssh = parsePSSH(pssh, psshsize);
17414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            Log.v(TAG, "DrmInfoImpl() PSSH: " + mMapPssh);
17424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
17434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            int supportedDRMsCount = parcel.readInt();
17444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            mSupportedSchemes = new UUID[supportedDRMsCount];
17454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            for (int i = 0; i < supportedDRMsCount; i++) {
17464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                byte[] uuid = new byte[16];
17474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                parcel.readByteArray(uuid);
17484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
17494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                mSupportedSchemes[i] = bytesToUUID(uuid);
17504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
17514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                Log.v(TAG, "DrmInfoImpl() supportedScheme[" + i + "]: "
17524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        + mSupportedSchemes[i]);
17534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
17544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
17554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            Log.v(TAG, "DrmInfoImpl() Parcel psshsize: " + psshsize
17564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    + " supportedDRMsCount: " + supportedDRMsCount);
17574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
17584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
17594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        private DrmInfoImpl makeCopy() {
17604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            return new DrmInfoImpl(this.mMapPssh, this.mSupportedSchemes);
17614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
17624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
17634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        private String arrToHex(byte[] bytes) {
17644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            String out = "0x";
17654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            for (int i = 0; i < bytes.length; i++) {
17664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                out += String.format("%02x", bytes[i]);
17674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
17684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
17694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            return out;
17704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
17714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
17724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        private UUID bytesToUUID(byte[] uuid) {
17734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            long msb = 0, lsb = 0;
17744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            for (int i = 0; i < 8; i++) {
17754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                msb |= (((long) uuid[i] & 0xff) << (8 * (7 - i)));
17764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                lsb |= (((long) uuid[i + 8] & 0xff) << (8 * (7 - i)));
17774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
17784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
17794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            return new UUID(msb, lsb);
17804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
17814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
17824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        private Map<UUID, byte[]> parsePSSH(byte[] pssh, int psshsize) {
17834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            Map<UUID, byte[]> result = new HashMap<UUID, byte[]>();
17844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
17854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            final int uuidSize = 16;
17864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            final int dataLenSize = 4;
17874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
17884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            int len = psshsize;
17894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            int numentries = 0;
17904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            int i = 0;
17914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
17924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            while (len > 0) {
17934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                if (len < uuidSize) {
17944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    Log.w(TAG, String.format("parsePSSH: len is too short to parse "
17954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                            + "UUID: (%d < 16) pssh: %d", len, psshsize));
17964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    return null;
17974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                }
17984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
17994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                byte[] subset = Arrays.copyOfRange(pssh, i, i + uuidSize);
18004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                UUID uuid = bytesToUUID(subset);
18014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                i += uuidSize;
18024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                len -= uuidSize;
18034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
18044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                // get data length
18054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                if (len < 4) {
18064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    Log.w(TAG, String.format("parsePSSH: len is too short to parse "
18074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                            + "datalen: (%d < 4) pssh: %d", len, psshsize));
18084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    return null;
18094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                }
18104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
18114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                subset = Arrays.copyOfRange(pssh, i, i + dataLenSize);
18124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                int datalen = (ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN)
18134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        ? ((subset[3] & 0xff) << 24) | ((subset[2] & 0xff) << 16)
18144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        | ((subset[1] & 0xff) << 8) | (subset[0] & 0xff)
18154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        : ((subset[0] & 0xff) << 24) | ((subset[1] & 0xff) << 16)
18164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                                | ((subset[2] & 0xff) << 8) | (subset[3] & 0xff);
18174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                i += dataLenSize;
18184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                len -= dataLenSize;
18194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
18204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                if (len < datalen) {
18214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    Log.w(TAG, String.format("parsePSSH: len is too short to parse "
18224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                            + "data: (%d < %d) pssh: %d", len, datalen, psshsize));
18234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    return null;
18244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                }
18254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
18264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                byte[] data = Arrays.copyOfRange(pssh, i, i + datalen);
18274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
18284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                // skip the data
18294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                i += datalen;
18304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                len -= datalen;
18314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
18324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                Log.v(TAG, String.format("parsePSSH[%d]: <%s, %s> pssh: %d",
18334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        numentries, uuid, arrToHex(data), psshsize));
18344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                numentries++;
18354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                result.put(uuid, data);
18364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
18374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
18384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            return result;
18394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
18404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
18414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    };  // DrmInfoImpl
18424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
18434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    /**
18444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * Thrown when a DRM method is called before preparing a DRM scheme through prepareDrm().
18454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * Extends MediaDrm.MediaDrmException
18464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     */
18474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    public static final class NoDrmSchemeExceptionImpl extends NoDrmSchemeException {
18484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        public NoDrmSchemeExceptionImpl(String detailMessage) {
18494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            super(detailMessage);
18504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
18514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
18524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
18534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    /**
18544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * Thrown when the device requires DRM provisioning but the provisioning attempt has
18554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * failed due to a network error (Internet reachability, timeout, etc.).
18564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * Extends MediaDrm.MediaDrmException
18574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     */
18584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    public static final class ProvisioningNetworkErrorExceptionImpl
18594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            extends ProvisioningNetworkErrorException {
18604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        public ProvisioningNetworkErrorExceptionImpl(String detailMessage) {
18614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            super(detailMessage);
18624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
18634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
18644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
18654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    /**
18664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * Thrown when the device requires DRM provisioning but the provisioning attempt has
18674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * failed due to the provisioning server denying the request.
18684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     * Extends MediaDrm.MediaDrmException
18694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     */
18704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    public static final class ProvisioningServerErrorExceptionImpl
18714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            extends ProvisioningServerErrorException {
18724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        public ProvisioningServerErrorExceptionImpl(String detailMessage) {
18734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            super(detailMessage);
18744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
18754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
18764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
18774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    private abstract class Task implements Runnable {
18784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        private final int mMediaCallType;
18794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        private final boolean mNeedToWaitForEventToComplete;
18804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        private DataSourceDesc mDSD;
18814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
18824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        Task(int mediaCallType, boolean needToWaitForEventToComplete) {
18834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            mMediaCallType = mediaCallType;
18844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            mNeedToWaitForEventToComplete = needToWaitForEventToComplete;
18854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
18864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
18874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        abstract void process() throws IOException, NoDrmSchemeException;
18884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
18894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        @Override
18904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        public void run() {
18914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            int status = CALL_STATUS_NO_ERROR;
18924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            try {
18934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                process();
18944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            } catch (IllegalStateException e) {
18954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                status = CALL_STATUS_INVALID_OPERATION;
18964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            } catch (IllegalArgumentException e) {
18974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                status = CALL_STATUS_BAD_VALUE;
18984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            } catch (SecurityException e) {
18994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                status = CALL_STATUS_PERMISSION_DENIED;
19004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            } catch (IOException e) {
19014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                status = CALL_STATUS_ERROR_IO;
19024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            } catch (Exception e) {
19034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                status = CALL_STATUS_ERROR_UNKNOWN;
19044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
19054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            mDSD = getCurrentDataSource();
19064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
19074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            if (!mNeedToWaitForEventToComplete || status != CALL_STATUS_NO_ERROR) {
19084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
19094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                sendCompleteNotification(status);
19104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
19114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                synchronized (mTaskLock) {
19124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    mCurrentTask = null;
19134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    processPendingTask_l();
19144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                }
19154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
19164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
19174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
19184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        private void sendCompleteNotification(final int status) {
19194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            // In {@link #notifyWhenCommandLabelReached} case, a separate callback
19204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            // {#link #onCommandLabelReached} is already called in {@code process()}.
19214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            if (mMediaCallType == CALL_COMPLETED_NOTIFY_WHEN_COMMAND_LABEL_REACHED) {
19224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                return;
19234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
19244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            notifyMediaPlayer2Event(new Mp2EventNotifier() {
19254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                @Override
19264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                public void notify(MediaPlayer2EventCallback cb) {
19274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    cb.onCallCompleted(
19284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                            MediaPlayer2Impl.this, mDSD, mMediaCallType, status);
19294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                }
19304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            });
19314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
19324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    };
19334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
1934d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    private static class DataSourceError {
1935d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        final DataSourceDesc mDSD;
19364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        final int mWhat;
19374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
19384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        final int mExtra;
19394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        DataSourceError(DataSourceDesc dsd, int what, int extra) {
19404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            mDSD = dsd;
19414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            mWhat = what;
19424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            mExtra = extra;
19434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
19444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
1945d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    }
1946d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
1947d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    private class MediaPlayerSource {
1948d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
1949d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        volatile DataSourceDesc mDSD;
1950d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        final MediaPlayer mPlayer = new MediaPlayer();
1951d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        final AtomicInteger mBufferedPercentage = new AtomicInteger(0);
1952d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        int mSourceState = SOURCE_STATE_INIT;
1953d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        @BuffState int mBufferingState = BUFFERING_STATE_UNKNOWN;
1954d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        @PlayerState int mPlayerState = PLAYER_STATE_IDLE;
1955d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        boolean mPlayPending;
1956d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
1957d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        MediaPlayerSource(final DataSourceDesc dsd) {
1958d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann            mDSD = dsd;
1959d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann            setUpListeners(this);
1960d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        }
1961d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
1962d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        DataSourceDesc getDSD() {
1963d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann            return mDSD;
1964d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        }
1965d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
1966d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    }
1967d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
1968d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    private class MediaPlayerSourceQueue {
1969d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
1970d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        List<MediaPlayerSource> mQueue = new ArrayList<>();
1971d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        float mVolume = 1.0f;
1972d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        Surface mSurface;
1973d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
1974d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        MediaPlayerSourceQueue() {
1975d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann            mQueue.add(new MediaPlayerSource(null));
1976d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        }
1977d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
1978d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        synchronized MediaPlayer getCurrentPlayer() {
19794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            return mQueue.get(0).mPlayer;
19804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
19814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
19824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        synchronized MediaPlayerSource getFirst() {
19834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            return mQueue.get(0);
19844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
19854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
19864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        synchronized void setFirst(DataSourceDesc dsd) throws IOException {
19874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            if (mQueue.isEmpty()) {
19884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                mQueue.add(0, new MediaPlayerSource(dsd));
19894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            } else {
19904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                mQueue.get(0).mDSD = dsd;
19914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                setUpListeners(mQueue.get(0));
19924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
19934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            handleDataSource(mQueue.get(0));
19944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
19954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
19964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        synchronized DataSourceError setNext(DataSourceDesc dsd) {
19974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            MediaPlayerSource src = new MediaPlayerSource(dsd);
19984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            if (mQueue.isEmpty()) {
19994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                mQueue.add(src);
20004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                return prepareMediaPlayerSource(0);
20014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            } else {
20024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                mQueue.add(1, src);
20034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                return prepareMediaPlayerSource(1);
20044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
20054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
20064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
20074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        synchronized DataSourceError setNextMultiple(List<DataSourceDesc> descs) {
20084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            List<MediaPlayerSource> sources = new ArrayList<>();
20094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            for (DataSourceDesc dsd: descs) {
20104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                sources.add(new MediaPlayerSource(dsd));
20114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
20124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            if (mQueue.isEmpty()) {
20134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                mQueue.addAll(sources);
20144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                return prepareMediaPlayerSource(0);
20154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            } else {
20164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                mQueue.addAll(1, sources);
20174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                return prepareMediaPlayerSource(1);
20184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
20194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
20204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
20214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        synchronized void play() {
20224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            MediaPlayerSource src = mQueue.get(0);
20234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            if (src.mSourceState == SOURCE_STATE_PREPARED) {
20244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                src.mPlayer.start();
20254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                setPlayerState(src.mPlayer, PLAYER_STATE_PLAYING);
20264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
20274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
20284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
20294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        synchronized void prepare() {
20304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            getCurrentPlayer().prepareAsync();
20314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
20324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
20334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        synchronized void release() {
20344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            getCurrentPlayer().release();
20354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
20364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
20374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        synchronized void prepareAsync() {
20384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            MediaPlayer mp = getCurrentPlayer();
20394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            mp.prepareAsync();
20404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            setBufferingState(mp, BUFFERING_STATE_BUFFERING_AND_STARVED);
20414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
20424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
20434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        synchronized void pause() {
20444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            MediaPlayer mp = getCurrentPlayer();
20454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            mp.pause();
20464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            setPlayerState(mp, PLAYER_STATE_PAUSED);
20474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
20484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
20494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        synchronized long getCurrentPosition() {
20504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            return getCurrentPlayer().getCurrentPosition();
20514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
20524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
20534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        synchronized long getDuration() {
20544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            return getCurrentPlayer().getDuration();
20554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
20564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
20574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        synchronized long getBufferedPosition() {
20584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            MediaPlayerSource src = mQueue.get(0);
20594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            return (long) src.mPlayer.getDuration() * src.mBufferedPercentage.get() / 100;
20604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
20614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
20624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        synchronized void setAudioAttributes(AudioAttributes attributes) {
20634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            getCurrentPlayer().setAudioAttributes(attributes);
20644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
20654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
20664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        synchronized DataSourceError onPrepared(MediaPlayer mp) {
20674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            for (int i = 0; i < mQueue.size(); i++) {
20684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                MediaPlayerSource src = mQueue.get(i);
20694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                if (mp == src.mPlayer) {
20704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    if (i == 0) {
20714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        if (src.mPlayPending) {
20724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                            src.mPlayPending = false;
20734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                            src.mPlayer.start();
20744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                            setPlayerState(src.mPlayer, PLAYER_STATE_PLAYING);
20754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        } else {
20764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                            setPlayerState(src.mPlayer, PLAYER_STATE_PAUSED);
20774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        }
20784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    }
20794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    src.mSourceState = SOURCE_STATE_PREPARED;
20804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    setBufferingState(src.mPlayer, BUFFERING_STATE_BUFFERING_AND_PLAYABLE);
20814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    return prepareMediaPlayerSource(i + 1);
20824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                }
20834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
20844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            return null;
20854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
20864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
20874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        synchronized DataSourceError onCompletion(MediaPlayer mp) {
20884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            if (!mQueue.isEmpty() && mp == getCurrentPlayer()) {
20894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                if (mQueue.size() == 1) {
20904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    setPlayerState(mp, PLAYER_STATE_PAUSED);
20914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    return null;
20924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                }
20934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                mp.release();
20944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                final MediaPlayerSource src1 = mQueue.remove(0);
20954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                final MediaPlayerSource src2 = mQueue.get(0);
20964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                if (src1.mPlayerState != src2.mPlayerState) {
20974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    notifyPlayerEvent(new PlayerEventNotifier() {
20984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        @Override
20994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        public void notify(PlayerEventCallback cb) {
21004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                            cb.onPlayerStateChanged(MediaPlayer2Impl.this, src2.mPlayerState);
21014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        }
21024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    });
21034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                }
21044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
21054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
21064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
21074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            DataSourceError err = null;
21084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            final MediaPlayerSource src = mQueue.get(0);
21094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            src.mPlayer.setSurface(mSurface);
21104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            src.mPlayer.setVolume(mVolume, mVolume);
21114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            if (src.mSourceState == SOURCE_STATE_PREPARED) {
21124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                // start next source only when it's in prepared state.
21134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                src.mPlayer.start();
21144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                notifyMediaPlayer2Event(new Mp2EventNotifier() {
21154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    @Override
21164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    public void notify(MediaPlayer2EventCallback callback) {
21174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        callback.onInfo(MediaPlayer2Impl.this, src.getDSD(),
21184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                                MEDIA_INFO_STARTED_AS_NEXT, 0);
21194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    }
21204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                });
21214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
21224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            } else {
21234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                if (src.mSourceState == SOURCE_STATE_INIT) {
21244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    err = prepareMediaPlayerSource(0);
21254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                }
21264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                src.mPlayPending = true;
21274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
21284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            return err;
21294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
21304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
21314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        synchronized void onError(MediaPlayer mp) {
21324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            setPlayerState(mp, PLAYER_STATE_ERROR);
21334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            setBufferingState(mp, BUFFERING_STATE_UNKNOWN);
21344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
21354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
21364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        synchronized DataSourceError prepareMediaPlayerSource(int n) {
21374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            if (n >= mQueue.size()
21384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    || mQueue.get(n).mSourceState != SOURCE_STATE_INIT
21394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    || getPlayerState() == PLAYER_STATE_IDLE) {
21404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                // There is no next source or it's in preparing or prepared state.
21414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                return null;
21424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
21434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
21444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            MediaPlayerSource src = mQueue.get(n);
21454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            try {
21464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                src.mSourceState = SOURCE_STATE_PREPARING;
21474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                handleDataSource(src);
21484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                src.mPlayer.prepareAsync();
21494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                return null;
21504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            } catch (Exception e) {
21514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                DataSourceDesc dsd = src.getDSD();
21524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                setPlayerState(src.mPlayer, PLAYER_STATE_ERROR);
21534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                return new DataSourceError(dsd, MEDIA_ERROR_UNKNOWN, MEDIA_ERROR_UNSUPPORTED);
21544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
21554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
21564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
21574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
21584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        synchronized void setLooping(boolean loop) {
21594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            getCurrentPlayer().setLooping(loop);
21604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
21614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
21624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        synchronized void setPlaybackParams(PlaybackParams playbackParams) {
21634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            getCurrentPlayer().setPlaybackParams(playbackParams);
21644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
21654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
21664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        synchronized float getVolume() {
21674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            return mVolume;
21684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
21694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
21704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        synchronized void setVolume(float volume) {
21714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            mVolume = volume;
21724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            getCurrentPlayer().setVolume(volume, volume);
21734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
21744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
21754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        synchronized void setSurface(Surface surface) {
21764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            mSurface = surface;
21774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            getCurrentPlayer().setSurface(surface);
21784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
21794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
21804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        synchronized int getVideoWidth() {
21814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            return getCurrentPlayer().getVideoWidth();
21824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
21834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
21844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        synchronized int getVideoHeight() {
21854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            return getCurrentPlayer().getVideoHeight();
21864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
21874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
21884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        synchronized PersistableBundle getMetrics() {
21894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            return getCurrentPlayer().getMetrics();
21904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
21914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
21924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        synchronized PlaybackParams getPlaybackParams() {
21934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            return getCurrentPlayer().getPlaybackParams();
21944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
21954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
21964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        synchronized void setSyncParams(SyncParams params) {
21974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            getCurrentPlayer().setSyncParams(params);
21984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
21994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
22004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        synchronized SyncParams getSyncParams() {
22014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            return getCurrentPlayer().getSyncParams();
22024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
22034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
22044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        synchronized void seekTo(long msec, int mode) {
22054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            getCurrentPlayer().seekTo(msec, mode);
22064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
22074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
22084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        synchronized void reset() {
22094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            MediaPlayerSource src = mQueue.get(0);
22104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            src.mPlayer.reset();
22114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            src.mBufferedPercentage.set(0);
22124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            mVolume = 1.0f;
22134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            setPlayerState(src.mPlayer, PLAYER_STATE_IDLE);
22144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            setBufferingState(src.mPlayer, BUFFERING_STATE_UNKNOWN);
22154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
22164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
22174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        synchronized MediaTimestamp getTimestamp() {
22184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            return getCurrentPlayer().getTimestamp();
22194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
22204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
22214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        synchronized void setAudioSessionId(int sessionId) {
22224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            getCurrentPlayer().setAudioSessionId(sessionId);
22234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
22244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
22254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        synchronized int getAudioSessionId() {
22264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            return getCurrentPlayer().getAudioSessionId();
22274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
22284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
22294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        synchronized void attachAuxEffect(int effectId) {
22304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            getCurrentPlayer().attachAuxEffect(effectId);
22314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
22324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
22334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        synchronized void setAuxEffectSendLevel(float level) {
22344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            getCurrentPlayer().setAuxEffectSendLevel(level);
22354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
22364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
22374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        synchronized MediaPlayer.TrackInfo[] getTrackInfo() {
22384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            return getCurrentPlayer().getTrackInfo();
22394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
22404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
22414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        synchronized int getSelectedTrack(int trackType) {
22424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            return getCurrentPlayer().getSelectedTrack(trackType);
22434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
22444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
22454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        synchronized void selectTrack(int index) {
22464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            getCurrentPlayer().selectTrack(index);
22474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
22484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
22494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        synchronized void deselectTrack(int index) {
22504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            getCurrentPlayer().deselectTrack(index);
22514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
22524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
22534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        synchronized MediaPlayer.DrmInfo getDrmInfo() {
22544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            return getCurrentPlayer().getDrmInfo();
22554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
22564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
22574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        synchronized void prepareDrm(UUID uuid)
22584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                throws ResourceBusyException, MediaPlayer.ProvisioningServerErrorException,
22594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                MediaPlayer.ProvisioningNetworkErrorException, UnsupportedSchemeException {
22604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            getCurrentPlayer().prepareDrm(uuid);
22614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
22624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
22634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        synchronized void releaseDrm() throws MediaPlayer.NoDrmSchemeException {
22644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            getCurrentPlayer().releaseDrm();
22654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
22664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
22674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        synchronized byte[] provideKeyResponse(byte[] keySetId, byte[] response)
22684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                throws DeniedByServerException, MediaPlayer.NoDrmSchemeException {
22694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            return getCurrentPlayer().provideKeyResponse(keySetId, response);
22704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
22714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
22724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        synchronized void restoreKeys(byte[] keySetId) throws MediaPlayer.NoDrmSchemeException {
22734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            getCurrentPlayer().restoreKeys(keySetId);
22744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
22754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
22764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        synchronized String getDrmPropertyString(String propertyName)
22774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                throws MediaPlayer.NoDrmSchemeException {
22784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            return getCurrentPlayer().getDrmPropertyString(propertyName);
22794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
22804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
22814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        synchronized void setDrmPropertyString(String propertyName, String value)
22824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                throws MediaPlayer.NoDrmSchemeException {
22834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            getCurrentPlayer().setDrmPropertyString(propertyName, value);
22844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
22854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
22864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        synchronized void setOnDrmConfigHelper(MediaPlayer.OnDrmConfigHelper onDrmConfigHelper) {
22874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            getCurrentPlayer().setOnDrmConfigHelper(onDrmConfigHelper);
22884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
22894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
22904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        synchronized MediaDrm.KeyRequest getKeyRequest(byte[] keySetId, byte[] initData,
22914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                String mimeType,
22924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                int keyType, Map<String, String> optionalParameters)
22934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                throws MediaPlayer.NoDrmSchemeException {
22944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            return getCurrentPlayer().getKeyRequest(keySetId, initData, mimeType, keyType,
22954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    optionalParameters);
22964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
22974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
22984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        synchronized void setPlayerState(MediaPlayer mp, @PlayerState final int state) {
22994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            for (final MediaPlayerSource src: mQueue) {
23004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                if (src.mPlayer != mp) {
23014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    continue;
23024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                }
23034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                if (src.mPlayerState == state) {
23044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    return;
23054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                }
23064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                src.mPlayerState = state;
23074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                notifyPlayerEvent(new PlayerEventNotifier() {
23084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    @Override
23094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    public void notify(PlayerEventCallback cb) {
23104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        cb.onPlayerStateChanged(MediaPlayer2Impl.this, state);
23114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    }
23124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                });
23134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                return;
23144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
23154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
23164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
23174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        synchronized void setBufferingState(MediaPlayer mp, @BuffState final int state) {
23184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            for (final MediaPlayerSource src: mQueue) {
23194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                if (src.mPlayer != mp) {
23204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    continue;
23214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                }
23224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                if (src.mBufferingState == state) {
23234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    return;
23244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                }
23254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                src.mBufferingState = state;
23264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                notifyPlayerEvent(new PlayerEventNotifier() {
23274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    @Override
23284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    public void notify(PlayerEventCallback cb) {
23294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        MediaPlayer2Impl mp2 = MediaPlayer2Impl.this;
23304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        DataSourceDesc dsd = src.getDSD();
23314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        cb.onBufferingStateChanged(mp2, dsd, state);
23324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    }
23334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                });
23344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                return;
23354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
23364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
23374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
23384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        synchronized @BuffState int getBufferingState() {
23394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            return mQueue.get(0).mBufferingState;
23404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
23414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
23424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        synchronized @PlayerState int getPlayerState() {
23434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            return mQueue.get(0).mPlayerState;
23444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
23454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
23464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        synchronized MediaPlayerSource getSourceForPlayer(MediaPlayer mp) {
23474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            for (MediaPlayerSource src: mQueue) {
23484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                if (src.mPlayer == mp) {
23494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    return src;
23504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                }
23514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
23524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            return null;
23534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
23544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
23554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
23564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
23574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann