1/*
2 * Copyright (C) 2013 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 *    notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 *    notice, this list of conditions and the following disclaimer in the
11 *    documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#ifndef MediaKeySession_h
27#define MediaKeySession_h
28
29#include "bindings/v8/ScriptWrappable.h"
30#include "core/dom/ActiveDOMObject.h"
31#include "modules/EventTargetModules.h"
32#include "platform/Timer.h"
33#include "platform/heap/Handle.h"
34#include "public/platform/WebContentDecryptionModuleSession.h"
35#include "wtf/Deque.h"
36#include "wtf/PassRefPtr.h"
37#include "wtf/RefCounted.h"
38#include "wtf/Uint8Array.h"
39#include "wtf/WeakPtr.h"
40#include "wtf/text/WTFString.h"
41
42namespace blink {
43class WebContentDecryptionModule;
44}
45
46namespace WebCore {
47
48class ExceptionState;
49class GenericEventQueue;
50class MediaKeyError;
51class MediaKeys;
52
53// References are held by JS only. However, even if all JS references are
54// dropped, it won't be garbage collected until close event received or
55// MediaKeys goes away (as determined by the validity of a WeakPtr). This allows
56// the CDM to continue to fire events for this session, as long as the session
57// is open.
58//
59// WeakPtr<MediaKeys> is used instead of having MediaKeys and MediaKeySession
60// keep references to each other, and then having to inform the other object
61// when it gets destroyed.
62//
63// Because this object controls the lifetime of the WebContentDecryptionModuleSession,
64// it may outlive any JavaScript references as long as the MediaKeys object is alive.
65// The WebContentDecryptionModuleSession has the same lifetime as this object.
66class MediaKeySession FINAL
67    : public RefCountedGarbageCollectedWillBeGarbageCollectedFinalized<MediaKeySession>, public ActiveDOMObject, public ScriptWrappable, public EventTargetWithInlineData
68    , private blink::WebContentDecryptionModuleSession::Client {
69    DEFINE_EVENT_TARGET_REFCOUNTING_WILL_BE_REMOVED(RefCountedGarbageCollected<MediaKeySession>);
70    WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(MediaKeySession);
71public:
72    static MediaKeySession* create(ExecutionContext*, blink::WebContentDecryptionModule*, MediaKeys*);
73    virtual ~MediaKeySession();
74
75    const String& keySystem() const { return m_keySystem; }
76    String sessionId() const;
77
78    void setError(MediaKeyError*);
79    MediaKeyError* error() { return m_error.get(); }
80
81    void initializeNewSession(const String& mimeType, const Uint8Array& initData);
82    void update(Uint8Array* response, ExceptionState&);
83    void release(ExceptionState&);
84
85    void enqueueEvent(PassRefPtrWillBeRawPtr<Event>);
86
87    // EventTarget
88    virtual const AtomicString& interfaceName() const OVERRIDE;
89    virtual ExecutionContext* executionContext() const OVERRIDE;
90
91    // ActiveDOMObject
92    virtual bool hasPendingActivity() const OVERRIDE;
93    virtual void stop() OVERRIDE;
94
95    virtual void trace(Visitor*) OVERRIDE;
96
97private:
98    // A struct holding the pending action.
99    struct PendingAction {
100        enum Type {
101            Update,
102            Release
103        };
104        const Type type;
105        const RefPtr<Uint8Array> data;
106
107        static PassOwnPtr<PendingAction> CreatePendingUpdate(PassRefPtr<Uint8Array> data);
108        static PassOwnPtr<PendingAction> CreatePendingRelease();
109        ~PendingAction();
110
111    private:
112        PendingAction(Type, PassRefPtr<Uint8Array> data);
113    };
114
115    MediaKeySession(ExecutionContext*, blink::WebContentDecryptionModule*, MediaKeys*);
116    void actionTimerFired(Timer<MediaKeySession>*);
117
118    // blink::WebContentDecryptionModuleSession::Client
119    virtual void message(const unsigned char* message, size_t messageLength, const blink::WebURL& destinationURL) OVERRIDE;
120    virtual void ready() OVERRIDE;
121    virtual void close() OVERRIDE;
122    virtual void error(MediaKeyErrorCode, unsigned long systemCode) OVERRIDE;
123    virtual void error(blink::WebContentDecryptionModuleException, unsigned long systemCode, const blink::WebString& errorMessage) OVERRIDE;
124
125    String m_keySystem;
126    RefPtr<MediaKeyError> m_error;
127    OwnPtrWillBeMember<GenericEventQueue> m_asyncEventQueue;
128    OwnPtr<blink::WebContentDecryptionModuleSession> m_session;
129
130    // Used to determine if MediaKeys is still active.
131    WeakMember<MediaKeys> m_keys;
132
133    // Is the CDM finished with this session?
134    bool m_isClosed;
135
136    Deque<OwnPtr<PendingAction> > m_pendingActions;
137    Timer<MediaKeySession> m_actionTimer;
138};
139
140}
141
142#endif // MediaKeySession_h
143