| Index: media/base/android/media_service_throttler.h
|
| diff --git a/media/base/android/media_service_throttler.h b/media/base/android/media_service_throttler.h
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..5d2a2fe9dcd646396bda33a80a2328f0c8c36696
|
| --- /dev/null
|
| +++ b/media/base/android/media_service_throttler.h
|
| @@ -0,0 +1,118 @@
|
| +// 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.
|
| +
|
| +#ifndef MEDIA_BASE_ANDROID_MEDIA_SERVICE_THROTTLER_H_
|
| +#define MEDIA_BASE_ANDROID_MEDIA_SERVICE_THROTTLER_H_
|
| +
|
| +#include <memory>
|
| +
|
| +#include "base/callback_forward.h"
|
| +#include "base/cancelable_callback.h"
|
| +#include "base/lazy_instance.h"
|
| +#include "base/macros.h"
|
| +#include "base/single_thread_task_runner.h"
|
| +#include "base/time/tick_clock.h"
|
| +#include "base/time/time.h"
|
| +#include "media/base/media_export.h"
|
| +
|
| +namespace media {
|
| +class MediaServerCrashListener;
|
| +
|
| +// The MediaServiceThrottler's purpose is to prevent a compromised process from
|
| +// attempting to crash the MediaServer, by repeatedly requesting resources or
|
| +// issuing malformed requests. It is used to delay the creation of Android
|
| +// MediaServer clients (currently only the MediaPlayerBridge) by some amount
|
| +// that makes it impractical to DOS the MediaServer (by requesting the
|
| +// playback of hundreds of malformed URLs per second, for example).
|
| +//
|
| +// GetDelayForClientCreation() linearly spaces out client creations and
|
| +// guarantees that the clients will never be scheduled faster than some
|
| +// threshold (see the .cc file for the latest values).
|
| +// The MediaServiceThrottler also uses a MediaServerCrashListener to monitor for
|
| +// MediaServer crashes. The delay between client creations is exponentially
|
| +// increased (up to a cap) based on the number of recent MediaServer crashes.
|
| +//
|
| +// NOTE: The MediaServiceThrottler has small moving window that allows a certain
|
| +// number of clients to be immediately scheduled, while still respecting the
|
| +// max scheduling rates. This allows clients to be 'burst created' to account
|
| +// for a burst of requests from a new page load.
|
| +//
|
| +// For an example of usage, look at MediaPlayerRenderer::Initialize().
|
| +class MEDIA_EXPORT MediaServiceThrottler {
|
| + public:
|
| + // Called to get the singleton MediaServiceThrottler instance.
|
| + // The first thread on which GetInstance() is called is the thread on which
|
| + // calls to OnMediaServerCrash() will be signaled.
|
| + static MediaServiceThrottler* GetInstance();
|
| +
|
| + // Returns the delay to wait until a new client is allowed to be created.
|
| + base::TimeDelta GetDelayForClientCreation();
|
| +
|
| + // Test only methods.
|
| + void SetTickClockForTesting(base::TickClock* clock);
|
| + void ResetInternalStateForTesting();
|
| + base::TimeDelta GetBaseThrottlingRateForTesting();
|
| + bool IsCrashListenerAliveForTesting();
|
| + void SetCrashListenerTaskRunnerForTesting(
|
| + scoped_refptr<base::SingleThreadTaskRunner> crash_listener_task_runner);
|
| +
|
| + private:
|
| + friend struct base::DefaultLazyInstanceTraits<MediaServiceThrottler>;
|
| + friend class MediaServiceThrottlerTest;
|
| +
|
| + MediaServiceThrottler();
|
| + virtual ~MediaServiceThrottler();
|
| +
|
| + // Called by the |crash_listener_| whenever a crash is detected.
|
| + void OnMediaServerCrash(bool watchdog_needs_release);
|
| +
|
| + // Updates |current_craches_| according to a linear decay function.
|
| + void UpdateServerCrashes();
|
| +
|
| + // Ensures that the MediaServerCrashListener was properly started (can lead
|
| + // to OnMediaServerCrash() being called in the case it hasn't).
|
| + void EnsureCrashListenerStarted();
|
| +
|
| + // Frees up the resources used by |crash_listener_|;
|
| + void ReleaseCrashListener();
|
| +
|
| + // Gets the delay for ScheduleClientCreation(), which grows exponentially
|
| + // based on |current_crashes_|.
|
| + base::TimeDelta GetThrottlingDelayFromServerCrashes();
|
| +
|
| + std::unique_ptr<base::TickClock> clock_;
|
| +
|
| + // Effective number of media server crashes.
|
| + // NOTE: This is of type double because we decay the number of crashes at a
|
| + // rate of one per minute (e.g. 30s after a single crash, |curren_crashes_|
|
| + // should be equal to 0.5).
|
| + double current_crashes_;
|
| +
|
| + // Next time at which a client creation can be scheduled.
|
| + base::TimeTicks next_schedulable_slot_;
|
| +
|
| + // Last media server crash time.
|
| + base::TimeTicks last_server_crash_;
|
| +
|
| + // Last time UpdateServerCrashes() was called.
|
| + base::TimeTicks last_current_crash_update_time_;
|
| +
|
| + // Last time ScheduleClientCreation() was called.
|
| + base::TimeTicks last_schedule_call_;
|
| +
|
| + // Callbacks used to release |crash_listener_| after 60s of inactivity.
|
| + base::Closure release_crash_listener_cb_;
|
| + base::CancelableClosure cancelable_release_crash_listener_cb_;
|
| +
|
| + // Listener that verifies
|
| + std::unique_ptr<MediaServerCrashListener> crash_listener_;
|
| +
|
| + scoped_refptr<base::SingleThreadTaskRunner> crash_listener_task_runner_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(MediaServiceThrottler);
|
| +};
|
| +
|
| +} // namespace media
|
| +
|
| +#endif // MEDIA_BASE_ANDROID_MEDIA_SERVICE_THROTTLER_H_
|
|
|