PageRenderTime 89ms CodeModel.GetById 1ms RepoModel.GetById 0ms app.codeStats 0ms

/media/base/android/java/src/org/chromium/media/MediaServerCrashListener.java

https://github.com/chromium/chromium
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
  1. // Copyright 2016 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. package org.chromium.media;
  5. import android.media.MediaPlayer;
  6. import android.os.SystemClock;
  7. import org.chromium.base.ContextUtils;
  8. import org.chromium.base.Log;
  9. import org.chromium.base.annotations.CalledByNative;
  10. import org.chromium.base.annotations.JNINamespace;
  11. import org.chromium.base.annotations.NativeMethods;
  12. /**
  13. * Class for listening to Android MediaServer crashes to throttle media decoding
  14. * when needed.
  15. */
  16. @JNINamespace("media")
  17. public class MediaServerCrashListener implements MediaPlayer.OnErrorListener {
  18. private static final String TAG = "crMediaCrashListener";
  19. private static final long UNKNOWN_TIME = -1;
  20. // Watchdog player. Used to listen to all media server crashes.
  21. private MediaPlayer mPlayer;
  22. // Protecting the creation/release of the watchdog player.
  23. private final Object mLock = new Object();
  24. // Approximate time necessary for the MediaServer to restart after a crash.
  25. private static final int APPROX_MEDIA_SERVER_RESTART_TIME_IN_MS = 5000;
  26. // The last time we reported a failure to create the watchdog as a server crash.
  27. private long mLastReportedWatchdogCreationFailure = UNKNOWN_TIME;
  28. private long mNativeMediaServerCrashListener;
  29. @CalledByNative
  30. private static MediaServerCrashListener create(long nativeMediaServerCrashListener) {
  31. return new MediaServerCrashListener(nativeMediaServerCrashListener);
  32. }
  33. private MediaServerCrashListener(long nativeMediaServerCrashListener) {
  34. mNativeMediaServerCrashListener = nativeMediaServerCrashListener;
  35. }
  36. @CalledByNative
  37. public void releaseWatchdog() {
  38. if (mPlayer == null) return;
  39. mPlayer.release();
  40. mPlayer = null;
  41. }
  42. @CalledByNative
  43. public boolean startListening() {
  44. if (mPlayer != null) return true;
  45. try {
  46. mPlayer = MediaPlayer.create(ContextUtils.getApplicationContext(), R.raw.empty);
  47. } catch (IllegalStateException e) {
  48. Log.e(TAG, "Exception while creating the watchdog player.", e);
  49. } catch (RuntimeException e) {
  50. Log.e(TAG, "Exception while creating the watchdog player.", e);
  51. }
  52. if (mPlayer != null) {
  53. mPlayer.setOnErrorListener(MediaServerCrashListener.this);
  54. // Reset the reported creation failure time on successful
  55. // watchdog creation.
  56. mLastReportedWatchdogCreationFailure = UNKNOWN_TIME;
  57. return true;
  58. }
  59. long currentTime = SystemClock.elapsedRealtime();
  60. // It takes ~5s for the MediaServer to restart. Do not report a
  61. // failure to create a watchdog MediaPlayer as a crash more than
  62. // once per 5s, to prevent a burst of calls to startListening() from
  63. // artificially inflating the number of crashes.
  64. if (mLastReportedWatchdogCreationFailure == UNKNOWN_TIME
  65. || (currentTime - mLastReportedWatchdogCreationFailure)
  66. > APPROX_MEDIA_SERVER_RESTART_TIME_IN_MS) {
  67. Log.e(TAG, "Unable to create watchdog player, treating it as server crash.");
  68. MediaServerCrashListenerJni.get().onMediaServerCrashDetected(
  69. mNativeMediaServerCrashListener, MediaServerCrashListener.this, false);
  70. mLastReportedWatchdogCreationFailure = currentTime;
  71. }
  72. return false;
  73. }
  74. @Override
  75. public boolean onError(MediaPlayer mp, int what, int extra) {
  76. if (what == MediaPlayer.MEDIA_ERROR_SERVER_DIED) {
  77. MediaServerCrashListenerJni.get().onMediaServerCrashDetected(
  78. mNativeMediaServerCrashListener, MediaServerCrashListener.this, true);
  79. releaseWatchdog();
  80. }
  81. return true;
  82. }
  83. @NativeMethods
  84. interface Natives {
  85. void onMediaServerCrashDetected(long nativeMediaServerCrashListener,
  86. MediaServerCrashListener caller, boolean watchdogNeedsRelease);
  87. }
  88. }