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

Commit 6980340b authored by Galia Peycheva's avatar Galia Peycheva Committed by Android (Google) Code Review
Browse files

Merge "Reset pip actions when pip disappears"

parents d3fba3e3 127a7400
Loading
Loading
Loading
Loading
+13 −0
Original line number Original line Diff line number Diff line
@@ -77,6 +77,19 @@ abstract class TvPipAction {
        return mActionType;
        return mActionType;
    }
    }


    static String getActionTypeString(@ActionType int actionType) {
        switch (actionType) {
            case ACTION_FULLSCREEN: return "ACTION_FULLSCREEN";
            case ACTION_CLOSE: return "ACTION_CLOSE";
            case ACTION_MOVE: return "ACTION_MOVE";
            case ACTION_EXPAND_COLLAPSE: return "ACTION_EXPAND_COLLAPSE";
            case ACTION_CUSTOM: return "ACTION_CUSTOM";
            case ACTION_CUSTOM_CLOSE: return "ACTION_CUSTOM_CLOSE";
            default:
                return "UNDEFINED";
        }
    }

    abstract void populateButton(@NonNull TvWindowMenuActionButton button, Handler mainHandler);
    abstract void populateButton(@NonNull TvWindowMenuActionButton button, Handler mainHandler);


    abstract PendingIntent getPendingIntent();
    abstract PendingIntent getPendingIntent();
+22 −11
Original line number Original line Diff line number Diff line
@@ -56,8 +56,10 @@ public class TvPipActionsProvider implements TvPipAction.SystemActionsHandler {
    private final List<Listener> mListeners = new ArrayList<>();
    private final List<Listener> mListeners = new ArrayList<>();
    private final TvPipAction.SystemActionsHandler mSystemActionsHandler;
    private final TvPipAction.SystemActionsHandler mSystemActionsHandler;


    private final List<TvPipAction> mActionsList;
    private final List<TvPipAction> mActionsList = new ArrayList<>();
    private final TvPipSystemAction mFullscreenAction;
    private final TvPipSystemAction mDefaultCloseAction;
    private final TvPipSystemAction mDefaultCloseAction;
    private final TvPipSystemAction mMoveAction;
    private final TvPipSystemAction mExpandCollapseAction;
    private final TvPipSystemAction mExpandCollapseAction;


    private final List<RemoteAction> mMediaActions = new ArrayList<>();
    private final List<RemoteAction> mMediaActions = new ArrayList<>();
@@ -67,26 +69,27 @@ public class TvPipActionsProvider implements TvPipAction.SystemActionsHandler {
            TvPipAction.SystemActionsHandler systemActionsHandler) {
            TvPipAction.SystemActionsHandler systemActionsHandler) {
        mSystemActionsHandler = systemActionsHandler;
        mSystemActionsHandler = systemActionsHandler;


        mActionsList = new ArrayList<>();
        mFullscreenAction = new TvPipSystemAction(ACTION_FULLSCREEN, R.string.pip_fullscreen,
        mActionsList.add(new TvPipSystemAction(ACTION_FULLSCREEN, R.string.pip_fullscreen,
                R.drawable.pip_ic_fullscreen_white, ACTION_TO_FULLSCREEN, context,
                R.drawable.pip_ic_fullscreen_white, ACTION_TO_FULLSCREEN, context,
                mSystemActionsHandler));
                mSystemActionsHandler);

        mDefaultCloseAction = new TvPipSystemAction(ACTION_CLOSE, R.string.pip_close,
        mDefaultCloseAction = new TvPipSystemAction(ACTION_CLOSE, R.string.pip_close,
                R.drawable.pip_ic_close_white, ACTION_CLOSE_PIP, context, mSystemActionsHandler);
                R.drawable.pip_ic_close_white, ACTION_CLOSE_PIP, context, mSystemActionsHandler);
        mActionsList.add(mDefaultCloseAction);
        mMoveAction = new TvPipSystemAction(ACTION_MOVE, R.string.pip_move,

                R.drawable.pip_ic_move_white, ACTION_MOVE_PIP, context, mSystemActionsHandler);
        mActionsList.add(new TvPipSystemAction(ACTION_MOVE, R.string.pip_move,
                R.drawable.pip_ic_move_white, ACTION_MOVE_PIP, context, mSystemActionsHandler));

        mExpandCollapseAction = new TvPipSystemAction(ACTION_EXPAND_COLLAPSE, R.string.pip_collapse,
        mExpandCollapseAction = new TvPipSystemAction(ACTION_EXPAND_COLLAPSE, R.string.pip_collapse,
                R.drawable.pip_ic_collapse, ACTION_TOGGLE_EXPANDED_PIP, context,
                R.drawable.pip_ic_collapse, ACTION_TOGGLE_EXPANDED_PIP, context,
                mSystemActionsHandler);
                mSystemActionsHandler);
        mActionsList.add(mExpandCollapseAction);
        initActions();


        pipMediaController.addActionListener(this::onMediaActionsChanged);
        pipMediaController.addActionListener(this::onMediaActionsChanged);
    }
    }


    private void initActions() {
        mActionsList.add(mFullscreenAction);
        mActionsList.add(mDefaultCloseAction);
        mActionsList.add(mMoveAction);
    }

    @Override
    @Override
    public void executeAction(@TvPipAction.ActionType int actionType) {
    public void executeAction(@TvPipAction.ActionType int actionType) {
        if (mSystemActionsHandler != null) {
        if (mSystemActionsHandler != null) {
@@ -199,6 +202,14 @@ public class TvPipActionsProvider implements TvPipAction.SystemActionsHandler {
        }
        }
    }
    }


    void reset() {
        mActionsList.clear();
        mMediaActions.clear();
        mAppActions.clear();

        initActions();
    }

    List<TvPipAction> getActionsList() {
    List<TvPipAction> getActionsList() {
        return mActionsList;
        return mActionsList;
    }
    }
+1 −0
Original line number Original line Diff line number Diff line
@@ -478,6 +478,7 @@ public class TvPipController implements PipTransitionController.PipTransitionCal
        mActionBroadcastReceiver.unregister();
        mActionBroadcastReceiver.unregister();


        mTvPipMenuController.closeMenu();
        mTvPipMenuController.closeMenu();
        mTvPipActionsProvider.reset();
        mTvPipBoundsState.resetTvPipState();
        mTvPipBoundsState.resetTvPipState();
        mTvPipBoundsController.reset();
        mTvPipBoundsController.reset();
        setState(STATE_NO_PIP);
        setState(STATE_NO_PIP);
+149 −100
Original line number Original line Diff line number Diff line
@@ -23,7 +23,9 @@ import static com.android.wm.shell.pip.tv.TvPipAction.ACTION_EXPAND_COLLAPSE;
import static com.android.wm.shell.pip.tv.TvPipAction.ACTION_FULLSCREEN;
import static com.android.wm.shell.pip.tv.TvPipAction.ACTION_FULLSCREEN;
import static com.android.wm.shell.pip.tv.TvPipAction.ACTION_MOVE;
import static com.android.wm.shell.pip.tv.TvPipAction.ACTION_MOVE;


import static org.junit.Assert.assertTrue;
import static java.util.Collections.EMPTY_LIST;

import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verify;
@@ -34,7 +36,6 @@ import android.graphics.drawable.Icon;
import android.test.suitebuilder.annotation.SmallTest;
import android.test.suitebuilder.annotation.SmallTest;
import android.testing.AndroidTestingRunner;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.testing.TestableLooper;
import android.util.Log;


import com.android.wm.shell.ShellTestCase;
import com.android.wm.shell.ShellTestCase;
import com.android.wm.shell.pip.PipMediaController;
import com.android.wm.shell.pip.PipMediaController;
@@ -46,7 +47,9 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.MockitoAnnotations;


import java.util.ArrayList;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.List;
import java.util.stream.Collectors;


/**
/**
 * Unit tests for {@link TvPipActionsProvider}
 * Unit tests for {@link TvPipActionsProvider}
@@ -69,35 +72,38 @@ public class TvPipActionProviderTest extends ShellTestCase {
    @Mock
    @Mock
    private PendingIntent mMockPendingIntent;
    private PendingIntent mMockPendingIntent;


    private RemoteAction createRemoteAction(int identifier) {
    private int mNumberOfRemoteActionsCreated = 0;

    private RemoteAction createRemoteAction() {
        final int identifier = mNumberOfRemoteActionsCreated++;
        return new RemoteAction(mMockIcon, "" + identifier, "" + identifier, mMockPendingIntent);
        return new RemoteAction(mMockIcon, "" + identifier, "" + identifier, mMockPendingIntent);
    }
    }


    private List<RemoteAction> createRemoteActions(int numberOfActions) {
    private List<RemoteAction> createRemoteActions(int numberOfActions) {
        List<RemoteAction> actions = new ArrayList<>();
        List<RemoteAction> actions = new ArrayList<>();
        for (int i = 0; i < numberOfActions; i++) {
        for (int i = 0; i < numberOfActions; i++) {
            actions.add(createRemoteAction(i));
            actions.add(createRemoteAction());
        }
        }
        return actions;
        return actions;
    }
    }


    private boolean checkActionsMatch(List<TvPipAction> actions, int[] actionTypes) {
    private void assertActionTypes(List<Integer> expected, List<Integer> actual) {
        for (int i = 0; i < actions.size(); i++) {
        assertEquals(getActionTypesStrings(expected), getActionTypesStrings(actual));
            int type = actions.get(i).getActionType();
            if (type != actionTypes[i]) {
                Log.e(TAG, "Action at index " + i + ": found " + type
                        + ", expected " + actionTypes[i]);
                return false;
    }
    }

    private static List<String> getActionTypesStrings(List<Integer> actionTypes) {
        return actionTypes.stream().map(a -> TvPipAction.getActionTypeString(a))
                .collect(Collectors.toList());
    }
    }
        return true;

    private List<Integer> getActionsTypes() {
        return mActionsProvider.getActionsList().stream().map(a -> a.getActionType())
                .collect(Collectors.toList());
    }
    }


    @Before
    @Before
    public void setUp() {
    public void setUp() {
        if (!isTelevision()) {
        assumeTelevision();
            return;
        }
        MockitoAnnotations.initMocks(this);
        MockitoAnnotations.initMocks(this);
        mActionsProvider = new TvPipActionsProvider(mContext, mMockPipMediaController,
        mActionsProvider = new TvPipActionsProvider(mContext, mMockPipMediaController,
                mMockSystemActionsHandler);
                mMockSystemActionsHandler);
@@ -105,57 +111,51 @@ public class TvPipActionProviderTest extends ShellTestCase {


    @Test
    @Test
    public void defaultSystemActions_regularPip() {
    public void defaultSystemActions_regularPip() {
        assumeTelevision();
        assertActionTypes(Arrays.asList(ACTION_FULLSCREEN, ACTION_CLOSE, ACTION_MOVE),
        mActionsProvider.updateExpansionEnabled(false);
                          getActionsTypes());
        assertTrue(checkActionsMatch(mActionsProvider.getActionsList(),
                new int[]{ACTION_FULLSCREEN, ACTION_CLOSE, ACTION_MOVE}));
    }
    }


    @Test
    @Test
    public void defaultSystemActions_expandedPip() {
    public void defaultSystemActions_expandedPip() {
        assumeTelevision();
        mActionsProvider.updateExpansionEnabled(true);
        mActionsProvider.updateExpansionEnabled(true);
        assertTrue(checkActionsMatch(mActionsProvider.getActionsList(),
        assertActionTypes(
                new int[]{ACTION_FULLSCREEN, ACTION_CLOSE, ACTION_MOVE, ACTION_EXPAND_COLLAPSE}));
                Arrays.asList(ACTION_FULLSCREEN, ACTION_CLOSE, ACTION_MOVE, ACTION_EXPAND_COLLAPSE),
                getActionsTypes());
    }
    }


    @Test
    @Test
    public void expandedPip_enableExpansion_enable() {
    public void expandedPip_enableExpansion_enable() {
        assumeTelevision();
        // PiP has expanded PiP disabled.
        // PiP has expanded PiP disabled.
        mActionsProvider.updateExpansionEnabled(false);

        mActionsProvider.addListener(mMockListener);
        mActionsProvider.addListener(mMockListener);
        mActionsProvider.updateExpansionEnabled(true);
        mActionsProvider.updateExpansionEnabled(true);


        assertTrue(checkActionsMatch(mActionsProvider.getActionsList(),
        assertActionTypes(
                new int[]{ACTION_FULLSCREEN, ACTION_CLOSE, ACTION_MOVE, ACTION_EXPAND_COLLAPSE}));
                Arrays.asList(ACTION_FULLSCREEN, ACTION_CLOSE, ACTION_MOVE, ACTION_EXPAND_COLLAPSE),
                getActionsTypes());
        verify(mMockListener).onActionsChanged(/* added= */ 1, /* updated= */ 0, /* index= */ 3);
        verify(mMockListener).onActionsChanged(/* added= */ 1, /* updated= */ 0, /* index= */ 3);
    }
    }


    @Test
    @Test
    public void expandedPip_enableExpansion_disable() {
    public void expandedPip_enableExpansion_disable() {
        assumeTelevision();
        mActionsProvider.updateExpansionEnabled(true);
        mActionsProvider.updateExpansionEnabled(true);


        mActionsProvider.addListener(mMockListener);
        mActionsProvider.addListener(mMockListener);
        mActionsProvider.updateExpansionEnabled(false);
        mActionsProvider.updateExpansionEnabled(false);


        assertTrue(checkActionsMatch(mActionsProvider.getActionsList(),
        assertActionTypes(
                new int[]{ACTION_FULLSCREEN, ACTION_CLOSE, ACTION_MOVE}));
                Arrays.asList(ACTION_FULLSCREEN, ACTION_CLOSE, ACTION_MOVE),
                getActionsTypes());
        verify(mMockListener).onActionsChanged(/* added= */ -1, /* updated= */ 0, /* index= */ 3);
        verify(mMockListener).onActionsChanged(/* added= */ -1, /* updated= */ 0, /* index= */ 3);
    }
    }


    @Test
    @Test
    public void expandedPip_enableExpansion_AlreadyEnabled() {
    public void expandedPip_enableExpansion_AlreadyEnabled() {
        assumeTelevision();
        mActionsProvider.updateExpansionEnabled(true);

        mActionsProvider.addListener(mMockListener);
        mActionsProvider.addListener(mMockListener);
        mActionsProvider.updateExpansionEnabled(true);
        mActionsProvider.updateExpansionEnabled(true);


        assertTrue(checkActionsMatch(mActionsProvider.getActionsList(),
        assertActionTypes(
                new int[]{ACTION_FULLSCREEN, ACTION_CLOSE, ACTION_MOVE, ACTION_EXPAND_COLLAPSE}));
                Arrays.asList(ACTION_FULLSCREEN, ACTION_CLOSE, ACTION_MOVE, ACTION_EXPAND_COLLAPSE),
                getActionsTypes());
    }
    }


    private void check_expandedPip_updateExpansionState(
    private void check_expandedPip_updateExpansionState(
@@ -167,8 +167,9 @@ public class TvPipActionProviderTest extends ShellTestCase {
        mActionsProvider.addListener(mMockListener);
        mActionsProvider.addListener(mMockListener);
        mActionsProvider.updatePipExpansionState(endExpansion);
        mActionsProvider.updatePipExpansionState(endExpansion);


        assertTrue(checkActionsMatch(mActionsProvider.getActionsList(),
        assertActionTypes(
                new int[]{ACTION_FULLSCREEN, ACTION_CLOSE, ACTION_MOVE, ACTION_EXPAND_COLLAPSE}));
                Arrays.asList(ACTION_FULLSCREEN, ACTION_CLOSE, ACTION_MOVE, ACTION_EXPAND_COLLAPSE),
                getActionsTypes());


        if (updateExpected) {
        if (updateExpected) {
            verify(mMockListener).onActionsChanged(0, 1, 3);
            verify(mMockListener).onActionsChanged(0, 1, 3);
@@ -180,7 +181,6 @@ public class TvPipActionProviderTest extends ShellTestCase {


    @Test
    @Test
    public void expandedPip_toggleExpansion_collapse() {
    public void expandedPip_toggleExpansion_collapse() {
        assumeTelevision();
        check_expandedPip_updateExpansionState(
        check_expandedPip_updateExpansionState(
                /* startExpansion= */ true,
                /* startExpansion= */ true,
                /* endExpansion= */ false,
                /* endExpansion= */ false,
@@ -189,7 +189,6 @@ public class TvPipActionProviderTest extends ShellTestCase {


    @Test
    @Test
    public void expandedPip_toggleExpansion_expand() {
    public void expandedPip_toggleExpansion_expand() {
        assumeTelevision();
        check_expandedPip_updateExpansionState(
        check_expandedPip_updateExpansionState(
                /* startExpansion= */ false,
                /* startExpansion= */ false,
                /* endExpansion= */ true,
                /* endExpansion= */ true,
@@ -198,7 +197,6 @@ public class TvPipActionProviderTest extends ShellTestCase {


    @Test
    @Test
    public void expandedPiP_updateExpansionState_alreadyExpanded() {
    public void expandedPiP_updateExpansionState_alreadyExpanded() {
        assumeTelevision();
        check_expandedPip_updateExpansionState(
        check_expandedPip_updateExpansionState(
                /* startExpansion= */ true,
                /* startExpansion= */ true,
                /* endExpansion= */ true,
                /* endExpansion= */ true,
@@ -207,7 +205,6 @@ public class TvPipActionProviderTest extends ShellTestCase {


    @Test
    @Test
    public void expandedPiP_updateExpansionState_alreadyCollapsed() {
    public void expandedPiP_updateExpansionState_alreadyCollapsed() {
        assumeTelevision();
        check_expandedPip_updateExpansionState(
        check_expandedPip_updateExpansionState(
                /* startExpansion= */ false,
                /* startExpansion= */ false,
                /* endExpansion= */ false,
                /* endExpansion= */ false,
@@ -216,8 +213,6 @@ public class TvPipActionProviderTest extends ShellTestCase {


    @Test
    @Test
    public void regularPiP_updateExpansionState_setCollapsed() {
    public void regularPiP_updateExpansionState_setCollapsed() {
        assumeTelevision();
        mActionsProvider.updateExpansionEnabled(false);
        mActionsProvider.updatePipExpansionState(/* expanded= */ false);
        mActionsProvider.updatePipExpansionState(/* expanded= */ false);


        mActionsProvider.addListener(mMockListener);
        mActionsProvider.addListener(mMockListener);
@@ -229,153 +224,207 @@ public class TvPipActionProviderTest extends ShellTestCase {


    @Test
    @Test
    public void customActions_added() {
    public void customActions_added() {
        assumeTelevision();
        mActionsProvider.updateExpansionEnabled(false);
        mActionsProvider.addListener(mMockListener);
        mActionsProvider.addListener(mMockListener);


        mActionsProvider.setAppActions(createRemoteActions(2), null);
        mActionsProvider.setAppActions(createRemoteActions(2), null);


        assertTrue(checkActionsMatch(mActionsProvider.getActionsList(),
        assertActionTypes(
                new int[]{ACTION_FULLSCREEN, ACTION_CLOSE, ACTION_CUSTOM, ACTION_CUSTOM,
                Arrays.asList(ACTION_FULLSCREEN, ACTION_CLOSE, ACTION_CUSTOM, ACTION_CUSTOM,
                        ACTION_MOVE}));
                    ACTION_MOVE),
                getActionsTypes());
        verify(mMockListener).onActionsChanged(/* added= */ 2, /* updated= */ 0, /* index= */ 2);
        verify(mMockListener).onActionsChanged(/* added= */ 2, /* updated= */ 0, /* index= */ 2);
    }
    }


    @Test
    @Test
    public void customActions_replacedMore() {
    public void customActions_replacedMore() {
        assumeTelevision();
        mActionsProvider.updateExpansionEnabled(false);
        mActionsProvider.setAppActions(createRemoteActions(2), null);
        mActionsProvider.setAppActions(createRemoteActions(2), null);


        mActionsProvider.addListener(mMockListener);
        mActionsProvider.addListener(mMockListener);
        mActionsProvider.setAppActions(createRemoteActions(3), null);
        mActionsProvider.setAppActions(createRemoteActions(3), null);


        assertTrue(checkActionsMatch(mActionsProvider.getActionsList(),
        assertActionTypes(
                new int[]{ACTION_FULLSCREEN, ACTION_CLOSE, ACTION_CUSTOM, ACTION_CUSTOM,
                Arrays.asList(ACTION_FULLSCREEN, ACTION_CLOSE, ACTION_CUSTOM, ACTION_CUSTOM,
                        ACTION_CUSTOM, ACTION_MOVE}));
                    ACTION_CUSTOM, ACTION_MOVE),
                getActionsTypes());
        verify(mMockListener).onActionsChanged(/* added= */ 1, /* updated= */ 2, /* index= */ 2);
        verify(mMockListener).onActionsChanged(/* added= */ 1, /* updated= */ 2, /* index= */ 2);
    }
    }


    @Test
    @Test
    public void customActions_replacedLess() {
    public void customActions_replacedLess() {
        assumeTelevision();
        mActionsProvider.updateExpansionEnabled(false);
        mActionsProvider.setAppActions(createRemoteActions(2), null);
        mActionsProvider.setAppActions(createRemoteActions(2), null);


        mActionsProvider.addListener(mMockListener);
        mActionsProvider.addListener(mMockListener);
        mActionsProvider.setAppActions(createRemoteActions(0), null);
        mActionsProvider.setAppActions(EMPTY_LIST, null);


        assertTrue(checkActionsMatch(mActionsProvider.getActionsList(),
        assertActionTypes(
                new int[]{ACTION_FULLSCREEN, ACTION_CLOSE, ACTION_MOVE}));
                Arrays.asList(ACTION_FULLSCREEN, ACTION_CLOSE, ACTION_MOVE),
                getActionsTypes());
        verify(mMockListener).onActionsChanged(/* added= */ -2, /* updated= */ 0, /* index= */ 2);
        verify(mMockListener).onActionsChanged(/* added= */ -2, /* updated= */ 0, /* index= */ 2);
    }
    }


    @Test
    @Test
    public void customCloseAdded() {
    public void customCloseAdded() {
        assumeTelevision();
        mActionsProvider.updateExpansionEnabled(false);

        List<RemoteAction> customActions = new ArrayList<>();
        List<RemoteAction> customActions = new ArrayList<>();
        mActionsProvider.setAppActions(customActions, null);
        mActionsProvider.setAppActions(customActions, null);


        mActionsProvider.addListener(mMockListener);
        mActionsProvider.addListener(mMockListener);
        mActionsProvider.setAppActions(customActions, createRemoteAction(0));
        mActionsProvider.setAppActions(customActions, createRemoteAction());


        assertTrue(checkActionsMatch(mActionsProvider.getActionsList(),
        assertActionTypes(
                new int[]{ACTION_FULLSCREEN, ACTION_CUSTOM_CLOSE, ACTION_MOVE}));
                Arrays.asList(ACTION_FULLSCREEN, ACTION_CUSTOM_CLOSE, ACTION_MOVE),
                getActionsTypes());
        verify(mMockListener).onActionsChanged(/* added= */ 0, /* updated= */ 1, /* index= */ 1);
        verify(mMockListener).onActionsChanged(/* added= */ 0, /* updated= */ 1, /* index= */ 1);
    }
    }


    @Test
    @Test
    public void customClose_matchesOtherCustomAction() {
    public void customClose_matchesOtherCustomAction() {
        assumeTelevision();
        mActionsProvider.updateExpansionEnabled(false);

        List<RemoteAction> customActions = createRemoteActions(2);
        List<RemoteAction> customActions = createRemoteActions(2);
        RemoteAction customClose = createRemoteAction(/* id= */ 10);
        RemoteAction customClose = createRemoteAction();
        customActions.add(customClose);
        customActions.add(customClose);


        mActionsProvider.addListener(mMockListener);
        mActionsProvider.addListener(mMockListener);
        mActionsProvider.setAppActions(customActions, customClose);
        mActionsProvider.setAppActions(customActions, customClose);


        assertTrue(checkActionsMatch(mActionsProvider.getActionsList(),
        assertActionTypes(
                new int[]{ACTION_FULLSCREEN, ACTION_CUSTOM_CLOSE, ACTION_CUSTOM, ACTION_CUSTOM,
                Arrays.asList(ACTION_FULLSCREEN, ACTION_CUSTOM_CLOSE, ACTION_CUSTOM, ACTION_CUSTOM,
                        ACTION_MOVE}));
                    ACTION_MOVE),
                getActionsTypes());
        verify(mMockListener).onActionsChanged(/* added= */ 0, /* updated= */ 1, /* index= */ 1);
        verify(mMockListener).onActionsChanged(/* added= */ 0, /* updated= */ 1, /* index= */ 1);
        verify(mMockListener).onActionsChanged(/* added= */ 2, /* updated= */ 0, /* index= */ 2);
        verify(mMockListener).onActionsChanged(/* added= */ 2, /* updated= */ 0, /* index= */ 2);
    }
    }


    @Test
    @Test
    public void mediaActions_added_whileCustomActionsExist() {
    public void mediaActions_added_whileCustomActionsExist() {
        assumeTelevision();
        mActionsProvider.updateExpansionEnabled(false);
        mActionsProvider.setAppActions(createRemoteActions(2), null);
        mActionsProvider.setAppActions(createRemoteActions(2), null);


        mActionsProvider.addListener(mMockListener);
        mActionsProvider.addListener(mMockListener);
        mActionsProvider.onMediaActionsChanged(createRemoteActions(3));
        mActionsProvider.onMediaActionsChanged(createRemoteActions(3));


        assertTrue(checkActionsMatch(mActionsProvider.getActionsList(),
        assertActionTypes(
                new int[]{ACTION_FULLSCREEN, ACTION_CLOSE, ACTION_CUSTOM, ACTION_CUSTOM,
                Arrays.asList(ACTION_FULLSCREEN, ACTION_CLOSE, ACTION_CUSTOM, ACTION_CUSTOM,
                        ACTION_MOVE}));
                    ACTION_MOVE),
                getActionsTypes());
        verify(mMockListener, times(0)).onActionsChanged(anyInt(), anyInt(), anyInt());
        verify(mMockListener, times(0)).onActionsChanged(anyInt(), anyInt(), anyInt());
    }
    }


    @Test
    @Test
    public void customActions_removed_whileMediaActionsExist() {
    public void customActions_removed_whileMediaActionsExist() {
        assumeTelevision();
        mActionsProvider.updateExpansionEnabled(false);
        mActionsProvider.onMediaActionsChanged(createRemoteActions(2));
        mActionsProvider.onMediaActionsChanged(createRemoteActions(2));
        mActionsProvider.setAppActions(createRemoteActions(3), null);
        mActionsProvider.setAppActions(createRemoteActions(3), null);


        assertActionTypes(
                Arrays.asList(ACTION_FULLSCREEN, ACTION_CLOSE, ACTION_CUSTOM, ACTION_CUSTOM,
                    ACTION_CUSTOM, ACTION_MOVE),
                getActionsTypes());

        mActionsProvider.addListener(mMockListener);
        mActionsProvider.addListener(mMockListener);
        mActionsProvider.setAppActions(createRemoteActions(0), null);
        mActionsProvider.setAppActions(EMPTY_LIST, null);


        assertTrue(checkActionsMatch(mActionsProvider.getActionsList(),
        assertActionTypes(
                new int[]{ACTION_FULLSCREEN, ACTION_CLOSE, ACTION_CUSTOM, ACTION_CUSTOM,
                Arrays.asList(ACTION_FULLSCREEN, ACTION_CLOSE, ACTION_CUSTOM, ACTION_CUSTOM,
                        ACTION_MOVE}));
                    ACTION_MOVE),
                getActionsTypes());
        verify(mMockListener).onActionsChanged(/* added= */ -1, /* updated= */ 2, /* index= */ 2);
        verify(mMockListener).onActionsChanged(/* added= */ -1, /* updated= */ 2, /* index= */ 2);
    }
    }


    @Test
    @Test
    public void customCloseOnly_mediaActionsShowing() {
    public void customCloseOnly_mediaActionsShowing() {
        assumeTelevision();
        mActionsProvider.updateExpansionEnabled(false);
        mActionsProvider.onMediaActionsChanged(createRemoteActions(2));
        mActionsProvider.onMediaActionsChanged(createRemoteActions(2));


        mActionsProvider.addListener(mMockListener);
        mActionsProvider.addListener(mMockListener);
        mActionsProvider.setAppActions(createRemoteActions(0), createRemoteAction(5));
        mActionsProvider.setAppActions(EMPTY_LIST, createRemoteAction());


        assertTrue(checkActionsMatch(mActionsProvider.getActionsList(),
        assertActionTypes(
                new int[]{ACTION_FULLSCREEN, ACTION_CUSTOM_CLOSE, ACTION_CUSTOM, ACTION_CUSTOM,
                Arrays.asList(ACTION_FULLSCREEN, ACTION_CUSTOM_CLOSE, ACTION_CUSTOM, ACTION_CUSTOM,
                        ACTION_MOVE}));
                    ACTION_MOVE),
                getActionsTypes());
        verify(mMockListener).onActionsChanged(/* added= */ 0, /* updated= */ 1, /* index= */ 1);
        verify(mMockListener).onActionsChanged(/* added= */ 0, /* updated= */ 1, /* index= */ 1);
    }
    }


    @Test
    @Test
    public void customActions_showDisabledActions() {
    public void customActions_showDisabledActions() {
        assumeTelevision();
        mActionsProvider.updateExpansionEnabled(false);

        List<RemoteAction> customActions = createRemoteActions(2);
        List<RemoteAction> customActions = createRemoteActions(2);
        customActions.get(0).setEnabled(false);
        customActions.get(0).setEnabled(false);
        mActionsProvider.setAppActions(customActions, null);
        mActionsProvider.setAppActions(customActions, null);


        assertTrue(checkActionsMatch(mActionsProvider.getActionsList(),
        assertActionTypes(
                new int[]{ACTION_FULLSCREEN, ACTION_CLOSE, ACTION_CUSTOM, ACTION_CUSTOM,
                Arrays.asList(ACTION_FULLSCREEN, ACTION_CLOSE, ACTION_CUSTOM, ACTION_CUSTOM,
                        ACTION_MOVE}));
                    ACTION_MOVE),
                getActionsTypes());
    }
    }


    @Test
    @Test
    public void mediaActions_hideDisabledActions() {
    public void mediaActions_hideDisabledActions() {
        assumeTelevision();
        List<RemoteAction> customActions = createRemoteActions(2);
        mActionsProvider.updateExpansionEnabled(false);
        customActions.get(0).setEnabled(false);
        mActionsProvider.onMediaActionsChanged(customActions);


        assertActionTypes(
                Arrays.asList(ACTION_FULLSCREEN, ACTION_CLOSE, ACTION_CUSTOM, ACTION_MOVE),
                getActionsTypes());
    }

    @Test
    public void reset_mediaActions() {
        List<RemoteAction> customActions = createRemoteActions(2);
        List<RemoteAction> customActions = createRemoteActions(2);
        customActions.get(0).setEnabled(false);
        customActions.get(0).setEnabled(false);
        mActionsProvider.onMediaActionsChanged(customActions);
        mActionsProvider.onMediaActionsChanged(customActions);


        assertTrue(checkActionsMatch(mActionsProvider.getActionsList(),
        assertActionTypes(
                new int[]{ACTION_FULLSCREEN, ACTION_CLOSE, ACTION_CUSTOM, ACTION_MOVE}));
                Arrays.asList(ACTION_FULLSCREEN, ACTION_CLOSE, ACTION_CUSTOM, ACTION_MOVE),
                getActionsTypes());

        mActionsProvider.reset();
        assertActionTypes(
                Arrays.asList(ACTION_FULLSCREEN, ACTION_CLOSE, ACTION_MOVE),
                getActionsTypes());
    }

    @Test
    public void reset_customActions() {
        List<RemoteAction> customActions = createRemoteActions(2);
        customActions.get(0).setEnabled(false);
        mActionsProvider.setAppActions(customActions, null);

        assertActionTypes(
                Arrays.asList(ACTION_FULLSCREEN, ACTION_CLOSE, ACTION_CUSTOM, ACTION_CUSTOM,
                    ACTION_MOVE),
                getActionsTypes());

        mActionsProvider.reset();
        assertActionTypes(
                Arrays.asList(ACTION_FULLSCREEN, ACTION_CLOSE, ACTION_MOVE),
                getActionsTypes());
    }

    @Test
    public void reset_customClose() {
        mActionsProvider.setAppActions(EMPTY_LIST, createRemoteAction());

        assertActionTypes(
                Arrays.asList(ACTION_FULLSCREEN, ACTION_CUSTOM_CLOSE, ACTION_MOVE),
                getActionsTypes());

        mActionsProvider.reset();
        assertActionTypes(
                Arrays.asList(ACTION_FULLSCREEN, ACTION_CLOSE, ACTION_MOVE),
                getActionsTypes());
    }

    @Test
    public void reset_All() {
        mActionsProvider.setAppActions(createRemoteActions(2), createRemoteAction());
        mActionsProvider.onMediaActionsChanged(createRemoteActions(3));

        assertActionTypes(
                Arrays.asList(ACTION_FULLSCREEN, ACTION_CUSTOM_CLOSE, ACTION_CUSTOM, ACTION_CUSTOM,
                    ACTION_MOVE),
                getActionsTypes());

        mActionsProvider.reset();
        assertActionTypes(
                Arrays.asList(ACTION_FULLSCREEN, ACTION_CLOSE, ACTION_MOVE),
                getActionsTypes());
    }
    }


}
}