• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (C) 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.media.cujcommon.cts;
18 
19 import android.os.Looper;
20 import android.util.Log;
21 
22 import androidx.annotation.NonNull;
23 import androidx.media3.common.Player;
24 
25 import java.time.Clock;
26 import java.time.Duration;
27 import java.util.Random;
28 
29 public class SeekTestPlayerListener extends PlayerListener {
30 
31   private static final String LOG_TAG = SeekTestPlayerListener.class.getSimpleName();
32 
33   private final int mNumOfSeekIterationsPerClip;
34   private Duration mSeekDuration;
35   private final long mSeed;
36 
SeekTestPlayerListener(int numOfSeekIterationsPerClip, Duration seekDuration, Duration sendMessagePosition)37   public SeekTestPlayerListener(int numOfSeekIterationsPerClip, Duration seekDuration,
38       Duration sendMessagePosition) {
39     super();
40     this.mNumOfSeekIterationsPerClip = numOfSeekIterationsPerClip;
41     this.mSeekDuration = seekDuration;
42     this.mSeed = getSeed();
43     this.mSendMessagePosition = sendMessagePosition;
44   }
45 
46   /**
47    * Returns seed for Seek test.
48    */
getSeed()49   private long getSeed() {
50     // Truncate time to the nearest day.
51     long seed = Clock.tick(Clock.systemUTC(), Duration.ofDays(1)).instant().toEpochMilli();
52     Log.d(LOG_TAG, "Random seed = " + seed);
53     return seed;
54   }
55 
56   /**
57    * Seek the player.
58    */
seek()59   private void seek() {
60     Random random = new Random(mSeed);
61     // In case of small test, number of seek requested (i.e. mNumOfSeekIterationsPerClip) is one
62     // per clip. We seek forward and backward alternatively for mSeekDuration for all the clips in
63     // the given media list.
64     // In case of large test, number of seek requested (i.e. mNumOfSeekIterationsPerClip) is 30 per
65     // clip. We seek forward 10 times, backward 10 times or vice-versa (i.e. backward 10 times and
66     // forward 10 times) and then randomly backwards or forwards 10 times for mSeekDuration for all
67     // the clips in the given media l̥ist.
68     for (int i = 0; i < mNumOfSeekIterationsPerClip; i++) {
69       mActivity.mPlayer.seekTo(mActivity.mPlayer.getCurrentPosition() + mSeekDuration.toMillis());
70       // Update expected total time due to seek
71       mExpectedTotalTime -= mSeekDuration.toMillis();
72       mTotalSeekOverhead = mTotalSeekOverhead.plus(CujTestBase.OVERHEAD_PER_SEEK);
73       if (mNumOfSeekIterationsPerClip == 1 || i == 9) {
74         mSeekDuration = mSeekDuration.multipliedBy(-1);
75       } else if (i >= 19) {
76         mSeekDuration =
77             random.nextBoolean() ? mSeekDuration.multipliedBy(-1) : mSeekDuration.multipliedBy(1);
78       }
79     }
80   }
81 
82   @Override
getTestType()83   public TestType getTestType() {
84     return TestType.SEEK_TEST;
85   }
86 
87   @Override
onEventsPlaybackStateChanged(@onNull Player player)88   public void onEventsPlaybackStateChanged(@NonNull Player player) {
89     if (mExpectedTotalTime == 0 && player.getPlaybackState() == Player.STATE_READY) {
90       // At the first media transition player is not ready. So, add duration of
91       // first clip when player is ready
92       mExpectedTotalTime += player.getDuration();
93     }
94   }
95 
96   @Override
onEventsMediaItemTransition(@onNull Player player)97   public void onEventsMediaItemTransition(@NonNull Player player) {
98     mActivity.mPlayer.createMessage((messageType, payload) -> {
99           seek();
100         }).setLooper(Looper.getMainLooper()).setPosition(mSendMessagePosition.toMillis())
101         .setDeleteAfterDelivery(true)
102         .send();
103   }
104 }
105