diff options
author | Justin Klaassen <justinklaassen@google.com> | 2017-09-18 17:38:50 -0400 |
---|---|---|
committer | Justin Klaassen <justinklaassen@google.com> | 2017-09-18 17:38:50 -0400 |
commit | bc81c7ada5aab3806dd0b17498f5c9672c9b33c4 (patch) | |
tree | 7fdcc541a9ac9e92134f1a80cec557fee772bcf8 /android/media | |
parent | 10d07c88d69cc64f73a069163e7ea5ba2519a099 (diff) | |
download | android-28-bc81c7ada5aab3806dd0b17498f5c9672c9b33c4.tar.gz |
Import Android SDK Platform P [4344336]
/google/data/ro/projects/android/fetch_artifact \
--bid 4344336 \
--target sdk_phone_armv7-win_sdk \
sdk-repo-linux-sources-4344336.zip
AndroidVersion.ApiLevel has been modified to appear as 28
Change-Id: If482fcd4cfaf6c5e544e5574926be25a293e9a6d
Diffstat (limited to 'android/media')
-rw-r--r-- | android/media/AudioManager.java | 6 | ||||
-rw-r--r-- | android/media/AudioPlaybackConfiguration.java | 52 | ||||
-rw-r--r-- | android/media/MediaMuxer.java | 2 | ||||
-rw-r--r-- | android/media/MediaPlayer.java | 124 | ||||
-rw-r--r-- | android/media/MediaRouter.java | 4 |
5 files changed, 110 insertions, 78 deletions
diff --git a/android/media/AudioManager.java b/android/media/AudioManager.java index 15754574..186b2650 100644 --- a/android/media/AudioManager.java +++ b/android/media/AudioManager.java @@ -3058,7 +3058,11 @@ public class AudioManager { private final IPlaybackConfigDispatcher mPlayCb = new IPlaybackConfigDispatcher.Stub() { @Override - public void dispatchPlaybackConfigChange(List<AudioPlaybackConfiguration> configs) { + public void dispatchPlaybackConfigChange(List<AudioPlaybackConfiguration> configs, + boolean flush) { + if (flush) { + Binder.flushPendingCommands(); + } synchronized(mPlaybackCallbackLock) { if (mPlaybackCallbackList != null) { for (int i=0 ; i < mPlaybackCallbackList.size() ; i++) { diff --git a/android/media/AudioPlaybackConfiguration.java b/android/media/AudioPlaybackConfiguration.java index 14bc5551..8a36f91c 100644 --- a/android/media/AudioPlaybackConfiguration.java +++ b/android/media/AudioPlaybackConfiguration.java @@ -212,8 +212,10 @@ public final class AudioPlaybackConfiguration implements Parcelable { * @hide */ public void init() { - if (mIPlayerShell != null) { - mIPlayerShell.monitorDeath(); + synchronized (this) { + if (mIPlayerShell != null) { + mIPlayerShell.monitorDeath(); + } } } @@ -322,7 +324,11 @@ public final class AudioPlaybackConfiguration implements Parcelable { */ @SystemApi public PlayerProxy getPlayerProxy() { - return mIPlayerShell == null ? null : new PlayerProxy(this); + final IPlayerShell ips; + synchronized (this) { + ips = mIPlayerShell; + } + return ips == null ? null : new PlayerProxy(this); } /** @@ -330,7 +336,11 @@ public final class AudioPlaybackConfiguration implements Parcelable { * @return the IPlayer interface for the associated player */ IPlayer getIPlayer() { - return mIPlayerShell == null ? null : mIPlayerShell.getIPlayer(); + final IPlayerShell ips; + synchronized (this) { + ips = mIPlayerShell; + } + return ips == null ? null : ips.getIPlayer(); } /** @@ -351,10 +361,14 @@ public final class AudioPlaybackConfiguration implements Parcelable { * @return true if the state changed, false otherwise */ public boolean handleStateEvent(int event) { - final boolean changed = (mPlayerState != event); - mPlayerState = event; - if ((event == PLAYER_STATE_RELEASED) && (mIPlayerShell != null)) { - mIPlayerShell.release(); + final boolean changed; + synchronized (this) { + changed = (mPlayerState != event); + mPlayerState = event; + if (changed && (event == PLAYER_STATE_RELEASED) && (mIPlayerShell != null)) { + mIPlayerShell.release(); + mIPlayerShell = null; + } } return changed; } @@ -447,7 +461,11 @@ public final class AudioPlaybackConfiguration implements Parcelable { dest.writeInt(mClientPid); dest.writeInt(mPlayerState); mPlayerAttr.writeToParcel(dest, 0); - dest.writeStrongInterface(mIPlayerShell == null ? null : mIPlayerShell.getIPlayer()); + final IPlayerShell ips; + synchronized (this) { + ips = mIPlayerShell; + } + dest.writeStrongInterface(ips == null ? null : ips.getIPlayer()); } private AudioPlaybackConfiguration(Parcel in) { @@ -479,14 +497,17 @@ public final class AudioPlaybackConfiguration implements Parcelable { static final class IPlayerShell implements IBinder.DeathRecipient { final AudioPlaybackConfiguration mMonitor; // never null - private IPlayer mIPlayer; + private volatile IPlayer mIPlayer; IPlayerShell(@NonNull AudioPlaybackConfiguration monitor, @NonNull IPlayer iplayer) { mMonitor = monitor; mIPlayer = iplayer; } - void monitorDeath() { + synchronized void monitorDeath() { + if (mIPlayer == null) { + return; + } try { mIPlayer.asBinder().linkToDeath(this, 0); } catch (RemoteException e) { @@ -509,8 +530,13 @@ public final class AudioPlaybackConfiguration implements Parcelable { } else if (DEBUG) { Log.i(TAG, "IPlayerShell binderDied"); } } - void release() { + synchronized void release() { + if (mIPlayer == null) { + return; + } mIPlayer.asBinder().unlinkToDeath(this, 0); + mIPlayer = null; + Binder.flushPendingCommands(); } } @@ -532,7 +558,7 @@ public final class AudioPlaybackConfiguration implements Parcelable { case PLAYER_TYPE_HW_SOURCE: return "hardware source"; case PLAYER_TYPE_EXTERNAL_PROXY: return "external proxy"; default: - return "unknown player type - FIXME"; + return "unknown player type " + type + " - FIXME"; } } diff --git a/android/media/MediaMuxer.java b/android/media/MediaMuxer.java index 832b2974..91e57ee0 100644 --- a/android/media/MediaMuxer.java +++ b/android/media/MediaMuxer.java @@ -70,7 +70,7 @@ import java.util.Map; <p> Per-frame metadata is useful in carrying extra information that correlated with video or audio to facilitate offline processing, e.g. gyro signals from the sensor could help video stabilization when - doing offline processing. Metaadata track is only supported in MP4 container. When adding a new + doing offline processing. Metadata track is only supported in MP4 container. When adding a new metadata track, track's mime format must start with prefix "application/", e.g. "applicaton/gyro". Metadata's format/layout will be defined by the application. Writing metadata is nearly the same as writing video/audio data except that the data will not be from mediacodec. Application just needs diff --git a/android/media/MediaPlayer.java b/android/media/MediaPlayer.java index 0d99473c..7787d4b5 100644 --- a/android/media/MediaPlayer.java +++ b/android/media/MediaPlayer.java @@ -2072,6 +2072,20 @@ public class MediaPlayer extends PlayerBase private native void _reset(); /** + * Set up a timer for {@link #TimeProvider}. {@link #TimeProvider} will be + * notified when the presentation time reaches (becomes greater than or equal to) + * the value specified. + * + * @param mediaTimeUs presentation time to get timed event callback at + * @hide + */ + public void notifyAt(long mediaTimeUs) { + _notifyAt(mediaTimeUs); + } + + private native void _notifyAt(long mediaTimeUs); + + /** * Sets the audio stream type for this MediaPlayer. See {@link AudioManager} * for a list of stream types. Must call this method before prepare() or * prepareAsync() in order for the target stream type to become effective @@ -3155,6 +3169,7 @@ public class MediaPlayer extends PlayerBase private static final int MEDIA_PAUSED = 7; private static final int MEDIA_STOPPED = 8; private static final int MEDIA_SKIPPED = 9; + private static final int MEDIA_NOTIFY_TIME = 98; private static final int MEDIA_TIMED_TEXT = 99; private static final int MEDIA_ERROR = 100; private static final int MEDIA_INFO = 200; @@ -3345,6 +3360,14 @@ public class MediaPlayer extends PlayerBase } // No real default action so far. return; + + case MEDIA_NOTIFY_TIME: + TimeProvider timeProvider = mTimeProvider; + if (timeProvider != null) { + timeProvider.onNotifyTime(); + } + return; + case MEDIA_TIMED_TEXT: OnTimedTextListener onTimedTextListener = mOnTimedTextListener; if (onTimedTextListener == null) @@ -5144,19 +5167,16 @@ public class MediaPlayer extends PlayerBase private boolean mStopped = true; private boolean mBuffering; private long mLastReportedTime; - private long mTimeAdjustment; // since we are expecting only a handful listeners per stream, there is // no need for log(N) search performance private MediaTimeProvider.OnMediaTimeListener mListeners[]; private long mTimes[]; - private long mLastNanoTime; private Handler mEventHandler; private boolean mRefresh = false; private boolean mPausing = false; private boolean mSeeking = false; private static final int NOTIFY = 1; private static final int NOTIFY_TIME = 0; - private static final int REFRESH_AND_NOTIFY_TIME = 1; private static final int NOTIFY_STOP = 2; private static final int NOTIFY_SEEK = 3; private static final int NOTIFY_TRACK_DATA = 4; @@ -5188,13 +5208,11 @@ public class MediaPlayer extends PlayerBase mListeners = new MediaTimeProvider.OnMediaTimeListener[0]; mTimes = new long[0]; mLastTimeUs = 0; - mTimeAdjustment = 0; } private void scheduleNotification(int type, long delayUs) { // ignore time notifications until seek is handled - if (mSeeking && - (type == NOTIFY_TIME || type == REFRESH_AND_NOTIFY_TIME)) { + if (mSeeking && type == NOTIFY_TIME) { return; } @@ -5221,6 +5239,14 @@ public class MediaPlayer extends PlayerBase } /** @hide */ + public void onNotifyTime() { + synchronized (this) { + if (DEBUG) Log.d(TAG, "onNotifyTime: "); + scheduleNotification(NOTIFY_TIME, 0 /* delay */); + } + } + + /** @hide */ public void onPaused(boolean paused) { synchronized(this) { if (DEBUG) Log.d(TAG, "onPaused: " + paused); @@ -5231,7 +5257,7 @@ public class MediaPlayer extends PlayerBase } else { mPausing = paused; // special handling if player disappeared mSeeking = false; - scheduleNotification(REFRESH_AND_NOTIFY_TIME, 0 /* delay */); + scheduleNotification(NOTIFY_TIME, 0 /* delay */); } } } @@ -5241,7 +5267,7 @@ public class MediaPlayer extends PlayerBase synchronized (this) { if (DEBUG) Log.d(TAG, "onBuffering: " + buffering); mBuffering = buffering; - scheduleNotification(REFRESH_AND_NOTIFY_TIME, 0 /* delay */); + scheduleNotification(NOTIFY_TIME, 0 /* delay */); } } @@ -5438,7 +5464,7 @@ public class MediaPlayer extends PlayerBase if (nextTimeUs > nowUs && !mPaused) { // schedule callback at nextTimeUs if (DEBUG) Log.d(TAG, "scheduling for " + nextTimeUs + " and " + nowUs); - scheduleNotification(NOTIFY_TIME, nextTimeUs - nowUs); + mPlayer.notifyAt(nextTimeUs); } else { mEventHandler.removeMessages(NOTIFY); // no more callbacks @@ -5449,25 +5475,6 @@ public class MediaPlayer extends PlayerBase } } - private long getEstimatedTime(long nanoTime, boolean monotonic) { - if (mPaused) { - mLastReportedTime = mLastTimeUs + mTimeAdjustment; - } else { - long timeSinceRead = (nanoTime - mLastNanoTime) / 1000; - mLastReportedTime = mLastTimeUs + timeSinceRead; - if (mTimeAdjustment > 0) { - long adjustment = - mTimeAdjustment - timeSinceRead / TIME_ADJUSTMENT_RATE; - if (adjustment <= 0) { - mTimeAdjustment = 0; - } else { - mLastReportedTime += adjustment; - } - } - } - return mLastReportedTime; - } - public long getCurrentTimeUs(boolean refreshTime, boolean monotonic) throws IllegalStateException { synchronized (this) { @@ -5477,42 +5484,38 @@ public class MediaPlayer extends PlayerBase return mLastReportedTime; } - long nanoTime = System.nanoTime(); - if (refreshTime || - nanoTime >= mLastNanoTime + MAX_NS_WITHOUT_POSITION_CHECK) { - try { - mLastTimeUs = mPlayer.getCurrentPosition() * 1000L; - mPaused = !mPlayer.isPlaying() || mBuffering; - if (DEBUG) Log.v(TAG, (mPaused ? "paused" : "playing") + " at " + mLastTimeUs); - } catch (IllegalStateException e) { - if (mPausing) { - // if we were pausing, get last estimated timestamp - mPausing = false; - getEstimatedTime(nanoTime, monotonic); - mPaused = true; - if (DEBUG) Log.d(TAG, "illegal state, but pausing: estimating at " + mLastReportedTime); - return mLastReportedTime; + try { + mLastTimeUs = mPlayer.getCurrentPosition() * 1000L; + mPaused = !mPlayer.isPlaying() || mBuffering; + if (DEBUG) Log.v(TAG, (mPaused ? "paused" : "playing") + " at " + mLastTimeUs); + } catch (IllegalStateException e) { + if (mPausing) { + // if we were pausing, get last estimated timestamp + mPausing = false; + if (!monotonic || mLastReportedTime < mLastTimeUs) { + mLastReportedTime = mLastTimeUs; } - // TODO get time when prepared - throw e; + mPaused = true; + if (DEBUG) Log.d(TAG, "illegal state, but pausing: estimating at " + mLastReportedTime); + return mLastReportedTime; } - mLastNanoTime = nanoTime; - if (monotonic && mLastTimeUs < mLastReportedTime) { - /* have to adjust time */ - mTimeAdjustment = mLastReportedTime - mLastTimeUs; - if (mTimeAdjustment > 1000000) { - // schedule seeked event if time jumped significantly - // TODO: do this properly by introducing an exception - mStopped = false; - mSeeking = true; - scheduleNotification(NOTIFY_SEEK, 0 /* delay */); - } - } else { - mTimeAdjustment = 0; + // TODO get time when prepared + throw e; + } + if (monotonic && mLastTimeUs < mLastReportedTime) { + /* have to adjust time */ + if (mLastReportedTime - mLastTimeUs > 1000000) { + // schedule seeked event if time jumped significantly + // TODO: do this properly by introducing an exception + mStopped = false; + mSeeking = true; + scheduleNotification(NOTIFY_SEEK, 0 /* delay */); } + } else { + mLastReportedTime = mLastTimeUs; } - return getEstimatedTime(nanoTime, monotonic); + return mLastReportedTime; } } @@ -5526,9 +5529,6 @@ public class MediaPlayer extends PlayerBase if (msg.what == NOTIFY) { switch (msg.arg1) { case NOTIFY_TIME: - notifyTimedEvent(false /* refreshTime */); - break; - case REFRESH_AND_NOTIFY_TIME: notifyTimedEvent(true /* refreshTime */); break; case NOTIFY_STOP: diff --git a/android/media/MediaRouter.java b/android/media/MediaRouter.java index 2894e895..fe427a73 100644 --- a/android/media/MediaRouter.java +++ b/android/media/MediaRouter.java @@ -193,7 +193,9 @@ public class MediaRouter { } else if ((newRoutes.mainType&AudioRoutesInfo.MAIN_DOCK_SPEAKERS) != 0) { name = com.android.internal.R.string.default_audio_route_name_dock_speakers; } else if ((newRoutes.mainType&AudioRoutesInfo.MAIN_HDMI) != 0) { - name = com.android.internal.R.string.default_media_route_name_hdmi; + name = com.android.internal.R.string.default_audio_route_name_hdmi; + } else if ((newRoutes.mainType&AudioRoutesInfo.MAIN_USB) != 0) { + name = com.android.internal.R.string.default_audio_route_name_usb; } else { name = com.android.internal.R.string.default_audio_route_name; } |