4 <title>Test multiple MediaKeys lifetimes</title>
5 <script src="encrypted-media-utils.js"></script>
6 <script src="../../resources/testharness.js"></script>
7 <script src="../../resources/testharnessreport.js"></script>
12 // Since MediaKeys are not ActiveDOMObjects, it is hard to
13 // determine when they are garbage collected. For the test below
14 // a MediaKeySession (which is an ActiveDOMObject) is added to each
15 // MediaKeys object so there is something to count.
17 // MediaKeySessions remain as long as:
18 // JavaScript has a reference to it
19 // OR (MediaKeys is around
20 // AND the session has not received a close() event)
21 // In the tests below, we do not close any session nor keep a
22 // Javascript reference to any session, so MediaKeySessions remain
23 // as long as the associated MediaKeys object is around.
25 // For this test, create several MediaKeys (each with a
26 // MediaKeySession object so they can be counted) and verify
28 async_test(function(test)
31 var initDataType = getInitDataType();
32 var initData = getInitData(initDataType);
34 var startingActiveDOMObjectCount = window.internals.activeDOMObjectCount(document);
36 function numActiveDOMObjectsCreated()
38 return window.internals.activeDOMObjectCount(document) - startingActiveDOMObjectCount;
41 // Create a MediaKeys object and an associated MediaKeySession
42 // object. |mediaKeys| is updated to refer to the new MediaKeys
43 // object. Returns a promise that resolves with the new
44 // MediaKeySession object.
45 function createMediaKeyWithMediaKeySession()
47 return MediaKeys.create('org.w3.clearkey').then(function(result) {
49 var mediaKeySession = mediaKeys.createSession();
50 return mediaKeySession.generateRequest(initDataType, initData).then(function() {
51 return mediaKeySession;
56 // Create a few MediaKeys + MediaKeySession objects. Only keep
57 // a reference to the last one created.
58 createMediaKeyWithMediaKeySession().then(function(mediaKeySession) {
59 // Should be 1 MediaKeySession.
60 assert_equals(numActiveDOMObjectsCreated(), 1);
61 return createMediaKeyWithMediaKeySession();
62 }).then(function(mediaKeySession) {
63 // Should be 2 MediaKeySessions.
64 assert_equals(numActiveDOMObjectsCreated(), 2);
65 return createMediaKeyWithMediaKeySession();
66 }).then(function(mediaKeySession) {
67 // Should be 3 MediaKeySessions.
68 assert_equals(numActiveDOMObjectsCreated(), 3);
69 return createMediaKeyWithMediaKeySession();
70 }).then(function(mediaKeySession) {
71 // Should be 4 MediaKeySessions.
72 assert_equals(numActiveDOMObjectsCreated(), 4);
73 return createMediaKeyWithMediaKeySession();
74 }).then(function(mediaKeySession) {
75 // Should be 5 MediaKeySessions.
76 assert_equals(numActiveDOMObjectsCreated(), 5);
78 // |mediaKeys| refers to the most recently created MediaKeys
81 // In order for the MediaKeySession objects to have no
82 // outstanding activity so that they can be garbage
83 // collected, it needs time to process any pending events.
84 // As a "message" event is generated when a new session is
85 // created, we need to allow the event to run (we're not
86 // doing anything with the event in this test).
87 return delayToAllowEventProcessingPromise();
88 }).then(function(result) {
89 // Should be just 5 MediaKeySessions.
90 assert_equals(numActiveDOMObjectsCreated(), 5);
92 // As we only have a reference (|mediaKeys|) to the last
93 // created MediaKeys object, the other 4 MediaKeys objects
94 // are available to be garbage collected.
96 // Since MediaKeySessions remain alive as long as MediaKeys
97 // is around, it is possible that gc() checks the
98 // MediaKeySession object first, and doesn't collect it
99 // since MediaKeys hasn't been collected yet. Thus run gc()
100 // twice, to ensure that the unreferenced MediaKeySession
101 // objects get collected.
102 return createGCPromise();
103 }).then(function(result) {
104 return createGCPromise();
105 }).then(function(result) {
106 // Should be 1 MediaKeySession, the session for |mediaKeys|.
107 assert_equals(numActiveDOMObjectsCreated(), 1);
108 assert_equals(mediaKeys.keySystem, 'org.w3.clearkey');
110 // Release the last MediaKeys object created.
113 // Run gc() again to reclaim the remaining MediaKeys object
114 // and the last MediaKeySession. gc() run twice in case
115 // MediaKeySession checked first and not collected in the
117 return createGCPromise();
118 }).then(function(result) {
119 return createGCPromise();
120 }).then(function(result) {
121 assert_equals(numActiveDOMObjectsCreated(), 0);
123 }).catch(function(error) {
124 forceTestFailureFromPromise(test, error);
126 }, 'Multiple MediaKeys lifetime');