1 /*
2  * Copyright (C) 2022 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.app.cts;
18 
19 import android.app.Instrumentation;
20 import android.app.stubs.DialogStubActivity;
21 import android.view.ViewGroup;
22 import android.widget.ListAdapter;
23 import android.widget.ListView;
24 
25 import androidx.test.ext.junit.rules.ActivityScenarioRule;
26 import androidx.test.platform.app.InstrumentationRegistry;
27 
28 import com.android.compatibility.common.util.PollingCheck;
29 import com.android.compatibility.common.util.WindowUtil;
30 
31 import org.junit.Before;
32 import org.junit.Rule;
33 
34 /**
35  * Base class for AlertDialog_Builder tests.
36  */
37 public abstract class AlertDialog_BuilderTestBase {
38 
39     private static final long TOUCH_MODE_PROPAGATION_TIMEOUT_MILLIS = 5_000L;
40 
41     protected Instrumentation mInstrumentation;
42     protected DialogStubActivity mDialogActivity;
43 
44     @Rule
45     public ActivityScenarioRule<DialogStubActivity> mActivityRule =
46             new ActivityScenarioRule<>(DialogStubActivity.class);
47 
48     @Before
setUp()49     public void setUp() throws Exception {
50         mInstrumentation = InstrumentationRegistry.getInstrumentation();
51         mActivityRule.getScenario().onActivity(a -> mDialogActivity = a);
52         WindowUtil.waitForFocus(mDialogActivity);
53     }
54 
55     /**
56      * Re-attaches the floating {@link ListView} passed as argument to the activity started by the
57      * test's activity scenario, and then sets the adapter again. This will ensure that
58      * {@link ListView#lookForSelectablePosition} will be able to properly position its cursor.
59      *
60      * When setting the adapter, {@link ListView#lookForSelectablePosition} won't be able to
61      * position its cursor if the ListView is in touch mode (#lookForSelectablePosition requires the
62      * {@link ListView} to not be in touch mode).
63      */
reAttachListViewAdapter(ListView listView)64     void reAttachListViewAdapter(ListView listView) {
65         final ListAdapter[] adapter = new ListAdapter[1];
66         mActivityRule.getScenario().onActivity(a -> {
67             adapter[0] = listView.getAdapter();
68             ((ViewGroup) listView.getParent()).removeView(listView);
69             a.addContentView(listView, new ViewGroup.LayoutParams(1, 1));
70         });
71         mInstrumentation.setInTouchMode(false);
72         PollingCheck.waitFor(TOUCH_MODE_PROPAGATION_TIMEOUT_MILLIS,
73                 () -> !listView.isInTouchMode());
74         mActivityRule.getScenario().onActivity(a -> listView.setAdapter(adapter[0]));
75     }
76 }
77