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

Commit 18cc17a2 authored by Clara Bayarri's avatar Clara Bayarri
Browse files

PhoneWindow ActionMode handling tests

Tests focusing on action mode creation, how the two types of
modes are handled together and how the lifecycle is handled.

Change-Id: I17fe7a83cba4651b295a8ce80bc449f2f2538048
parent be752b1f
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -1119,6 +1119,8 @@
        </activity>
        <activity android:name="com.android.internal.app.WindowDecorActionBarTestActivity">
        </activity>
        <activity android:name="com.android.internal.policy.PhoneWindowActionModeTestActivity">
        </activity>

        <receiver android:name="android.app.activity.AbortReceiver">
            <intent-filter android:priority="1">
+372 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.internal.policy;

import android.test.ActivityInstrumentationTestCase2;
import android.test.UiThreadTest;
import android.view.ActionMode;
import android.view.ActionMode.Callback;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.SearchEvent;
import android.view.View;
import android.view.Window;
import android.view.WindowManager.LayoutParams;
import android.view.accessibility.AccessibilityEvent;

/**
 * Tests {@link PhoneWindow}'s {@link ActionMode} related methods.
 */
public final class PhoneWindowActionModeTest
        extends ActivityInstrumentationTestCase2<PhoneWindowActionModeTestActivity> {

    private PhoneWindow mPhoneWindow;
    private MockWindowCallback mWindowCallback;
    private MockActionModeCallback mActionModeCallback;

    public PhoneWindowActionModeTest() {
        super(PhoneWindowActionModeTestActivity.class);
    }

    @Override
    protected void setUp() throws Exception {
        super.setUp();
        mPhoneWindow = (PhoneWindow) getActivity().getWindow();
        mWindowCallback = new MockWindowCallback();
        mPhoneWindow.setCallback(mWindowCallback);
        mActionModeCallback = new MockActionModeCallback();
    }

    public void testStartActionModeWithCallback() {
        mWindowCallback.mShouldReturnOwnActionMode = true;

        ActionMode mode = mPhoneWindow.getDecorView().startActionMode(
                mActionModeCallback, ActionMode.TYPE_FLOATING);

        assertEquals(mWindowCallback.mLastCreatedActionMode, mode);
    }

    public void testStartActionModePrimaryFinishesPreviousMode() {
        // Use custom callback to control the provided ActionMode.
        mWindowCallback.mShouldReturnOwnActionMode = true;

        ActionMode mode1 = mPhoneWindow.getDecorView().startActionMode(
                mActionModeCallback, ActionMode.TYPE_PRIMARY);
        ActionMode mode2 = mPhoneWindow.getDecorView().startActionMode(
                mActionModeCallback, ActionMode.TYPE_PRIMARY);

        assertTrue(mode1 instanceof MockActionMode);
        assertTrue(((MockActionMode) mode1).mIsFinished);
        assertNotNull(mode2);
    }

    public void testStartActionModeFloatingFinishesPreviousMode() {
        // Use custom callback to control the provided ActionMode.
        mWindowCallback.mShouldReturnOwnActionMode = true;

        ActionMode mode1 = mPhoneWindow.getDecorView().startActionMode(
                mActionModeCallback, ActionMode.TYPE_FLOATING);
        ActionMode mode2 = mPhoneWindow.getDecorView().startActionMode(
                mActionModeCallback, ActionMode.TYPE_FLOATING);

        assertTrue(mode1 instanceof MockActionMode);
        assertTrue(((MockActionMode) mode1).mIsFinished);
        assertNotNull(mode2);
    }

    public void testStartActionModePreservesPreviousModeOfDifferentType1() {
        // Use custom callback to control the provided ActionMode.
        mWindowCallback.mShouldReturnOwnActionMode = true;

        ActionMode mode1 = mPhoneWindow.getDecorView().startActionMode(
                mActionModeCallback, ActionMode.TYPE_FLOATING);
        ActionMode mode2 = mPhoneWindow.getDecorView().startActionMode(
                mActionModeCallback, ActionMode.TYPE_PRIMARY);

        assertTrue(mode1 instanceof MockActionMode);
        assertFalse(((MockActionMode) mode1).mIsFinished);
        assertNotNull(mode2);
    }

    public void testStartActionModePreservesPreviousModeOfDifferentType2() {
        // Use custom callback to control the provided ActionMode.
        mWindowCallback.mShouldReturnOwnActionMode = true;

        ActionMode mode1 = mPhoneWindow.getDecorView().startActionMode(
                mActionModeCallback, ActionMode.TYPE_PRIMARY);
        ActionMode mode2 = mPhoneWindow.getDecorView().startActionMode(
                mActionModeCallback, ActionMode.TYPE_FLOATING);

        assertTrue(mode1 instanceof MockActionMode);
        assertFalse(((MockActionMode) mode1).mIsFinished);
        assertNotNull(mode2);
    }

    public void testWindowCallbackModesLifecycleIsNotHandled() {
        mWindowCallback.mShouldReturnOwnActionMode = true;

        ActionMode mode = mPhoneWindow.getDecorView().startActionMode(
                mActionModeCallback, ActionMode.TYPE_PRIMARY);

        assertNotNull(mode);
        assertEquals(mWindowCallback.mLastCreatedActionMode, mode);
        assertFalse(mActionModeCallback.mIsCreateActionModeCalled);
        assertTrue(mWindowCallback.mIsActionModeStarted);
    }

    @UiThreadTest
    public void testCreatedPrimaryModeLifecycleIsHandled() {
        mWindowCallback.mShouldReturnOwnActionMode = false;

        ActionMode mode = mPhoneWindow.getDecorView().startActionMode(
                mActionModeCallback, ActionMode.TYPE_PRIMARY);

        assertNotNull(mode);
        assertEquals(ActionMode.TYPE_PRIMARY, mode.getType());
        assertTrue(mActionModeCallback.mIsCreateActionModeCalled);
        assertTrue(mWindowCallback.mIsActionModeStarted);
    }

    @UiThreadTest
    public void testCreatedFloatingModeLifecycleIsHandled() {
        mWindowCallback.mShouldReturnOwnActionMode = false;

        ActionMode mode = mPhoneWindow.getDecorView().startActionMode(
                mActionModeCallback, ActionMode.TYPE_FLOATING);

        assertNotNull(mode);
        assertEquals(ActionMode.TYPE_FLOATING, mode.getType());
        assertTrue(mActionModeCallback.mIsCreateActionModeCalled);
        assertTrue(mWindowCallback.mIsActionModeStarted);
    }

    @UiThreadTest
    public void testCreatedModeIsNotStartedIfCreateReturnsFalse() {
        mWindowCallback.mShouldReturnOwnActionMode = false;
        mActionModeCallback.mShouldCreateActionMode = false;

        ActionMode mode = mPhoneWindow.getDecorView().startActionMode(
                mActionModeCallback, ActionMode.TYPE_FLOATING);

        assertTrue(mActionModeCallback.mIsCreateActionModeCalled);
        assertFalse(mWindowCallback.mIsActionModeStarted);
        assertNull(mode);
    }

    private static final class MockWindowCallback implements Window.Callback {
        private boolean mShouldReturnOwnActionMode = false;
        private MockActionMode mLastCreatedActionMode;
        private boolean mIsActionModeStarted = false;

        @Override
        public boolean dispatchKeyEvent(KeyEvent event) {
            return false;
        }

        @Override
        public boolean dispatchKeyShortcutEvent(KeyEvent event) {
            return false;
        }

        @Override
        public boolean dispatchTouchEvent(MotionEvent event) {
            return false;
        }

        @Override
        public boolean dispatchTrackballEvent(MotionEvent event) {
            return false;
        }

        @Override
        public boolean dispatchGenericMotionEvent(MotionEvent event) {
            return false;
        }

        @Override
        public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
            return false;
        }

        @Override
        public View onCreatePanelView(int featureId) {
            return null;
        }

        @Override
        public boolean onCreatePanelMenu(int featureId, Menu menu) {
            return false;
        }

        @Override
        public boolean onPreparePanel(int featureId, View view, Menu menu) {
            return false;
        }

        @Override
        public boolean onMenuOpened(int featureId, Menu menu) {
            return false;
        }

        @Override
        public boolean onMenuItemSelected(int featureId, MenuItem item) {
            return false;
        }

        @Override
        public void onWindowAttributesChanged(LayoutParams attrs) {}

        @Override
        public void onContentChanged() {}

        @Override
        public void onWindowFocusChanged(boolean hasFocus) {}

        @Override
        public void onAttachedToWindow() {}

        @Override
        public void onDetachedFromWindow() {}

        @Override
        public void onPanelClosed(int featureId, Menu menu) {}

        @Override
        public boolean onSearchRequested() {
            return false;
        }

        @Override
        public boolean onSearchRequested(SearchEvent searchEvent) {
            return false;
        }

        @Override
        public ActionMode onWindowStartingActionMode(Callback callback) {
            if (mShouldReturnOwnActionMode) {
                MockActionMode mode = new MockActionMode();
                mLastCreatedActionMode = mode;
                return mode;
            }
            return null;
        }

        @Override
        public ActionMode onWindowStartingActionMode(Callback callback, int type) {
            if (mShouldReturnOwnActionMode) {
                MockActionMode mode = new MockActionMode();
                mode.mActionModeType = type;
                mLastCreatedActionMode = mode;
                return mode;
            }
            return null;
        }

        @Override
        public void onActionModeStarted(ActionMode mode) {
            mIsActionModeStarted = true;
        }

        @Override
        public void onActionModeFinished(ActionMode mode) {}
    }

    private static final class MockActionModeCallback implements ActionMode.Callback {
        private boolean mShouldCreateActionMode = true;
        private boolean mIsCreateActionModeCalled = false;

        @Override
        public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
            return true;
        }

        @Override
        public void onDestroyActionMode(ActionMode mode) {}

        @Override
        public boolean onCreateActionMode(ActionMode mode, Menu menu) {
            mIsCreateActionModeCalled = true;
            return mShouldCreateActionMode;
        }

        @Override
        public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
            return false;
        }
    }

    private static final class MockActionMode extends ActionMode {
        private int mActionModeType = ActionMode.TYPE_PRIMARY;
        private boolean mIsFinished = false;

        @Override
        public int getType() {
            return mActionModeType;
        }

        @Override
        public void setTitle(CharSequence title) {}

        @Override
        public void setTitle(int resId) {}

        @Override
        public void setSubtitle(CharSequence subtitle) {}

        @Override
        public void setSubtitle(int resId) {}

        @Override
        public void setCustomView(View view) {}

        @Override
        public void invalidate() {}

        @Override
        public void finish() {
            mIsFinished = true;
        }

        @Override
        public Menu getMenu() {
            return null;
        }

        @Override
        public CharSequence getTitle() {
            return null;
        }

        @Override
        public CharSequence getSubtitle() {
            return null;
        }

        @Override
        public View getCustomView() {
            return null;
        }

        @Override
        public MenuInflater getMenuInflater() {
            return null;
        }
    }
}
+30 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.internal.policy;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;

public class PhoneWindowActionModeTestActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(new View(this));
    }
}