Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f51b194b authored by Sal Savage's avatar Sal Savage
Browse files

Address testAddressedPlayerChangedToSamePlayerId flake rate

The testAddressedPlayerChangedToSamePlayerId test had a high flake rate
due to the testing logic allowing it to potentially stay in the
GetFolderListing state longer than it should. Repeat attempts to get the
now playing list had the small chance to be grouped with previous ones
from test setup if timing was unlucky.

Tag: #stability
Bug: 192663607
Test: atest
com.android.bluetooth.avrcpcontroller.AvrcpControllerStateMachineTest#testAddressedPlayerChangedToSamePlayerId
--rerun-until-faliure 500

Change-Id: I51db5e7546519080fba89e7cab729b80c65d849d
parent 12c022f2
Loading
Loading
Loading
Loading
+36 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import android.bluetooth.BluetoothDevice;
import android.content.Intent;
import android.os.Handler;
import android.os.Looper;
import android.os.MessageQueue;

import androidx.test.InstrumentationRegistry;
import androidx.test.rule.ServiceTestRule;
@@ -245,6 +246,41 @@ public class TestUtils {
        });
    }

    /**
     * Wait for looper to become idle
     *
     * @param looper looper of interest
     */
    public static void waitForLooperToBeIdle(Looper looper) {
        class Idler implements MessageQueue.IdleHandler {
            private boolean mIdle = false;

            @Override
            public boolean queueIdle() {
                synchronized (this) {
                    mIdle = true;
                    notifyAll();
                }
                return false;
            }

            public synchronized void waitForIdle() {
                while (!mIdle) {
                    try {
                        wait();
                    } catch (InterruptedException e) {
                    }
                }
            }
        }

        Idler idle = new Idler();
        looper.getQueue().addIdleHandler(idle);
        // Ensure we are not Idle to begin with so the idle handler will run
        waitForLooperToFinishScheduledTask(looper);
        idle.waitForIdle();
    }

    /**
     * Run synchronously a runnable action on a looper.
     * The method will return after the action has been execution to completion.
+10 −2
Original line number Diff line number Diff line
@@ -974,6 +974,11 @@ public class AvrcpControllerStateMachineTest {
        // Set the addressed player so we can change to the same one
        mAvrcpStateMachine.sendMessage(
                AvrcpControllerStateMachine.MESSAGE_PROCESS_ADDRESSED_PLAYER_CHANGED, 1);

        // Wait until idle so Now Playing List is queried for, resolve it
        TestUtils.waitForLooperToBeIdle(mAvrcpStateMachine.getHandler().getLooper());
        mAvrcpStateMachine.sendMessage(
                AvrcpControllerStateMachine.MESSAGE_PROCESS_GET_FOLDER_ITEMS_OUT_OF_RANGE);
        TestUtils.waitForLooperToFinishScheduledTask(mAvrcpStateMachine.getHandler().getLooper());

        //Get the root of the device
@@ -995,14 +1000,17 @@ public class AvrcpControllerStateMachineTest {
        mAvrcpStateMachine.sendMessage(AvrcpControllerStateMachine.MESSAGE_PROCESS_GET_PLAYER_ITEMS,
                testPlayers);

        // Wait for players to be processed
        // Wait until idle so Now Playing List is queried for again, resolve it again
        TestUtils.waitForLooperToBeIdle(mAvrcpStateMachine.getHandler().getLooper());
        mAvrcpStateMachine.sendMessage(
                AvrcpControllerStateMachine.MESSAGE_PROCESS_GET_FOLDER_ITEMS_OUT_OF_RANGE);
        TestUtils.waitForLooperToFinishScheduledTask(mAvrcpStateMachine.getHandler().getLooper());
        clearInvocations(mAvrcpControllerService);

        // Send an addressed player changed to the same player ID
        mAvrcpStateMachine.sendMessage(
                AvrcpControllerStateMachine.MESSAGE_PROCESS_ADDRESSED_PLAYER_CHANGED, 1);
        TestUtils.waitForLooperToFinishScheduledTask(mAvrcpStateMachine.getHandler().getLooper());
        TestUtils.waitForLooperToBeIdle(mAvrcpStateMachine.getHandler().getLooper());

        // Verify we make no assumptions about the player ID and still fetch metadata, play status
        // and now playing list (since player 1 supports it)