1 /* 2 * Copyright (C) 2019 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 package android.contentcaptureservice.cts; 17 18 import static android.contentcaptureservice.cts.Assertions.assertDecorViewAppeared; 19 import static android.contentcaptureservice.cts.Assertions.assertRightActivity; 20 import static android.contentcaptureservice.cts.Assertions.assertSessionPaused; 21 import static android.contentcaptureservice.cts.Assertions.assertSessionResumed; 22 import static android.contentcaptureservice.cts.Assertions.assertViewAppeared; 23 import static android.contentcaptureservice.cts.Assertions.assertViewTreeFinished; 24 import static android.contentcaptureservice.cts.Assertions.assertViewTreeStarted; 25 import static android.contentcaptureservice.cts.Assertions.assertViewWithUnknownParentAppeared; 26 import static android.contentcaptureservice.cts.Assertions.assertViewsOptionallyDisappeared; 27 28 import static com.google.common.truth.Truth.assertThat; 29 30 import android.contentcaptureservice.cts.CtsContentCaptureService.Session; 31 import android.os.Bundle; 32 import android.util.Log; 33 import android.view.View; 34 import android.view.ViewStructure; 35 import android.view.contentcapture.ContentCaptureEvent; 36 37 import androidx.annotation.NonNull; 38 39 import com.android.compatibility.common.util.DoubleVisitor; 40 import com.android.compatibility.common.util.Visitor; 41 42 import java.util.List; 43 44 public class CustomViewActivity extends AbstractContentCaptureActivity { 45 46 private static final String TAG = CustomViewActivity.class.getSimpleName(); 47 48 private static DoubleVisitor<CustomView, ViewStructure> sCustomViewDelegate; 49 private static Visitor<CustomViewActivity> sRootViewVisitor; 50 51 /** 52 * Mininum number of events generated when the activity starts. 53 * 54 * <p>Used on {@link #assertInitialViewsAppeared(Session, int)} and 55 * {@link #assertInitialViewsDisappeared(List, int)}. 56 */ 57 public static final int MIN_EVENTS = 7; 58 59 CustomView mCustomView; 60 61 /** 62 * Sets a delegate that provides the behavior of 63 * {@link CustomView#onProvideContentCaptureStructure(ViewStructure, int)}. 64 */ setCustomViewDelegate(@onNull DoubleVisitor<CustomView, ViewStructure> delegate)65 static void setCustomViewDelegate(@NonNull DoubleVisitor<CustomView, ViewStructure> delegate) { 66 sCustomViewDelegate = delegate; 67 } 68 onRootView(@onNull Visitor<CustomViewActivity> visitor)69 static void onRootView(@NonNull Visitor<CustomViewActivity> visitor) { 70 sRootViewVisitor = visitor; 71 } 72 73 @Override onCreate(Bundle savedInstanceState)74 protected void onCreate(Bundle savedInstanceState) { 75 super.onCreate(savedInstanceState); 76 setContentView(R.layout.custom_view_activity); 77 mCustomView = findViewById(R.id.custom_view); 78 Log.d(TAG, "onCreate(): custom view id is " + mCustomView.getAutofillId()); 79 if (sCustomViewDelegate != null) { 80 Log.d(TAG, "Setting delegate on " + mCustomView); 81 mCustomView.setContentCaptureDelegate( 82 (structure) -> sCustomViewDelegate.visit(mCustomView, structure)); 83 } 84 if (sRootViewVisitor != null) { 85 try { 86 sRootViewVisitor.visit(this); 87 } finally { 88 sRootViewVisitor = null; 89 } 90 } 91 } 92 93 @Override assertDefaultEvents(@onNull Session session)94 public void assertDefaultEvents(@NonNull Session session) { 95 assertRightActivity(session, session.id, this); 96 final int additionalEvents = 0; 97 final List<ContentCaptureEvent> events = assertInitialViewsAppeared(session, 98 additionalEvents); 99 Log.v(TAG, "events(" + events.size() + "): " + events); 100 assertInitialViewsDisappeared(events, additionalEvents); 101 } 102 103 /** 104 * Asserts the events generated when this activity was launched, up to the 105 * {@code TYPE_INITIAL_VIEW_HIERARCHY_FINISHED} event. 106 */ 107 @NonNull assertInitialViewsAppeared(Session session, int additionalEvents)108 public List<ContentCaptureEvent> assertInitialViewsAppeared(Session session, 109 int additionalEvents) { 110 return assertJustInitialViewsAppeared(session, additionalEvents); 111 } 112 113 /** 114 * Asserts the events generated when this activity was launched, but without the 115 * {@code TYPE_INITIAL_VIEW_HIERARCHY_FINISHED} event. 116 */ 117 @NonNull assertJustInitialViewsAppeared(@onNull Session session, int additionalEvents)118 private List<ContentCaptureEvent> assertJustInitialViewsAppeared(@NonNull Session session, 119 int additionalEvents) { 120 final View grandpa1 = (View) mCustomView.getParent(); 121 final View grandpa2 = (View) grandpa1.getParent(); 122 final View decorView = getDecorView(); 123 Log.v(TAG, "assertJustInitialViewsAppeared(): grandpa1=" + grandpa1.getAutofillId() 124 + ", grandpa2=" + grandpa2.getAutofillId() + ", decor=" 125 + decorView.getAutofillId()); 126 127 final List<ContentCaptureEvent> events = session.getEvents(); 128 Log.v(TAG, "events(" + events.size() + "): " + events); 129 assertThat(events.size()).isAtLeast(MIN_EVENTS + additionalEvents); 130 131 // Assert just the relevant events 132 assertSessionResumed(events, 0); 133 assertViewTreeStarted(events, 1); 134 assertDecorViewAppeared(events, 2, getDecorView()); 135 assertViewAppeared(events, 3, grandpa2, decorView.getAutofillId()); 136 assertViewAppeared(events, 4, grandpa1, grandpa2.getAutofillId()); 137 assertViewWithUnknownParentAppeared(events, 5, session.id, mCustomView); 138 assertViewTreeFinished(events, 6); 139 140 return events; 141 } 142 143 /** 144 * Asserts the initial views disappeared after the activity was finished. 145 */ 146 // TODO(b/123540067, 122315042): fix and document or remove assertInitialViewsDisappeared(@onNull List<ContentCaptureEvent> events, int additionalEvents)147 public void assertInitialViewsDisappeared(@NonNull List<ContentCaptureEvent> events, 148 int additionalEvents) { 149 if (true) return; // TODO(b/123540067, 122315042): not really working 150 assertViewsOptionallyDisappeared(events, MIN_EVENTS + additionalEvents, 151 getDecorView().getAutofillId(), mCustomView.getAutofillId()); 152 assertSessionPaused(events, MIN_EVENTS + additionalEvents); 153 } 154 } 155