Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(808)

Side by Side Diff: webkit/media/crypto/proxy_decryptor_unittest.cc

Issue 10822026: Implement "Key Presence" step in "Encrypted Block Encounted" algorithm in EME. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "webkit/media/crypto/proxy_decryptor.h"
6
7 #include "base/basictypes.h"
8 #include "base/bind.h"
9 #include "base/memory/ref_counted.h"
10 #include "base/message_loop.h"
11 #include "media/base/decoder_buffer.h"
12 #include "media/base/decrypt_config.h"
13 #include "media/base/mock_filters.h"
14 #include "testing/gmock/include/gmock/gmock.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16
17 using ::testing::_;
18 using ::testing::AtLeast;
19 using ::testing::InvokeWithoutArgs;
20 using ::testing::IsNull;
21 using ::testing::NotNull;
22
23 using media::DecoderBuffer;
24 using media::DecryptConfig;
25 using media::Decryptor;
26
27 namespace webkit_media {
28
29 static const uint8 kFakeKeyId[] = { 0x4b, 0x65, 0x79, 0x20, 0x49, 0x44 };
30 static const uint8 kFakeIv[DecryptConfig::kDecryptionKeySize] = { 0 };
31 static const uint8 kFakeCheckSum[] = { 0, 0 };
32 static const char kFakeKeySystem[] = "system.key.fake";
33 static const char kFakeSessionId[] = "FakeSessionId";
34 static const uint8 kFakeKey[] = { 0x4b, 0x65, 0x79 };
35 static const uint8 kEncryptedData[] = { 0x65, 0x6E, 0x63, 0x72, 0x79 };
36 static const uint8 kDecryptedData[] = { 0x64, 0x65, 0x63, 0x72, 0x79 };
37
38 // Creates a fake non-empty encrypted buffer.
39 static scoped_refptr<DecoderBuffer> CreateFakeEncryptedBuffer() {
40 const int encrypted_frame_offset = 1; // This should be non-zero.
41 scoped_refptr<DecoderBuffer> encrypted_buffer =
42 DecoderBuffer::CopyFrom(kEncryptedData, arraysize(kEncryptedData));
43 encrypted_buffer->SetDecryptConfig(scoped_ptr<DecryptConfig>(
44 new DecryptConfig(
45 std::string(reinterpret_cast<const char*>(kFakeKeyId),
46 arraysize(kFakeKeyId)),
47 std::string(reinterpret_cast<const char*>(kFakeIv),
48 DecryptConfig::kDecryptionKeySize),
49 std::string(reinterpret_cast<const char*>(kFakeCheckSum),
50 arraysize(kFakeCheckSum)),
51 encrypted_frame_offset,
52 std::vector<media::SubsampleEntry>())));
53 return encrypted_buffer;
54 }
55
56 ACTION_P2(RunDecryptCB, status, buffer) {
57 arg1.Run(status, buffer);
58 }
59
60 // Tests the interaction between external Decryptor calls and concrete Decryptor
61 // implementations. This test is not interested in any specific Decryptor
62 // implementation. A MockDecryptor is used here to serve this purpose.
63 class ProxyDecryptorTest : public testing::Test {
64 public:
65 ProxyDecryptorTest()
66 : proxy_decryptor_(&client_, NULL, NULL),
67 real_decryptor_(new media::MockDecryptor()),
68 encrypted_buffer_(CreateFakeEncryptedBuffer()),
69 decrypted_buffer_(DecoderBuffer::CopyFrom(kDecryptedData,
70 arraysize(kDecryptedData))),
71 null_buffer_(scoped_refptr<DecoderBuffer>()),
72 decrypt_cb_(base::Bind(&ProxyDecryptorTest::BufferDecrypted,
73 base::Unretained(this))) {
74 }
75
76 // Instead of calling ProxyDecryptor::GenerateKeyRequest() here to create a
77 // real Decryptor, inject a MockDecryptor for testing purpose.
78 void GenerateKeyRequest() {
79 proxy_decryptor_.set_decryptor_for_testing(
80 scoped_ptr<Decryptor>(real_decryptor_));
81 }
82
83 // Since we are using the MockDecryptor, we can simulate any decryption
84 // behavior we want. Therefore, we do not care which key is really added,
85 // hence always use fake key IDs and keys.
86 void AddKey() {
87 EXPECT_CALL(*real_decryptor_, AddKey(kFakeKeySystem,
88 kFakeKeyId, arraysize(kFakeKeyId),
89 kFakeKey, arraysize(kFakeKey),
90 kFakeSessionId));
91 proxy_decryptor_.AddKey(kFakeKeySystem,
92 kFakeKeyId, arraysize(kFakeKeyId),
93 kFakeKey, arraysize(kFakeKey),
94 kFakeSessionId);
95 }
96
97 void ScheduleMessageLoopToStop() {
98 message_loop_.PostTask(FROM_HERE, MessageLoop::QuitClosure());
99 }
100
101 MOCK_METHOD2(BufferDecrypted, void(Decryptor::DecryptStatus,
102 const scoped_refptr<DecoderBuffer>&));
103
104 protected:
105 MessageLoop message_loop_;
106 media::MockDecryptorClient client_;
107 ProxyDecryptor proxy_decryptor_;
108 media::MockDecryptor* real_decryptor_;
109 scoped_refptr<DecoderBuffer> encrypted_buffer_;
110 scoped_refptr<DecoderBuffer> decrypted_buffer_;
111 scoped_refptr<DecoderBuffer> null_buffer_;
112 Decryptor::DecryptCB decrypt_cb_;
113
114 private:
115 DISALLOW_COPY_AND_ASSIGN(ProxyDecryptorTest);
116 };
117
118 // Tests a typical use case: GKR(), AddKey() and Decrypt() succeeds.
119 TEST_F(ProxyDecryptorTest, NormalDecryption_Success) {
120 GenerateKeyRequest();
121 AddKey();
122
123 EXPECT_CALL(*real_decryptor_, Decrypt(encrypted_buffer_, _))
124 .WillOnce(RunDecryptCB(Decryptor::kSuccess, decrypted_buffer_));
125 EXPECT_CALL(*this, BufferDecrypted(Decryptor::kSuccess, decrypted_buffer_));
126 proxy_decryptor_.Decrypt(encrypted_buffer_, decrypt_cb_);
127 }
128
129 // Tests the case where Decrypt() fails.
130 TEST_F(ProxyDecryptorTest, NormalDecryption_Error) {
131 GenerateKeyRequest();
132 AddKey();
133
134 EXPECT_CALL(*real_decryptor_, Decrypt(encrypted_buffer_, _))
135 .WillOnce(RunDecryptCB(Decryptor::kError, null_buffer_));
136 EXPECT_CALL(*this, BufferDecrypted(Decryptor::kError, IsNull()));
137 proxy_decryptor_.Decrypt(encrypted_buffer_, decrypt_cb_);
138 }
139
140 // Tests the case where no key is available for decryption.
141 TEST_F(ProxyDecryptorTest, NormalDecryption_NoKey) {
142 GenerateKeyRequest();
143
144 EXPECT_CALL(*real_decryptor_, Decrypt(encrypted_buffer_, _))
145 .WillOnce(RunDecryptCB(Decryptor::kNoKey, null_buffer_));
146 EXPECT_CALL(client_, NeedKeyMock("", "", NotNull(), arraysize(kFakeKeyId)));
147 proxy_decryptor_.Decrypt(encrypted_buffer_, decrypt_cb_);
148 }
149
150 // Tests the case where Decrypt() is called before GKR() is called and the right
151 // key is added.
152 TEST_F(ProxyDecryptorTest, DecryptBeforeGenerateKeyRequest) {
153 EXPECT_CALL(client_, NeedKeyMock("", "", NotNull(), arraysize(kFakeKeyId)));
154 proxy_decryptor_.Decrypt(encrypted_buffer_, decrypt_cb_);
155
156 EXPECT_CALL(*real_decryptor_, Decrypt(encrypted_buffer_, _))
157 .WillOnce(RunDecryptCB(Decryptor::kSuccess, decrypted_buffer_));
158 EXPECT_CALL(*this, BufferDecrypted(Decryptor::kSuccess, decrypted_buffer_))
159 .WillOnce(InvokeWithoutArgs(
scherkus (not reviewing) 2012/08/02 18:05:32 nit: instead of InvokeWithoutArgs you can have AC
xhwang 2012/08/03 20:08:10 Done.
160 this, &ProxyDecryptorTest::ScheduleMessageLoopToStop));
161 GenerateKeyRequest();
162 AddKey();
163 message_loop_.Run();
164 }
165
166 // Tests the case where multiple AddKey() is called to add some irrelevant keys
167 // before the real key that can decrypt |encrypted_buffer_| is added.
168 TEST_F(ProxyDecryptorTest, MultipleAddKeys) {
169 EXPECT_CALL(client_, NeedKeyMock("", "", NotNull(), arraysize(kFakeKeyId)))
170 .Times(AtLeast(1));
171 proxy_decryptor_.Decrypt(encrypted_buffer_, decrypt_cb_);
172
173 EXPECT_CALL(*real_decryptor_, Decrypt(encrypted_buffer_, _))
174 .WillRepeatedly(RunDecryptCB(Decryptor::kNoKey, null_buffer_));
175 GenerateKeyRequest();
176 const int number_of_irrelevant_addkey = 5;
177 for (int i = 0; i < number_of_irrelevant_addkey; ++i)
178 AddKey(); // Some irrelevant keys are added.
179
180 EXPECT_CALL(*real_decryptor_, Decrypt(encrypted_buffer_, _))
181 .WillOnce(RunDecryptCB(Decryptor::kSuccess, decrypted_buffer_));
182 EXPECT_CALL(*this, BufferDecrypted(Decryptor::kSuccess, decrypted_buffer_))
183 .WillOnce(InvokeWithoutArgs(
184 this, &ProxyDecryptorTest::ScheduleMessageLoopToStop));
185 AddKey(); // Correct key added.
186 message_loop_.Run();
187 }
188
189 // Tests the case where Decrypt() is called multiple times (e.g. from multiple
190 // stream) before the right key is added via AddKey().
191 TEST_F(ProxyDecryptorTest, MultiplePendingDecryptions) {
192 EXPECT_CALL(client_, NeedKeyMock("", "", NotNull(), arraysize(kFakeKeyId)))
193 .Times(AtLeast(1));
194 EXPECT_CALL(*real_decryptor_, Decrypt(encrypted_buffer_, _))
195 .WillRepeatedly(RunDecryptCB(Decryptor::kNoKey, null_buffer_));
196 proxy_decryptor_.Decrypt(encrypted_buffer_, decrypt_cb_);
197 GenerateKeyRequest();
198 proxy_decryptor_.Decrypt(encrypted_buffer_, decrypt_cb_);
199 AddKey(); // An irrelevant key is added.
200 proxy_decryptor_.Decrypt(encrypted_buffer_, decrypt_cb_);
201
202 EXPECT_CALL(*real_decryptor_, Decrypt(encrypted_buffer_, _))
203 .WillRepeatedly(RunDecryptCB(Decryptor::kSuccess, decrypted_buffer_));
204 EXPECT_CALL(*this, BufferDecrypted(Decryptor::kSuccess, decrypted_buffer_))
205 .Times(3);
206 AddKey(); // Correct key added.
207
208 ScheduleMessageLoopToStop();
209 message_loop_.Run();
210 }
211
212 TEST_F(ProxyDecryptorTest, StopWhenDecryptionsPending) {
213 EXPECT_CALL(client_, NeedKeyMock("", "", NotNull(), arraysize(kFakeKeyId)))
214 .Times(AtLeast(1));
215 EXPECT_CALL(*real_decryptor_, Decrypt(encrypted_buffer_, _))
216 .WillRepeatedly(RunDecryptCB(Decryptor::kNoKey, null_buffer_));
217 proxy_decryptor_.Decrypt(encrypted_buffer_, decrypt_cb_);
218 GenerateKeyRequest();
219 proxy_decryptor_.Decrypt(encrypted_buffer_, decrypt_cb_);
220 AddKey(); // An irrelevant key is added.
221 proxy_decryptor_.Decrypt(encrypted_buffer_, decrypt_cb_);
222
223 EXPECT_CALL(*real_decryptor_, Stop());
224 EXPECT_CALL(*this, BufferDecrypted(Decryptor::kError, null_buffer_))
225 .Times(3);
226 proxy_decryptor_.Stop();
227
228 ScheduleMessageLoopToStop();
229 message_loop_.Run();
230 }
231
232 } // namespace webkit_media
OLDNEW
« webkit/media/crypto/proxy_decryptor.cc ('K') | « webkit/media/crypto/proxy_decryptor.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698