1 /* 2 * Copyright (C) 2015 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.view.cts; 18 19 import static org.junit.Assert.assertEquals; 20 import static org.junit.Assert.assertFalse; 21 import static org.junit.Assert.assertNotNull; 22 import static org.junit.Assert.assertNull; 23 import static org.junit.Assert.assertSame; 24 import static org.junit.Assert.assertTrue; 25 import static org.mockito.Matchers.any; 26 import static org.mockito.Mockito.atLeastOnce; 27 import static org.mockito.Mockito.doReturn; 28 import static org.mockito.Mockito.mock; 29 import static org.mockito.Mockito.never; 30 import static org.mockito.Mockito.spy; 31 import static org.mockito.Mockito.verify; 32 33 import android.app.Instrumentation; 34 import android.graphics.Rect; 35 import android.view.ActionMode; 36 import android.view.Menu; 37 import android.view.MenuInflater; 38 import android.view.View; 39 40 import androidx.test.InstrumentationRegistry; 41 import androidx.test.filters.SmallTest; 42 import androidx.test.rule.ActivityTestRule; 43 import androidx.test.runner.AndroidJUnit4; 44 45 import org.junit.Before; 46 import org.junit.Rule; 47 import org.junit.Test; 48 import org.junit.runner.RunWith; 49 50 @SmallTest 51 @RunWith(AndroidJUnit4.class) 52 public class ActionModeTest { 53 private Instrumentation mInstrumentation; 54 private ActionModeCtsActivity mActivity; 55 56 @Rule 57 public ActivityTestRule<ActionModeCtsActivity> mActivityRule = 58 new ActivityTestRule<>(ActionModeCtsActivity.class); 59 60 @Before setup()61 public void setup() { 62 mInstrumentation = InstrumentationRegistry.getInstrumentation(); 63 mActivity = mActivityRule.getActivity(); 64 } 65 66 @Test testSetType()67 public void testSetType() { 68 final ActionMode mockActionMode = new MockActionMode(); 69 assertEquals(ActionMode.TYPE_PRIMARY, mockActionMode.getType()); 70 71 mockActionMode.setType(ActionMode.TYPE_FLOATING); 72 assertEquals(ActionMode.TYPE_FLOATING, mockActionMode.getType()); 73 74 mockActionMode.setType(ActionMode.TYPE_PRIMARY); 75 assertEquals(ActionMode.TYPE_PRIMARY, mockActionMode.getType()); 76 } 77 78 @Test testInvalidateContentRectDoesNotInvalidateFull()79 public void testInvalidateContentRectDoesNotInvalidateFull() { 80 final ActionMode mockActionMode = spy(new MockActionMode()); 81 82 mockActionMode.invalidateContentRect(); 83 84 verify(mockActionMode, never()).invalidate(); 85 } 86 87 @Test testInvalidateContentRectOnFloatingCallsCallback()88 public void testInvalidateContentRectOnFloatingCallsCallback() throws Throwable { 89 final View view = mActivity.contentView; 90 final ActionMode.Callback2 mockCallback = mock(ActionMode.Callback2.class); 91 doReturn(Boolean.TRUE).when(mockCallback).onCreateActionMode( 92 any(ActionMode.class), any(Menu.class)); 93 doReturn(Boolean.TRUE).when(mockCallback).onPrepareActionMode( 94 any(ActionMode.class), any(Menu.class)); 95 96 mActivityRule.runOnUiThread(() -> { 97 ActionMode mode = view.startActionMode(mockCallback, ActionMode.TYPE_FLOATING); 98 assertNotNull(mode); 99 mode.invalidateContentRect(); 100 }); 101 mInstrumentation.waitForIdleSync(); 102 103 verify(mockCallback, atLeastOnce()).onGetContentRect(any(ActionMode.class), any(View.class), 104 any(Rect.class)); 105 } 106 107 @Test testSetAndGetTitleOptionalHint()108 public void testSetAndGetTitleOptionalHint() { 109 final ActionMode actionMode = new MockActionMode(); 110 111 // Check default value. 112 assertFalse(actionMode.getTitleOptionalHint()); 113 // Test set and get. 114 actionMode.setTitleOptionalHint(true); 115 assertTrue(actionMode.getTitleOptionalHint()); 116 actionMode.setTitleOptionalHint(false); 117 assertFalse(actionMode.getTitleOptionalHint()); 118 } 119 120 @Test testSetAndGetTag()121 public void testSetAndGetTag() { 122 final ActionMode actionMode = new MockActionMode(); 123 Object tag = new Object(); 124 125 // Check default value. 126 assertNull(actionMode.getTag()); 127 128 actionMode.setTag(tag); 129 assertSame(tag, actionMode.getTag()); 130 } 131 132 @Test testIsTitleOptional()133 public void testIsTitleOptional() { 134 final ActionMode actionMode = new MockActionMode(); 135 136 // Check default value. 137 assertFalse(actionMode.isTitleOptional()); 138 } 139 140 @Test testIsUiFocusable()141 public void testIsUiFocusable() { 142 final ActionMode actionMode = new MockActionMode(); 143 144 // Check default value. 145 assertTrue(actionMode.isUiFocusable()); 146 } 147 148 @Test testHide()149 public void testHide() { 150 final ActionMode actionMode = new MockActionMode(); 151 152 actionMode.hide(0); 153 actionMode.hide(ActionMode.DEFAULT_HIDE_DURATION); 154 } 155 156 @Test testOnWindowFocusChanged()157 public void testOnWindowFocusChanged() { 158 final ActionMode actionMode = new MockActionMode(); 159 160 actionMode.onWindowFocusChanged(true); 161 actionMode.onWindowFocusChanged(false); 162 } 163 164 protected static class MockActionMode extends ActionMode { 165 @Override setTitle(CharSequence title)166 public void setTitle(CharSequence title) {} 167 168 @Override setTitle(int resId)169 public void setTitle(int resId) {} 170 171 @Override setSubtitle(CharSequence subtitle)172 public void setSubtitle(CharSequence subtitle) {} 173 174 @Override setSubtitle(int resId)175 public void setSubtitle(int resId) {} 176 177 @Override setCustomView(View view)178 public void setCustomView(View view) {} 179 180 @Override invalidate()181 public void invalidate() { 182 } 183 184 @Override finish()185 public void finish() {} 186 187 @Override getMenu()188 public Menu getMenu() { 189 return null; 190 } 191 192 @Override getTitle()193 public CharSequence getTitle() { 194 return null; 195 } 196 197 @Override getSubtitle()198 public CharSequence getSubtitle() { 199 return null; 200 } 201 202 @Override getCustomView()203 public View getCustomView() { 204 return null; 205 } 206 207 @Override getMenuInflater()208 public MenuInflater getMenuInflater() { 209 return null; 210 } 211 } 212 } 213