// Tests callback invocation. TEST(UserGestureIndicatorTest, Callback) { UsedCallback cb; { UserGestureIndicator userGestureScope(UserGestureToken::create()); UserGestureIndicator::currentToken()->setUserGestureUtilizedCallback(&cb); EXPECT_EQ(0u, cb.getAndResetUsedCount()); // Untracked doesn't invoke the callback EXPECT_TRUE(UserGestureIndicator::processingUserGesture()); EXPECT_EQ(0u, cb.getAndResetUsedCount()); // But processingUserGesture does EXPECT_TRUE(UserGestureIndicator::utilizeUserGesture()); EXPECT_EQ(1u, cb.getAndResetUsedCount()); // But only the first time EXPECT_TRUE(UserGestureIndicator::utilizeUserGesture()); EXPECT_TRUE(UserGestureIndicator::consumeUserGesture()); EXPECT_EQ(0u, cb.getAndResetUsedCount()); } EXPECT_EQ(0u, cb.getAndResetUsedCount()); { UserGestureIndicator userGestureScope(UserGestureToken::create()); UserGestureIndicator::currentToken()->setUserGestureUtilizedCallback(&cb); // Consume also invokes the callback EXPECT_TRUE(UserGestureIndicator::consumeUserGesture()); EXPECT_EQ(1u, cb.getAndResetUsedCount()); // But only once EXPECT_FALSE(UserGestureIndicator::utilizeUserGesture()); EXPECT_FALSE(UserGestureIndicator::consumeUserGesture()); EXPECT_EQ(0u, cb.getAndResetUsedCount()); } { std::unique_ptr<UserGestureIndicator> userGestureScope( new UserGestureIndicator(UserGestureToken::create())); RefPtr<UserGestureToken> token = UserGestureIndicator::currentToken(); token->setUserGestureUtilizedCallback(&cb); userGestureScope.reset(); // The callback should be cleared when the UseGestureIndicator is deleted. EXPECT_FALSE(UserGestureIndicator::utilizeUserGesture()); EXPECT_EQ(0u, cb.getAndResetUsedCount()); } // The callback isn't invoked outside the scope of the UGI EXPECT_FALSE(UserGestureIndicator::utilizeUserGesture()); EXPECT_EQ(0u, cb.getAndResetUsedCount()); EXPECT_FALSE(UserGestureIndicator::consumeUserGesture()); EXPECT_EQ(0u, cb.getAndResetUsedCount()); }
// Tests creation of scoped UserGestureIndicator objects. TEST(UserGestureIndicatorTest, ScopedNewUserGestureIndicators) { // Root GestureIndicator and GestureToken. UserGestureIndicator userGestureScope( UserGestureToken::create(UserGestureToken::NewGesture)); EXPECT_TRUE(UserGestureIndicator::utilizeUserGesture()); EXPECT_TRUE(UserGestureIndicator::processedUserGestureSinceLoad()); EXPECT_NE(nullptr, UserGestureIndicator::currentToken()); { // Construct inner UserGestureIndicator. // It should share GestureToken with the root indicator. UserGestureIndicator innerUserGesture( UserGestureToken::create(UserGestureToken::NewGesture)); EXPECT_TRUE(UserGestureIndicator::utilizeUserGesture()); EXPECT_NE(nullptr, UserGestureIndicator::currentToken()); // Consume inner gesture. EXPECT_TRUE(UserGestureIndicator::consumeUserGesture()); } EXPECT_TRUE(UserGestureIndicator::utilizeUserGesture()); EXPECT_NE(nullptr, UserGestureIndicator::currentToken()); // Consume root gesture. EXPECT_TRUE(UserGestureIndicator::consumeUserGesture()); EXPECT_FALSE(UserGestureIndicator::utilizeUserGesture()); EXPECT_NE(nullptr, UserGestureIndicator::currentToken()); }
TEST(UserGestureIndicatorTest, ConstructedWithNoUserGesture) { UserGestureIndicator::clearProcessedUserGestureSinceLoad(); UserGestureIndicator userGestureScope(nullptr); EXPECT_FALSE(UserGestureIndicator::utilizeUserGesture()); EXPECT_FALSE(UserGestureIndicator::processedUserGestureSinceLoad()); EXPECT_EQ(nullptr, UserGestureIndicator::currentToken()); EXPECT_FALSE(UserGestureIndicator::consumeUserGesture()); }
TEST(UserGestureIndicatorTest, ConstructedWithUserGesture) { UserGestureIndicator::clearProcessedUserGestureSinceLoad(); UserGestureIndicator userGestureScope(UserGestureToken::create()); EXPECT_TRUE(UserGestureIndicator::utilizeUserGesture()); EXPECT_TRUE(UserGestureIndicator::processedUserGestureSinceLoad()); EXPECT_NE(nullptr, UserGestureIndicator::currentToken()); EXPECT_TRUE(UserGestureIndicator::consumeUserGesture()); }
// Check that after UserGestureIndicator destruction state will be cleared. TEST(UserGestureIndicatorTest, DestructUserGestureIndicator) { { UserGestureIndicator userGestureScope(UserGestureToken::create()); EXPECT_TRUE(UserGestureIndicator::utilizeUserGesture()); EXPECT_TRUE(UserGestureIndicator::processedUserGestureSinceLoad()); EXPECT_NE(nullptr, UserGestureIndicator::currentToken()); } EXPECT_FALSE(UserGestureIndicator::utilizeUserGesture()); EXPECT_EQ(nullptr, UserGestureIndicator::currentToken()); EXPECT_FALSE(UserGestureIndicator::consumeUserGesture()); }
TEST_F(BaseAudioContextTest, AutoplayMetrics_CreateGesture) { HistogramTester histogramTester; createChildFrame(); childDocument().settings()->setMediaPlaybackRequiresUserGesture(true); UserGestureIndicator userGestureScope(DocumentUserGestureToken::create( &childDocument(), UserGestureToken::NewGesture)); BaseAudioContext* audioContext = BaseAudioContext::create(childDocument(), ASSERT_NO_EXCEPTION); recordAutoplayStatus(audioContext); histogramTester.expectBucketCount(kCrossOriginMetric, AutoplayStatus::AutoplayStatusSucceeded, 1); histogramTester.expectTotalCount(kCrossOriginMetric, 1); }
TEST_F(BaseAudioContextTest, AutoplayMetrics_NodeStartGesture) { HistogramTester histogramTester; createChildFrame(); childDocument().settings()->setMediaPlaybackRequiresUserGesture(true); BaseAudioContext* audioContext = BaseAudioContext::create(childDocument(), ASSERT_NO_EXCEPTION); UserGestureIndicator userGestureScope( UserGestureToken::create(UserGestureToken::NewGesture)); audioContext->maybeRecordStartAttempt(); recordAutoplayStatus(audioContext); histogramTester.expectBucketCount( kCrossOriginMetric, AutoplayStatus::AutoplayStatusFailedWithStart, 1); histogramTester.expectTotalCount(kCrossOriginMetric, 1); }
TEST_F(BaseAudioContextTest, AutoplayMetrics_NodeStartGestureThenSucces) { HistogramTester histogramTester; createChildFrame(); childDocument().settings()->setMediaPlaybackRequiresUserGesture(true); ScriptState::Scope scope(getScriptStateFrom(childDocument())); BaseAudioContext* audioContext = BaseAudioContext::create(childDocument(), ASSERT_NO_EXCEPTION); UserGestureIndicator userGestureScope(DocumentUserGestureToken::create( &childDocument(), UserGestureToken::NewGesture)); audioContext->maybeRecordStartAttempt(); audioContext->resumeContext(getScriptStateFrom(childDocument())); rejectPendingResolvers(audioContext); recordAutoplayStatus(audioContext); histogramTester.expectBucketCount(kCrossOriginMetric, AutoplayStatus::AutoplayStatusSucceeded, 1); histogramTester.expectTotalCount(kCrossOriginMetric, 1); }