blob: 84c20cec6a843d5cc6db874e2be33e77c4c74740 [file] [log] [blame]
/*
* Copyright (C) 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef MediaKeySession_h
#define MediaKeySession_h
#include <memory>
#include "bindings/core/v8/ActiveScriptWrappable.h"
#include "bindings/core/v8/ScriptPromiseProperty.h"
#include "core/dom/ContextLifecycleObserver.h"
#include "core/typed_arrays/DOMArrayPiece.h"
#include "modules/EventTargetModules.h"
#include "modules/encryptedmedia/MediaKeyStatusMap.h"
#include "platform/Timer.h"
#include "platform/heap/Handle.h"
#include "public/platform/WebContentDecryptionModuleSession.h"
#include "public/platform/WebEncryptedMediaTypes.h"
namespace blink {
class DOMException;
class MediaElementEventQueue;
class MediaKeys;
// References are held by JS only. However, even if all JS references are
// dropped, it won't be garbage collected until close event received or
// MediaKeys goes away (as determined by a WeakMember reference). This allows
// the CDM to continue to fire events for this session, as long as the session
// is open.
//
// WeakMember<MediaKeys> is used instead of having MediaKeys and MediaKeySession
// keep references to each other, and then having to inform the other object
// when it gets destroyed. When the Oilpan garbage collector determines that
// only WeakMember<> references remain to the MediaKeys object, the MediaKeys
// object will be finalized and the WeakMember<> references will be cleared
// out(zeroed) by the garbage collector.
//
// Because this object controls the lifetime of the
// WebContentDecryptionModuleSession, it may outlive any JavaScript references
// as long as the MediaKeys object is alive.
// The WebContentDecryptionModuleSession has the same lifetime as this object.
class MediaKeySession final
: public EventTargetWithInlineData,
public ActiveScriptWrappable<MediaKeySession>,
public ContextLifecycleObserver,
private WebContentDecryptionModuleSession::Client {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(MediaKeySession);
USING_PRE_FINALIZER(MediaKeySession, Dispose);
public:
static MediaKeySession* Create(ScriptState*,
MediaKeys*,
WebEncryptedMediaSessionType);
~MediaKeySession() override;
String sessionId() const;
double expiration() const { return expiration_; }
ScriptPromise closed(ScriptState*);
MediaKeyStatusMap* keyStatuses();
DEFINE_ATTRIBUTE_EVENT_LISTENER(keystatuseschange);
DEFINE_ATTRIBUTE_EVENT_LISTENER(message);
ScriptPromise generateRequest(ScriptState*,
const String& init_data_type,
const DOMArrayPiece& init_data);
ScriptPromise load(ScriptState*, const String& session_id);
ScriptPromise update(ScriptState*, const DOMArrayPiece& response);
ScriptPromise close(ScriptState*);
ScriptPromise remove(ScriptState*);
// EventTarget
const AtomicString& InterfaceName() const override;
ExecutionContext* GetExecutionContext() const override;
// ScriptWrappable
bool HasPendingActivity() const final;
// ContextLifecycleObserver
void ContextDestroyed(ExecutionContext*) override;
void Trace(blink::Visitor*) override;
private:
class PendingAction;
friend class NewSessionResultPromise;
friend class LoadSessionResultPromise;
MediaKeySession(ScriptState*, MediaKeys*, WebEncryptedMediaSessionType);
void Dispose();
void ActionTimerFired(TimerBase*);
// The following perform the asynchronous part of the command referenced.
void GenerateRequestTask(ContentDecryptionModuleResult*,
WebEncryptedMediaInitDataType,
DOMArrayBuffer* init_data_buffer);
void FinishGenerateRequest();
void LoadTask(ContentDecryptionModuleResult*, const String& session_id);
void FinishLoad();
void UpdateTask(ContentDecryptionModuleResult*,
DOMArrayBuffer* sanitized_response);
void CloseTask(ContentDecryptionModuleResult*);
void RemoveTask(ContentDecryptionModuleResult*);
// WebContentDecryptionModuleSession::Client
void Message(MessageType,
const unsigned char* message,
size_t message_length) override;
void Close() override;
void ExpirationChanged(double updated_expiry_time_in_ms) override;
void KeysStatusesChange(const WebVector<WebEncryptedMediaKeyInformation>&,
bool has_additional_usable_key) override;
Member<MediaElementEventQueue> async_event_queue_;
std::unique_ptr<WebContentDecryptionModuleSession> session_;
// Used to determine if MediaKeys is still active.
WeakMember<MediaKeys> media_keys_;
// Session properties.
WebEncryptedMediaSessionType session_type_;
double expiration_;
Member<MediaKeyStatusMap> key_statuses_map_;
// Session states.
bool is_uninitialized_;
bool is_callable_;
bool is_closed_; // Is the CDM finished with this session?
// Keep track of the closed promise.
typedef ScriptPromiseProperty<Member<MediaKeySession>,
ToV8UndefinedGenerator,
Member<DOMException>>
ClosedPromise;
Member<ClosedPromise> closed_promise_;
HeapDeque<Member<PendingAction>> pending_actions_;
TaskRunnerTimer<MediaKeySession> action_timer_;
};
} // namespace blink
#endif // MediaKeySession_h