15253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee/*
25253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee * Copyright (C) 2014 The Android Open Source Project
35253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee *
45253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee * Licensed under the Apache License, Version 2.0 (the "License");
55253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee * you may not use this file except in compliance with the License.
65253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee * You may obtain a copy of the License at
75253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee *
85253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee *      http://www.apache.org/licenses/LICENSE-2.0
95253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee *
105253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee * Unless required by applicable law or agreed to in writing, software
115253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee * distributed under the License is distributed on an "AS IS" BASIS,
125253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee * See the License for the specific language governing permissions and
145253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee * limitations under the License.
155253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee */
165253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee
175253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Leepackage com.android.dialer.widget;
185253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee
195253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Leeimport android.content.Context;
205253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Leeimport android.test.InstrumentationTestCase;
215253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Leeimport android.test.suitebuilder.annotation.SmallTest;
225253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee
235253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Leeimport com.android.dialer.widget.ActionBarController.ActivityUi;
245253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee
255253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee@SmallTest
26c98a5bb2d806dde99325a15466a2bf144d216ae8Yorke Leepublic class ActionBarControllerTest extends InstrumentationTestCase {
275253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee
285253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee    private static final int ACTION_BAR_HEIGHT = 100;
295253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee    private ActionBarController mActionBarController;
305253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee    private SearchEditTextLayout mSearchBox;
315253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee    private MockActivityUi mActivityUi;
325253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee
335253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee    private class MockActivityUi implements ActivityUi {
345253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        boolean isInSearchUi;
355253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        boolean hasSearchQuery;
365253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        boolean shouldShowActionBar;
37c98a5bb2d806dde99325a15466a2bf144d216ae8Yorke Lee        int actionBarHideOffset;
385253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee
395253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        @Override
405253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        public boolean isInSearchUi() {
415253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee            return isInSearchUi;
425253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        }
435253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee
445253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        @Override
455253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        public boolean hasSearchQuery() {
465253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee            return hasSearchQuery;
475253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        }
485253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee
495253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        @Override
505253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        public boolean shouldShowActionBar() {
515253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee            return shouldShowActionBar;
525253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        }
535253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee
545253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        @Override
555253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        public int getActionBarHeight() {
565253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee            return ACTION_BAR_HEIGHT;
575253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        }
585253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee
595253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        @Override
60c98a5bb2d806dde99325a15466a2bf144d216ae8Yorke Lee        public int getActionBarHideOffset() {
61c98a5bb2d806dde99325a15466a2bf144d216ae8Yorke Lee            return actionBarHideOffset;
62c98a5bb2d806dde99325a15466a2bf144d216ae8Yorke Lee        }
63c98a5bb2d806dde99325a15466a2bf144d216ae8Yorke Lee
64c98a5bb2d806dde99325a15466a2bf144d216ae8Yorke Lee        @Override
65c98a5bb2d806dde99325a15466a2bf144d216ae8Yorke Lee        public void setActionBarHideOffset(int offset) {
66c98a5bb2d806dde99325a15466a2bf144d216ae8Yorke Lee            actionBarHideOffset = offset;
675253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        }
685253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee    }
695253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee
705253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee    /**
715253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee     * Mock version of the searchbox, that updates its state immediately instead of animating
725253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee     */
735253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee    private class MockSearchBox extends SearchEditTextLayout {
745253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee
755253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        public MockSearchBox(Context context) {
765253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee            super(context, null);
775253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        }
785253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee
795253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        @Override
805253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        public void expand(boolean animate, boolean requestFocus) {
815253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee            mIsExpanded = true;
825253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        }
835253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee
845253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        @Override
855253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        public void collapse(boolean animate) {
865253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee            mIsExpanded = false;
875253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        }
885253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee    }
895253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee
905253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee    @Override
915253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee    protected void setUp() {
925253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        mActivityUi = new MockActivityUi();
935253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        mSearchBox = new MockSearchBox(this.getInstrumentation().getContext());
945253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        mActionBarController = new ActionBarController(mActivityUi, mSearchBox);
955253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee    }
965253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee
975253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee    // Tapping the search box should only do something when the activity is not in the search UI
985253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee    public void testSearchBoxTapped() {
995253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        mSearchBox.collapse(false);
1005253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        mActivityUi.isInSearchUi = false;
1015253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        mActionBarController.onSearchBoxTapped();
1025253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        assertActionBarState(true, false, false);
1035253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee
1045253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        // Collapse the search box manually again. This time tapping on the search box should not
1055253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        // expand the search box because isInSearchUi is not true.
1065253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        mSearchBox.collapse(false);
1075253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        mActivityUi.isInSearchUi = true;
1085253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        mActionBarController.onSearchBoxTapped();
1095253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        assertActionBarState(false, false, false);
1105253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee    }
1115253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee
1125253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee    // The search box should always end up being faded in and collapsed. If necessary, it should
1135253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee    // be slid down or up depending on what the state of the action bar was before that.
1145253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee    public void testOnSearchUiExited() {
1155253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        // ActionBar shown previously before entering searchUI
1165253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        mSearchBox.expand(true, false);
117cdf36015580adf63bd32d2f1cdbf526918de9b88Yorke Lee        mSearchBox.setVisible(false);
1185253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        mActivityUi.shouldShowActionBar = true;
1195253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        mActionBarController.onSearchUiExited();
1205253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        assertActionBarState(false, false, false);
1215253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee
1225253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        // ActionBar slid up previously before entering searchUI
1235253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        mSearchBox.collapse(false);
124cdf36015580adf63bd32d2f1cdbf526918de9b88Yorke Lee        mSearchBox.setVisible(false);
1255253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        mActivityUi.shouldShowActionBar = false;
1265253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        mActionBarController.onSearchUiExited();
1275253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        assertActionBarState(false, false, true);
1285253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee    }
1295253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee
1305253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee    // Depending on what state the UI was in previously, sliding the dialpad down can mean either
1315253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee    // displaying the expanded search box by sliding it down, displaying the unexpanded search box,
1325253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee    // or nothing at all.
1335253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee    public void testOnDialpadDown() {
1345253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        // No search query typed in the dialpad and action bar was showing before
1355253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        mActivityUi.shouldShowActionBar = true;
1365253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        mActivityUi.isInSearchUi = true;
1375253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        mSearchBox.setVisible(false);
1385253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        mActionBarController.onDialpadDown();
1395253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        assertActionBarState(false, false, false);
1405253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee
1415253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        // No search query typed in the dialpad, but action bar was not showing before
142a524ae57ec8fce9532ed998c63a5577fce738fd5Yorke Lee        mActionBarController.slideActionBar(true /* slideUp */, false /* animate */);
1435253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        mActivityUi.shouldShowActionBar = false;
1445253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        mSearchBox.setVisible(false);
1455253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        mActionBarController.onDialpadDown();
1465253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        assertActionBarState(false, false, true);
1475253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee
1485253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        // Something typed in the dialpad - so remain in search UI and slide the expanded search
1495253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        // box down
150a524ae57ec8fce9532ed998c63a5577fce738fd5Yorke Lee        mActionBarController.slideActionBar(true /* slideUp */, false /* animate */);
1515253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        mActivityUi.shouldShowActionBar = true;
1525253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        mActivityUi.hasSearchQuery= true;
1535253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        mSearchBox.setVisible(false);
1545253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        mSearchBox.expand(false, false);
1555253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        mActionBarController.onDialpadDown();
1565253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        assertActionBarState(true, false, false);
1575253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee    }
1585253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee
1595253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee    // Sliding the dialpad up should fade out the search box if we weren't already in search, or
1605253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee    // slide up the search box otherwise
1615253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee    public void testOnDialpadUp() {
1625253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        mActivityUi.isInSearchUi = false;
1635253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        mActionBarController.onDialpadUp();
1645253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        assertActionBarState(false, true, false);
1655253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee
1665253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        // In Search UI, with expanded search box and something currently typed in the search box
1675253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        mActivityUi.isInSearchUi = true;
1685253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        mActivityUi.hasSearchQuery = true;
1695253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        mSearchBox.expand(true, false);
1705253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        mSearchBox.setVisible(true);
171a524ae57ec8fce9532ed998c63a5577fce738fd5Yorke Lee        mActionBarController.slideActionBar(true /* slideUp */, false /* animate */);
1725253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        mActionBarController.onDialpadUp();
1735253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        assertActionBarState(true, false, true);
1745253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee    }
1755253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee
1765253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee    private void assertActionBarState(boolean isExpanded, boolean isFadedOut, boolean isSlidUp) {
1775253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        assertEquals(isExpanded, mSearchBox.isExpanded());
1785253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        assertEquals(isFadedOut, mSearchBox.isFadedOut());
1795253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee        assertEquals(isSlidUp, mActionBarController.getIsActionBarSlidUp());
1805253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee    }
1815253be0d57edd4cdf5fbc0a980188e13e009c083Yorke Lee}
182