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