// Copyright 2021 Google LLC. All Rights Reserved. This file and proprietary // source code may only be used and distributed under the Widevine License // Agreement. #ifndef WVCDM_CORE_OKP_FALLBACK_POLICY_H_ #define WVCDM_CORE_OKP_FALLBACK_POLICY_H_ #include #include #include #include "clock.h" #include "file_store.h" #include "okp_info.h" #include "wv_class_utils.h" namespace wvcdm { class DeviceFiles; // OTA Keybox Provisioning (OKP) namespace okp { static constexpr int64_t kSecondsPerHour = 60 * 60; static constexpr int64_t kSecondsPerDay = kSecondsPerHour * 24; // Initial backoff duration. Subsequent backoff durations for the // same engine will double its previous duration. static constexpr int64_t kAverageInitialBackoffDuration = kSecondsPerDay; static constexpr int64_t kFastBackoffDuration = 30; // 30 seconds. static constexpr int64_t kInitialBackoffDurationDelta = kSecondsPerHour * 12; // Minimum backoff duration which an device will be required to // backoff the first time. static constexpr int64_t kMinInitialBackoffDuration = kAverageInitialBackoffDuration - kInitialBackoffDurationDelta; static constexpr int64_t kMaxInitialBackoffDuration = kAverageInitialBackoffDuration + kInitialBackoffDurationDelta; // SystemFallbackPolicy is a centralized OKP state manager which allows // multiple CDM engines to communicate between each other. In a production // build, there should only be at most one SystemFallbackPolicy instance. class SystemFallbackPolicy { public: WVCDM_DISALLOW_COPY_AND_MOVE(SystemFallbackPolicy); // Creates a new instance of SystemFallbackPolicy. If there exists // OKP information for the device in storage, it will be loaded and // the system policy will resume from its previous state. If no // OKP information exists, then the policy begins new. // Caller should immediately mark the fallback policy as requiring // provisioning. static std::unique_ptr Create(); // Creates a new instance of SystemFallbackPolicy for testing. // The testing instance of SystemFallbackPolicy behaves similar to a // production instance, except that it will not use device storage. // Optionally, a fake clock may be used for timestamp operations // and/or fake data may be used to initialize the policy. // Params: // - |info| (optional) // Fake device OKP info to use as a resume point. If not // specified, then policy begins the same as if no OKP // device info exists. // - |clock| (optional) // Fake/mock clock to be used instead of the CDM's default // Clock. static std::unique_ptr CreateForTesting( wvutil::Clock* clock = nullptr); static std::unique_ptr CreateForTesting( const SystemFallbackInfo& info, wvutil::Clock* clock = nullptr); // == System Info == const SystemFallbackInfo& info() const { return info_; } SystemState state() const { return info_.state(); } void MarkNeedsProvisioning(); void TriggerFallback(); void MarkProvisioned(); bool IsProvisioned(); bool IsInFallbackMode(); void SetDefaultBackoffDurationRules(); void SetFastBackoffDurationRules(); ~SystemFallbackPolicy(); private: SystemFallbackPolicy(); // Checks the device's file system for OKP info and loads it. // If the info does not exist, policy begins fresh. void TryRestore(); void StoreInfo(); int64_t GenerateInitialBackoffDuration(); int64_t GetSecondsSinceBackoffStart() const; void EndBackoffPeriod(); void SetClockForTesting(wvutil::Clock* clock) { clock_ref_ = (clock == nullptr) ? &clock_ : clock; } int64_t GetCurrentTime() const { return clock_ref_->GetCurrentTime(); } bool IsTestMode() const; SystemFallbackInfo info_; // When |fast_fallback_| is true, falling back only lasts a few // seconds, and exponential backoff is disabled. bool fast_fallback_ = false; // Handle for the DeviceFiles instance used to store the OKP // information. // Not set for test instances. std::unique_ptr fs_; std::unique_ptr device_files_; wvutil::Clock clock_; // System clock wvutil::Clock* clock_ref_ = nullptr; // Pointer to clock to be used. // All public methods must lock to protect from simultaneous // engine access. mutable std::mutex mutex_; }; // class SystemFallbackPolicy } // namespace okp } // namespace wvcdm #endif // WVCDM_CORE_OKP_FALLBACK_POLICY_H_