Phil Weaver | c140fdc | 2017-11-09 15:24:17 -0800 | [diff] [blame] | 1 | /* |
| 2 | * Copyright 2017 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.accessibility; |
Eugene Susla | 554edd3 | 2017-05-24 16:49:59 -0700 | [diff] [blame] | 18 | |
Phil Weaver | 2c9e780 | 2018-03-05 15:22:32 -0800 | [diff] [blame] | 19 | import static org.hamcrest.Matchers.emptyCollectionOf; |
| 20 | import static org.hamcrest.Matchers.equalTo; |
| 21 | import static org.hamcrest.Matchers.hasItem; |
| 22 | import static org.junit.Assert.assertThat; |
Eugene Susla | 554edd3 | 2017-05-24 16:49:59 -0700 | [diff] [blame] | 23 | import static org.junit.Assert.fail; |
| 24 | |
Phil Weaver | 2c9e780 | 2018-03-05 15:22:32 -0800 | [diff] [blame] | 25 | import android.os.Parcel; |
Aurimas Liutikas | bdbde55 | 2017-12-19 13:21:10 -0800 | [diff] [blame] | 26 | import android.support.test.filters.LargeTest; |
Eugene Susla | 554edd3 | 2017-05-24 16:49:59 -0700 | [diff] [blame] | 27 | import android.support.test.runner.AndroidJUnit4; |
| 28 | import android.util.ArraySet; |
Eugene Susla | 554edd3 | 2017-05-24 16:49:59 -0700 | [diff] [blame] | 29 | import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction; |
| 30 | |
| 31 | import com.android.internal.util.CollectionUtils; |
| 32 | |
| 33 | import org.junit.Test; |
| 34 | import org.junit.runner.RunWith; |
| 35 | |
| 36 | import java.util.ArrayList; |
| 37 | |
Aurimas Liutikas | bdbde55 | 2017-12-19 13:21:10 -0800 | [diff] [blame] | 38 | @LargeTest |
Eugene Susla | 554edd3 | 2017-05-24 16:49:59 -0700 | [diff] [blame] | 39 | @RunWith(AndroidJUnit4.class) |
| 40 | public class AccessibilityNodeInfoTest { |
Phil Weaver | 9e418b8 | 2018-04-03 11:02:52 -0700 | [diff] [blame^] | 41 | // The number of fields tested in the corresponding CTS AccessibilityNodeInfoTest: |
| 42 | // See fullyPopulateAccessibilityNodeInfo, assertEqualsAccessibilityNodeInfo, |
| 43 | // and assertAccessibilityNodeInfoCleared in that class. |
| 44 | private static final int NUM_MARSHALLED_PROPERTIES = 35; |
| 45 | |
| 46 | /** |
| 47 | * The number of properties that are purposely not marshalled |
| 48 | * mOriginalText - Used when resolving clickable spans; intentionally not parceled |
| 49 | */ |
| 50 | private static final int NUM_NONMARSHALLED_PROPERTIES = 1; |
Eugene Susla | 554edd3 | 2017-05-24 16:49:59 -0700 | [diff] [blame] | 51 | |
| 52 | @Test |
| 53 | public void testStandardActions_serializationFlagIsValid() { |
| 54 | AccessibilityAction brokenStandardAction = CollectionUtils.find( |
| 55 | new ArrayList<>(AccessibilityAction.sStandardActions), |
Phil Weaver | 2c9e780 | 2018-03-05 15:22:32 -0800 | [diff] [blame] | 56 | action -> Long.bitCount(action.mSerializationFlag) != 1); |
Eugene Susla | 554edd3 | 2017-05-24 16:49:59 -0700 | [diff] [blame] | 57 | if (brokenStandardAction != null) { |
| 58 | String message = "Invalid serialization flag(0x" |
Phil Weaver | 2c9e780 | 2018-03-05 15:22:32 -0800 | [diff] [blame] | 59 | + Long.toHexString(brokenStandardAction.mSerializationFlag) |
Eugene Susla | 554edd3 | 2017-05-24 16:49:59 -0700 | [diff] [blame] | 60 | + ") in " + brokenStandardAction; |
| 61 | if (brokenStandardAction.mSerializationFlag == 0L) { |
| 62 | message += "\nThis is likely due to an overflow"; |
| 63 | } |
| 64 | fail(message); |
| 65 | } |
| 66 | |
| 67 | brokenStandardAction = CollectionUtils.find( |
| 68 | new ArrayList<>(AccessibilityAction.sStandardActions), |
| 69 | action -> Integer.bitCount(action.getId()) == 1 |
| 70 | && action.getId() <= AccessibilityNodeInfo.LAST_LEGACY_STANDARD_ACTION |
| 71 | && action.getId() != action.mSerializationFlag); |
| 72 | if (brokenStandardAction != null) { |
| 73 | fail("Serialization flag(0x" |
Phil Weaver | 2c9e780 | 2018-03-05 15:22:32 -0800 | [diff] [blame] | 74 | + Long.toHexString(brokenStandardAction.mSerializationFlag) |
Eugene Susla | 554edd3 | 2017-05-24 16:49:59 -0700 | [diff] [blame] | 75 | + ") is different from legacy action id(0x" |
| 76 | + Integer.toHexString(brokenStandardAction.getId()) |
| 77 | + ") in " + brokenStandardAction); |
| 78 | } |
| 79 | } |
| 80 | |
| 81 | @Test |
| 82 | public void testStandardActions_idsAreUnique() { |
| 83 | ArraySet<AccessibilityAction> actions = AccessibilityAction.sStandardActions; |
| 84 | for (int i = 0; i < actions.size(); i++) { |
| 85 | for (int j = 0; j < i; j++) { |
| 86 | int id = actions.valueAt(i).getId(); |
| 87 | if (id == actions.valueAt(j).getId()) { |
| 88 | fail("Id 0x" + Integer.toHexString(id) |
| 89 | + " is duplicated for standard actions #" + i + " and #" + j); |
| 90 | } |
| 91 | } |
| 92 | } |
| 93 | } |
| 94 | |
Phil Weaver | 2c9e780 | 2018-03-05 15:22:32 -0800 | [diff] [blame] | 95 | @Test |
| 96 | public void testStandardActions_allComeThroughParceling() { |
| 97 | for (AccessibilityAction action : AccessibilityAction.sStandardActions) { |
| 98 | final AccessibilityNodeInfo nodeWithAction = AccessibilityNodeInfo.obtain(); |
| 99 | nodeWithAction.addAction(action); |
| 100 | assertThat(nodeWithAction.getActionList(), hasItem(action)); |
| 101 | final Parcel parcel = Parcel.obtain(); |
| 102 | nodeWithAction.writeToParcel(parcel, 0); |
| 103 | parcel.setDataPosition(0); |
| 104 | final AccessibilityNodeInfo unparceledNode = |
| 105 | AccessibilityNodeInfo.CREATOR.createFromParcel(parcel); |
| 106 | assertThat(unparceledNode.getActionList(), hasItem(action)); |
| 107 | } |
| 108 | } |
| 109 | |
| 110 | @Test |
| 111 | public void testEmptyListOfActions_parcelsCorrectly() { |
| 112 | // Also set text, as if there's nothing else in the parcel it can unparcel even with |
| 113 | // a bug present. |
| 114 | final String text = "text"; |
| 115 | final AccessibilityNodeInfo nodeWithEmptyActionList = AccessibilityNodeInfo.obtain(); |
| 116 | nodeWithEmptyActionList.addAction(AccessibilityAction.ACTION_ACCESSIBILITY_FOCUS); |
| 117 | nodeWithEmptyActionList.removeAction(AccessibilityAction.ACTION_ACCESSIBILITY_FOCUS); |
| 118 | nodeWithEmptyActionList.setText(text); |
| 119 | final Parcel parcel = Parcel.obtain(); |
| 120 | nodeWithEmptyActionList.writeToParcel(parcel, 0); |
| 121 | parcel.setDataPosition(0); |
| 122 | final AccessibilityNodeInfo unparceledNode = |
| 123 | AccessibilityNodeInfo.CREATOR.createFromParcel(parcel); |
| 124 | assertThat(unparceledNode.getActionList(), emptyCollectionOf(AccessibilityAction.class)); |
| 125 | assertThat(unparceledNode.getText(), equalTo(text)); |
| 126 | } |
Phil Weaver | 9e418b8 | 2018-04-03 11:02:52 -0700 | [diff] [blame^] | 127 | |
| 128 | @Test |
| 129 | public void dontForgetToUpdateCtsParcelingTestWhenYouAddNewFields() { |
| 130 | AccessibilityEventTest.assertNoNewNonStaticFieldsAdded(AccessibilityNodeInfo.class, |
| 131 | NUM_MARSHALLED_PROPERTIES + NUM_NONMARSHALLED_PROPERTIES); |
| 132 | } |
Eugene Susla | 554edd3 | 2017-05-24 16:49:59 -0700 | [diff] [blame] | 133 | } |