| OLD | NEW |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "media/mojo/services/mojo_audio_output_stream.h" | 5 #include "media/mojo/services/mojo_audio_output_stream.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/memory/shared_memory.h" | 9 #include "base/memory/shared_memory.h" |
| 10 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
| (...skipping 17 matching lines...) Expand all Loading... |
| 28 using testing::_; | 28 using testing::_; |
| 29 using testing::Mock; | 29 using testing::Mock; |
| 30 using testing::NotNull; | 30 using testing::NotNull; |
| 31 using testing::Return; | 31 using testing::Return; |
| 32 using testing::SaveArg; | 32 using testing::SaveArg; |
| 33 using testing::StrictMock; | 33 using testing::StrictMock; |
| 34 using testing::Test; | 34 using testing::Test; |
| 35 using AudioOutputStream = mojom::AudioOutputStream; | 35 using AudioOutputStream = mojom::AudioOutputStream; |
| 36 using AudioOutputStreamPtr = mojo::InterfacePtr<AudioOutputStream>; | 36 using AudioOutputStreamPtr = mojo::InterfacePtr<AudioOutputStream>; |
| 37 | 37 |
| 38 class TestCancelableSyncSocket : public base::CancelableSyncSocket { |
| 39 public: |
| 40 TestCancelableSyncSocket() {} |
| 41 |
| 42 void ExpectOwnershipTransfer() { expect_ownership_transfer_ = true; } |
| 43 |
| 44 ~TestCancelableSyncSocket() override { |
| 45 // When the handle is sent over mojo, mojo takes ownership over it and |
| 46 // closes it. We have to make sure we do not also retain the handle in the |
| 47 // sync socket, as the sync socket closes the handle on destruction. |
| 48 if (expect_ownership_transfer_) |
| 49 EXPECT_EQ(handle(), kInvalidHandle); |
| 50 } |
| 51 |
| 52 private: |
| 53 bool expect_ownership_transfer_ = false; |
| 54 |
| 55 DISALLOW_COPY_AND_ASSIGN(TestCancelableSyncSocket); |
| 56 }; |
| 57 |
| 38 class MockDelegate : NON_EXPORTED_BASE(public AudioOutputDelegate) { | 58 class MockDelegate : NON_EXPORTED_BASE(public AudioOutputDelegate) { |
| 39 public: | 59 public: |
| 40 MockDelegate() {} | 60 MockDelegate() {} |
| 41 ~MockDelegate() {} | 61 ~MockDelegate() {} |
| 42 | 62 |
| 43 MOCK_CONST_METHOD0(GetController, scoped_refptr<AudioOutputController>()); | 63 MOCK_CONST_METHOD0(GetController, scoped_refptr<AudioOutputController>()); |
| 44 MOCK_CONST_METHOD0(GetStreamId, int()); | 64 MOCK_CONST_METHOD0(GetStreamId, int()); |
| 45 MOCK_METHOD0(OnPlayStream, void()); | 65 MOCK_METHOD0(OnPlayStream, void()); |
| 46 MOCK_METHOD0(OnPauseStream, void()); | 66 MOCK_METHOD0(OnPauseStream, void()); |
| 47 MOCK_METHOD1(OnSetVolume, void(double)); | 67 MOCK_METHOD1(OnSetVolume, void(double)); |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 104 | 124 |
| 105 private: | 125 private: |
| 106 std::unique_ptr<base::SharedMemory> buffer_; | 126 std::unique_ptr<base::SharedMemory> buffer_; |
| 107 std::unique_ptr<base::CancelableSyncSocket> socket_; | 127 std::unique_ptr<base::CancelableSyncSocket> socket_; |
| 108 }; | 128 }; |
| 109 | 129 |
| 110 } // namespace | 130 } // namespace |
| 111 | 131 |
| 112 class MojoAudioOutputStreamTest : public Test { | 132 class MojoAudioOutputStreamTest : public Test { |
| 113 public: | 133 public: |
| 114 MojoAudioOutputStreamTest() {} | 134 MojoAudioOutputStreamTest() |
| 135 : foreign_socket_(base::MakeUnique<TestCancelableSyncSocket>()) {} |
| 115 | 136 |
| 116 AudioOutputStreamPtr CreateAudioOutput() { | 137 AudioOutputStreamPtr CreateAudioOutput() { |
| 117 AudioOutputStreamPtr p; | 138 AudioOutputStreamPtr p; |
| 118 ExpectDelegateCreation(); | 139 ExpectDelegateCreation(); |
| 119 impl_ = base::MakeUnique<MojoAudioOutputStream>( | 140 impl_ = base::MakeUnique<MojoAudioOutputStream>( |
| 120 mojo::MakeRequest(&p), | 141 mojo::MakeRequest(&p), |
| 121 base::BindOnce(&MockDelegateFactory::CreateDelegate, | 142 base::BindOnce(&MockDelegateFactory::CreateDelegate, |
| 122 base::Unretained(&mock_delegate_factory_)), | 143 base::Unretained(&mock_delegate_factory_)), |
| 123 base::Bind(&MockClient::Initialized, base::Unretained(&client_)), | 144 base::Bind(&MockClient::Initialized, base::Unretained(&client_)), |
| 124 base::BindOnce(&MockDeleter::Finished, base::Unretained(&deleter_))); | 145 base::BindOnce(&MockDeleter::Finished, base::Unretained(&deleter_))); |
| 125 EXPECT_NE(nullptr, p); | 146 EXPECT_NE(nullptr, p); |
| 126 return p; | 147 return p; |
| 127 } | 148 } |
| 128 | 149 |
| 129 protected: | 150 protected: |
| 130 void ExpectDelegateCreation() { | 151 void ExpectDelegateCreation() { |
| 131 delegate_ = new StrictMock<MockDelegate>(); | 152 delegate_ = new StrictMock<MockDelegate>(); |
| 132 mock_delegate_factory_.PrepareDelegateForCreation( | 153 mock_delegate_factory_.PrepareDelegateForCreation( |
| 133 base::WrapUnique(delegate_)); | 154 base::WrapUnique(delegate_)); |
| 134 EXPECT_TRUE( | 155 EXPECT_TRUE( |
| 135 base::CancelableSyncSocket::CreatePair(&local_, &foreign_socket_)); | 156 base::CancelableSyncSocket::CreatePair(&local_, foreign_socket_.get())); |
| 136 EXPECT_TRUE(mem_.CreateAnonymous(kShmemSize)); | 157 EXPECT_TRUE(mem_.CreateAnonymous(kShmemSize)); |
| 137 EXPECT_CALL(mock_delegate_factory_, MockCreateDelegate(NotNull())) | 158 EXPECT_CALL(mock_delegate_factory_, MockCreateDelegate(NotNull())) |
| 138 .WillOnce(SaveArg<0>(&delegate_event_handler_)); | 159 .WillOnce(SaveArg<0>(&delegate_event_handler_)); |
| 139 } | 160 } |
| 140 | 161 |
| 141 base::MessageLoop loop_; | 162 base::MessageLoop loop_; |
| 142 base::CancelableSyncSocket local_, foreign_socket_; | 163 base::CancelableSyncSocket local_; |
| 164 std::unique_ptr<TestCancelableSyncSocket> foreign_socket_; |
| 143 base::SharedMemory mem_; | 165 base::SharedMemory mem_; |
| 144 StrictMock<MockDelegate>* delegate_ = nullptr; | 166 StrictMock<MockDelegate>* delegate_ = nullptr; |
| 145 AudioOutputDelegate::EventHandler* delegate_event_handler_ = nullptr; | 167 AudioOutputDelegate::EventHandler* delegate_event_handler_ = nullptr; |
| 146 StrictMock<MockDelegateFactory> mock_delegate_factory_; | 168 StrictMock<MockDelegateFactory> mock_delegate_factory_; |
| 147 StrictMock<MockDeleter> deleter_; | 169 StrictMock<MockDeleter> deleter_; |
| 148 MockClient client_; | 170 MockClient client_; |
| 149 std::unique_ptr<MojoAudioOutputStream> impl_; | 171 std::unique_ptr<MojoAudioOutputStream> impl_; |
| 150 }; | 172 }; |
| 151 | 173 |
| 152 TEST_F(MojoAudioOutputStreamTest, Play_Plays) { | 174 TEST_F(MojoAudioOutputStreamTest, Play_Plays) { |
| (...skipping 18 matching lines...) Expand all Loading... |
| 171 | 193 |
| 172 audio_output_ptr->SetVolume(kNewVolume); | 194 audio_output_ptr->SetVolume(kNewVolume); |
| 173 base::RunLoop().RunUntilIdle(); | 195 base::RunLoop().RunUntilIdle(); |
| 174 } | 196 } |
| 175 | 197 |
| 176 TEST_F(MojoAudioOutputStreamTest, DestructWithCallPending_Safe) { | 198 TEST_F(MojoAudioOutputStreamTest, DestructWithCallPending_Safe) { |
| 177 AudioOutputStreamPtr audio_output_ptr = CreateAudioOutput(); | 199 AudioOutputStreamPtr audio_output_ptr = CreateAudioOutput(); |
| 178 base::RunLoop().RunUntilIdle(); | 200 base::RunLoop().RunUntilIdle(); |
| 179 | 201 |
| 180 ASSERT_NE(nullptr, delegate_event_handler_); | 202 ASSERT_NE(nullptr, delegate_event_handler_); |
| 181 delegate_event_handler_->OnStreamCreated(kStreamId, &mem_, &foreign_socket_); | 203 foreign_socket_->ExpectOwnershipTransfer(); |
| 204 delegate_event_handler_->OnStreamCreated(kStreamId, &mem_, |
| 205 std::move(foreign_socket_)); |
| 182 audio_output_ptr->Play(); | 206 audio_output_ptr->Play(); |
| 183 impl_.reset(); | 207 impl_.reset(); |
| 184 base::RunLoop().RunUntilIdle(); | 208 base::RunLoop().RunUntilIdle(); |
| 185 } | 209 } |
| 186 | 210 |
| 187 TEST_F(MojoAudioOutputStreamTest, Created_NotifiesClient) { | 211 TEST_F(MojoAudioOutputStreamTest, Created_NotifiesClient) { |
| 188 AudioOutputStreamPtr audio_output_ptr = CreateAudioOutput(); | 212 AudioOutputStreamPtr audio_output_ptr = CreateAudioOutput(); |
| 189 base::RunLoop().RunUntilIdle(); | 213 base::RunLoop().RunUntilIdle(); |
| 190 | 214 |
| 191 EXPECT_CALL(client_, GotNotification()); | 215 EXPECT_CALL(client_, GotNotification()); |
| 192 | 216 |
| 193 ASSERT_NE(nullptr, delegate_event_handler_); | 217 ASSERT_NE(nullptr, delegate_event_handler_); |
| 194 delegate_event_handler_->OnStreamCreated(kStreamId, &mem_, &foreign_socket_); | 218 foreign_socket_->ExpectOwnershipTransfer(); |
| 219 delegate_event_handler_->OnStreamCreated(kStreamId, &mem_, |
| 220 std::move(foreign_socket_)); |
| 195 | 221 |
| 196 base::RunLoop().RunUntilIdle(); | 222 base::RunLoop().RunUntilIdle(); |
| 197 } | 223 } |
| 198 | 224 |
| 199 TEST_F(MojoAudioOutputStreamTest, SetVolumeTooLarge_Error) { | 225 TEST_F(MojoAudioOutputStreamTest, SetVolumeTooLarge_Error) { |
| 200 AudioOutputStreamPtr audio_output_ptr = CreateAudioOutput(); | 226 AudioOutputStreamPtr audio_output_ptr = CreateAudioOutput(); |
| 201 EXPECT_CALL(deleter_, Finished()); | 227 EXPECT_CALL(deleter_, Finished()); |
| 202 | 228 |
| 203 audio_output_ptr->SetVolume(15); | 229 audio_output_ptr->SetVolume(15); |
| 204 base::RunLoop().RunUntilIdle(); | 230 base::RunLoop().RunUntilIdle(); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 224 base::RunLoop().RunUntilIdle(); | 250 base::RunLoop().RunUntilIdle(); |
| 225 Mock::VerifyAndClear(&deleter_); | 251 Mock::VerifyAndClear(&deleter_); |
| 226 } | 252 } |
| 227 | 253 |
| 228 TEST_F(MojoAudioOutputStreamTest, DelegateErrorAfterCreated_PropagatesError) { | 254 TEST_F(MojoAudioOutputStreamTest, DelegateErrorAfterCreated_PropagatesError) { |
| 229 AudioOutputStreamPtr audio_output_ptr = CreateAudioOutput(); | 255 AudioOutputStreamPtr audio_output_ptr = CreateAudioOutput(); |
| 230 EXPECT_CALL(deleter_, Finished()); | 256 EXPECT_CALL(deleter_, Finished()); |
| 231 base::RunLoop().RunUntilIdle(); | 257 base::RunLoop().RunUntilIdle(); |
| 232 | 258 |
| 233 ASSERT_NE(nullptr, delegate_event_handler_); | 259 ASSERT_NE(nullptr, delegate_event_handler_); |
| 234 delegate_event_handler_->OnStreamCreated(kStreamId, &mem_, &foreign_socket_); | 260 foreign_socket_->ExpectOwnershipTransfer(); |
| 261 delegate_event_handler_->OnStreamCreated(kStreamId, &mem_, |
| 262 std::move(foreign_socket_)); |
| 235 delegate_event_handler_->OnStreamError(kStreamId); | 263 delegate_event_handler_->OnStreamError(kStreamId); |
| 236 | 264 |
| 237 base::RunLoop().RunUntilIdle(); | 265 base::RunLoop().RunUntilIdle(); |
| 238 Mock::VerifyAndClear(&deleter_); | 266 Mock::VerifyAndClear(&deleter_); |
| 239 } | 267 } |
| 240 | 268 |
| 241 TEST_F(MojoAudioOutputStreamTest, RemoteEndGone_Error) { | 269 TEST_F(MojoAudioOutputStreamTest, RemoteEndGone_Error) { |
| 242 AudioOutputStreamPtr audio_output_ptr = CreateAudioOutput(); | 270 AudioOutputStreamPtr audio_output_ptr = CreateAudioOutput(); |
| 243 EXPECT_CALL(deleter_, Finished()); | 271 EXPECT_CALL(deleter_, Finished()); |
| 244 audio_output_ptr.reset(); | 272 audio_output_ptr.reset(); |
| 245 base::RunLoop().RunUntilIdle(); | 273 base::RunLoop().RunUntilIdle(); |
| 246 Mock::VerifyAndClear(&deleter_); | 274 Mock::VerifyAndClear(&deleter_); |
| 247 } | 275 } |
| 248 | 276 |
| 249 } // namespace media | 277 } // namespace media |
| OLD | NEW |