/media/base/android/java/src/org/chromium/media/MediaServerCrashListener.java
Java | 109 lines | 71 code | 21 blank | 17 comment | 11 complexity | 2f63567f74a3c0b8543c3308cb2731b1 MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, Apache-2.0, BSD-3-Clause
- // Copyright 2016 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- package org.chromium.media;
- import android.media.MediaPlayer;
- import android.os.SystemClock;
- import org.chromium.base.ContextUtils;
- import org.chromium.base.Log;
- import org.chromium.base.annotations.CalledByNative;
- import org.chromium.base.annotations.JNINamespace;
- import org.chromium.base.annotations.NativeMethods;
- /**
- * Class for listening to Android MediaServer crashes to throttle media decoding
- * when needed.
- */
- @JNINamespace("media")
- public class MediaServerCrashListener implements MediaPlayer.OnErrorListener {
- private static final String TAG = "crMediaCrashListener";
- private static final long UNKNOWN_TIME = -1;
- // Watchdog player. Used to listen to all media server crashes.
- private MediaPlayer mPlayer;
- // Protecting the creation/release of the watchdog player.
- private final Object mLock = new Object();
- // Approximate time necessary for the MediaServer to restart after a crash.
- private static final int APPROX_MEDIA_SERVER_RESTART_TIME_IN_MS = 5000;
- // The last time we reported a failure to create the watchdog as a server crash.
- private long mLastReportedWatchdogCreationFailure = UNKNOWN_TIME;
- private long mNativeMediaServerCrashListener;
- @CalledByNative
- private static MediaServerCrashListener create(long nativeMediaServerCrashListener) {
- return new MediaServerCrashListener(nativeMediaServerCrashListener);
- }
- private MediaServerCrashListener(long nativeMediaServerCrashListener) {
- mNativeMediaServerCrashListener = nativeMediaServerCrashListener;
- }
- @CalledByNative
- public void releaseWatchdog() {
- if (mPlayer == null) return;
- mPlayer.release();
- mPlayer = null;
- }
- @CalledByNative
- public boolean startListening() {
- if (mPlayer != null) return true;
- try {
- mPlayer = MediaPlayer.create(ContextUtils.getApplicationContext(), R.raw.empty);
- } catch (IllegalStateException e) {
- Log.e(TAG, "Exception while creating the watchdog player.", e);
- } catch (RuntimeException e) {
- Log.e(TAG, "Exception while creating the watchdog player.", e);
- }
- if (mPlayer != null) {
- mPlayer.setOnErrorListener(MediaServerCrashListener.this);
- // Reset the reported creation failure time on successful
- // watchdog creation.
- mLastReportedWatchdogCreationFailure = UNKNOWN_TIME;
- return true;
- }
- long currentTime = SystemClock.elapsedRealtime();
- // It takes ~5s for the MediaServer to restart. Do not report a
- // failure to create a watchdog MediaPlayer as a crash more than
- // once per 5s, to prevent a burst of calls to startListening() from
- // artificially inflating the number of crashes.
- if (mLastReportedWatchdogCreationFailure == UNKNOWN_TIME
- || (currentTime - mLastReportedWatchdogCreationFailure)
- > APPROX_MEDIA_SERVER_RESTART_TIME_IN_MS) {
- Log.e(TAG, "Unable to create watchdog player, treating it as server crash.");
- MediaServerCrashListenerJni.get().onMediaServerCrashDetected(
- mNativeMediaServerCrashListener, MediaServerCrashListener.this, false);
- mLastReportedWatchdogCreationFailure = currentTime;
- }
- return false;
- }
- @Override
- public boolean onError(MediaPlayer mp, int what, int extra) {
- if (what == MediaPlayer.MEDIA_ERROR_SERVER_DIED) {
- MediaServerCrashListenerJni.get().onMediaServerCrashDetected(
- mNativeMediaServerCrashListener, MediaServerCrashListener.this, true);
- releaseWatchdog();
- }
- return true;
- }
- @NativeMethods
- interface Natives {
- void onMediaServerCrashDetected(long nativeMediaServerCrashListener,
- MediaServerCrashListener caller, boolean watchdogNeedsRelease);
- }
- }