Merge "MediaPlayer: fix new API seekTo to address API review." into oc-dev
am: 62a3aa745a

Change-Id: I09feef76ad0ea67eaebecb6a14494b4fcb33e1e8
diff --git a/api/current.txt b/api/current.txt
index f4d906a..2e97782 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -22780,7 +22780,7 @@
     method public void releaseDrm() throws android.media.MediaPlayer.NoDrmSchemeException;
     method public void reset();
     method public void restoreKeys(byte[]) throws android.media.MediaPlayer.NoDrmSchemeException;
-    method public void seekTo(int, int) throws java.lang.IllegalStateException;
+    method public void seekTo(long, int);
     method public void seekTo(int) throws java.lang.IllegalStateException;
     method public void selectTrack(int) throws java.lang.IllegalStateException;
     method public void setAudioAttributes(android.media.AudioAttributes) throws java.lang.IllegalArgumentException;
diff --git a/api/system-current.txt b/api/system-current.txt
index ea1e515..5ad6cd8 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -24616,7 +24616,7 @@
     method public void releaseDrm() throws android.media.MediaPlayer.NoDrmSchemeException;
     method public void reset();
     method public void restoreKeys(byte[]) throws android.media.MediaPlayer.NoDrmSchemeException;
-    method public void seekTo(int, int) throws java.lang.IllegalStateException;
+    method public void seekTo(long, int);
     method public void seekTo(int) throws java.lang.IllegalStateException;
     method public void selectTrack(int) throws java.lang.IllegalStateException;
     method public void setAudioAttributes(android.media.AudioAttributes) throws java.lang.IllegalArgumentException;
diff --git a/api/test-current.txt b/api/test-current.txt
index 247a9a9..296a3f9 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -22888,7 +22888,7 @@
     method public void releaseDrm() throws android.media.MediaPlayer.NoDrmSchemeException;
     method public void reset();
     method public void restoreKeys(byte[]) throws android.media.MediaPlayer.NoDrmSchemeException;
-    method public void seekTo(int, int) throws java.lang.IllegalStateException;
+    method public void seekTo(long, int);
     method public void seekTo(int) throws java.lang.IllegalStateException;
     method public void selectTrack(int) throws java.lang.IllegalStateException;
     method public void setAudioAttributes(android.media.AudioAttributes) throws java.lang.IllegalArgumentException;
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index 293ceea..5cbccea 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -140,7 +140,7 @@
  *         {@link #getVideoWidth()}, {@link #setAudioAttributes(AudioAttributes)},
  *         {@link #setLooping(boolean)},
  *         {@link #setVolume(float, float)}, {@link #pause()}, {@link #start()},
- *         {@link #stop()}, {@link #seekTo(int, int)}, {@link #prepare()} or
+ *         {@link #stop()}, {@link #seekTo(long, int)}, {@link #prepare()} or
  *         {@link #prepareAsync()} in the <em>Idle</em> state for both cases. If any of these
  *         methods is called right after a MediaPlayer object is constructed,
  *         the user supplied callback method OnErrorListener.onError() won't be
@@ -286,9 +286,9 @@
  *         </ul>
  *         </li>
  *     <li>The playback position can be adjusted with a call to
- *         {@link #seekTo(int, int)}.
+ *         {@link #seekTo(long, int)}.
  *         <ul>
- *         <li>Although the asynchronuous {@link #seekTo(int, int)}
+ *         <li>Although the asynchronuous {@link #seekTo(long, int)}
  *         call returns right away, the actual seek operation may take a while to
  *         finish, especially for audio/video being streamed. When the actual
  *         seek operation completes, the internal player engine calls a user
@@ -296,9 +296,9 @@
  *         has been registered beforehand via
  *         {@link #setOnSeekCompleteListener(OnSeekCompleteListener)}.</li>
  *         <li>Please
- *         note that {@link #seekTo(int, int)} can also be called in the other states,
+ *         note that {@link #seekTo(long, int)} can also be called in the other states,
  *         such as <em>Prepared</em>, <em>Paused</em> and <em>PlaybackCompleted
- *         </em> state. When {@link #seekTo(int, int)} is called in those states,
+ *         </em> state. When {@link #seekTo(long, int)} is called in those states,
  *         one video frame will be displayed if the stream has video and the requested
  *         position is valid.
  *         </li>
@@ -1704,42 +1704,42 @@
     public native SyncParams getSyncParams();
 
     /**
-     * Seek modes used in method seekTo(int, int) to move media position
+     * Seek modes used in method seekTo(long, int) to move media position
      * to a specified location.
      *
      * Do not change these mode values without updating their counterparts
      * in include/media/IMediaSource.h!
      */
     /**
-     * This mode is used with {@link #seekTo(int, int)} to move media position to
+     * This mode is used with {@link #seekTo(long, int)} to move media position to
      * a sync (or key) frame associated with a data source that is located
      * right before or at the given time.
      *
-     * @see #seekTo(int, int)
+     * @see #seekTo(long, int)
      */
     public static final int SEEK_PREVIOUS_SYNC    = 0x00;
     /**
-     * This mode is used with {@link #seekTo(int, int)} to move media position to
+     * This mode is used with {@link #seekTo(long, int)} to move media position to
      * a sync (or key) frame associated with a data source that is located
      * right after or at the given time.
      *
-     * @see #seekTo(int, int)
+     * @see #seekTo(long, int)
      */
     public static final int SEEK_NEXT_SYNC        = 0x01;
     /**
-     * This mode is used with {@link #seekTo(int, int)} to move media position to
+     * This mode is used with {@link #seekTo(long, int)} to move media position to
      * a sync (or key) frame associated with a data source that is located
      * closest to (in time) or at the given time.
      *
-     * @see #seekTo(int, int)
+     * @see #seekTo(long, int)
      */
     public static final int SEEK_CLOSEST_SYNC     = 0x02;
     /**
-     * This mode is used with {@link #seekTo(int, int)} to move media position to
+     * This mode is used with {@link #seekTo(long, int)} to move media position to
      * a frame (not necessarily a key frame) associated with a data source that
      * is located closest to or at the given time.
      *
-     * @see #seekTo(int, int)
+     * @see #seekTo(long, int)
      */
     public static final int SEEK_CLOSEST          = 0x03;
 
@@ -1754,7 +1754,7 @@
     @Retention(RetentionPolicy.SOURCE)
     public @interface SeekMode {}
 
-    private native final void _seekTo(int msec, int mode);
+    private native final void _seekTo(long msec, int mode);
 
     /**
      * Moves the media to specified time position by considering the given mode.
@@ -1786,17 +1786,25 @@
      * initialized
      * @throws IllegalArgumentException if the mode is invalid.
      */
-    public void seekTo(int msec, @SeekMode int mode) throws IllegalStateException {
+    public void seekTo(long msec, @SeekMode int mode) {
         if (mode < SEEK_PREVIOUS_SYNC || mode > SEEK_CLOSEST) {
             final String msg = "Illegal seek mode: " + mode;
             throw new IllegalArgumentException(msg);
         }
+        // TODO: pass long to native, instead of truncating here.
+        if (msec > Integer.MAX_VALUE) {
+            Log.w(TAG, "seekTo offset " + msec + " is too large, cap to " + Integer.MAX_VALUE);
+            msec = Integer.MAX_VALUE;
+        } else if (msec < Integer.MIN_VALUE) {
+            Log.w(TAG, "seekTo offset " + msec + " is too small, cap to " + Integer.MIN_VALUE);
+            msec = Integer.MIN_VALUE;
+        }
         _seekTo(msec, mode);
     }
 
     /**
      * Seeks to specified time position.
-     * Same as {@link #seekTo(int, int)} with {@code mode = SEEK_PREVIOUS_SYNC}.
+     * Same as {@link #seekTo(long, int)} with {@code mode = SEEK_PREVIOUS_SYNC}.
      *
      * @param msec the offset in milliseconds from the start to seek to
      * @throws IllegalStateException if the internal player engine has not been
diff --git a/media/jni/android_media_MediaPlayer.cpp b/media/jni/android_media_MediaPlayer.cpp
index 2fc4afd..3711462 100644
--- a/media/jni/android_media_MediaPlayer.cpp
+++ b/media/jni/android_media_MediaPlayer.cpp
@@ -662,15 +662,15 @@
 }
 
 static void
-android_media_MediaPlayer_seekTo(JNIEnv *env, jobject thiz, jint msec, jint mode)
+android_media_MediaPlayer_seekTo(JNIEnv *env, jobject thiz, jlong msec, jint mode)
 {
     sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
     if (mp == NULL ) {
         jniThrowException(env, "java/lang/IllegalStateException", NULL);
         return;
     }
-    ALOGV("seekTo: %d(msec), mode=%d", msec, mode);
-    process_media_player_call( env, thiz, mp->seekTo(msec, (MediaPlayerSeekMode)mode), NULL, NULL );
+    ALOGV("seekTo: %lld(msec), mode=%d", (long long)msec, mode);
+    process_media_player_call( env, thiz, mp->seekTo((int)msec, (MediaPlayerSeekMode)mode), NULL, NULL );
 }
 
 static jint
@@ -1398,7 +1398,7 @@
     {"getPlaybackParams", "()Landroid/media/PlaybackParams;", (void *)android_media_MediaPlayer_getPlaybackParams},
     {"setSyncParams",     "(Landroid/media/SyncParams;)V",  (void *)android_media_MediaPlayer_setSyncParams},
     {"getSyncParams",     "()Landroid/media/SyncParams;",   (void *)android_media_MediaPlayer_getSyncParams},
-    {"_seekTo",             "(II)V",                            (void *)android_media_MediaPlayer_seekTo},
+    {"_seekTo",             "(JI)V",                            (void *)android_media_MediaPlayer_seekTo},
     {"_pause",              "()V",                              (void *)android_media_MediaPlayer_pause},
     {"isPlaying",           "()Z",                              (void *)android_media_MediaPlayer_isPlaying},
     {"getCurrentPosition",  "()I",                              (void *)android_media_MediaPlayer_getCurrentPosition},