• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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.server.wm.jetpack.utils;
18 
19 import static android.server.wm.jetpack.utils.WindowManagerJetpackTestBase.getActivityBounds;
20 
21 import android.app.Activity;
22 import android.content.Context;
23 import android.content.res.Configuration;
24 import android.graphics.Rect;
25 import android.os.Bundle;
26 import android.view.View;
27 
28 import androidx.annotation.Nullable;
29 
30 import java.util.concurrent.CountDownLatch;
31 import java.util.concurrent.TimeUnit;
32 
33 /**
34  * Test activity that can verify whether the layout changes. Copied from
35  * androidx.window.TestActivity.
36  */
37 public class TestActivity extends Activity implements View.OnLayoutChangeListener {
38 
39     private int mRootViewId;
40     private CountDownLatch mLayoutLatch;
41     private CountDownLatch mBoundsChangeLatch;
42     private final Rect mPreviousBounds = new Rect();
43     private static CountDownLatch sResumeLatch = new CountDownLatch(1);
44 
45     @Override
onCreate(@ullable Bundle savedInstanceState)46     public void onCreate(@Nullable Bundle savedInstanceState) {
47         super.onCreate(savedInstanceState);
48         final View contentView = new TestContentViewForConfigurationChange(this);
49         mRootViewId = View.generateViewId();
50         contentView.setId(mRootViewId);
51         setContentView(contentView);
52 
53         resetLayoutCounter();
54         resetBoundsChangeCounter();
55         getWindow().getDecorView().addOnLayoutChangeListener(this);
56     }
57 
getWidth()58     int getWidth() {
59         return findViewById(mRootViewId).getWidth();
60     }
61 
getHeight()62     int getHeight() {
63         return findViewById(mRootViewId).getHeight();
64     }
65 
66     @Override
onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom)67     public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft,
68             int oldTop, int oldRight, int oldBottom) {
69         mLayoutLatch.countDown();
70     }
71 
72     @Override
onResume()73     protected void onResume() {
74         super.onResume();
75         sResumeLatch.countDown();
76     }
77 
78     /**
79      * Resets layout counter when waiting for a layout to happen before calling
80      * {@link #waitForLayout()}.
81      */
resetLayoutCounter()82     public void resetLayoutCounter() {
83         mLayoutLatch = new CountDownLatch(1);
84     }
85 
86     /**
87      * Resets bounds change counter when waiting for a bounds change to happen before calling
88      * {@link #waitForBoundsChange()}.
89      */
resetBoundsChangeCounter()90     public void resetBoundsChangeCounter() {
91         mPreviousBounds.set(getActivityBounds(this));
92         mBoundsChangeLatch = new CountDownLatch(1);
93     }
94 
95     /**
96      * Blocks and waits for the next layout to happen. {@link #resetLayoutCounter()} must be called
97      * before calling this method.
98      * @return {@code true} if the layout happened before the timeout count reached zero and
99      *         {@code false} if the waiting time elapsed before the layout happened.
100      */
waitForLayout()101     public boolean waitForLayout() {
102         try {
103             return mLayoutLatch.await(3, TimeUnit.SECONDS);
104         } catch (InterruptedException e) {
105             return false;
106         }
107     }
108 
109     /**
110      * Blocks and waits for the next bounds change to happen. {@link #resetBoundsChangeCounter()}
111      * must be called before calling this method.
112      * @return {@code true} if the bounds change happened before the timeout count reached zero and
113      *         {@code false} if the waiting time elapsed before the bounds change happened.
114      */
waitForBoundsChange()115     public boolean waitForBoundsChange() {
116         try {
117             return mBoundsChangeLatch.await(3, TimeUnit.SECONDS);
118         } catch (InterruptedException e) {
119             return false;
120         }
121     }
122 
123     /**
124      * Resets layout counter when waiting for a layout to happen before calling
125      * {@link #waitForOnResume()}.
126      */
resetResumeCounter()127     public static void resetResumeCounter() {
128         sResumeLatch = new CountDownLatch(1);
129     }
130 
131     /**
132      * Same as {@link #waitForLayout()}, but waits for onResume() to be called for any activity of
133      * this class. This can be used to track activity re-creation.
134      * @return {@code true} if the onResume() happened before the timeout count reached zero and
135      *         {@code false} if the waiting time elapsed before the onResume() happened.
136      */
waitForOnResume()137     public static boolean waitForOnResume() {
138         try {
139             return sResumeLatch.await(3, TimeUnit.SECONDS);
140         } catch (InterruptedException e) {
141             return false;
142         }
143     }
144 
145     /**
146      * Sometimes activity configuration change does not trigger when embedding status change, need
147      * to use View's instead.
148      */
149     class TestContentViewForConfigurationChange extends View {
TestContentViewForConfigurationChange(Context context)150         public TestContentViewForConfigurationChange(Context context) {
151             super(context);
152         }
153 
154         @Override
onConfigurationChanged(Configuration newConfig)155         protected void onConfigurationChanged(Configuration newConfig) {
156             super.onConfigurationChanged(newConfig);
157             final Rect newActivityBounds = getActivityBounds(TestActivity.this);
158             if (!newActivityBounds.equals(mPreviousBounds)) {
159                 mPreviousBounds.set(newActivityBounds);
160                 mBoundsChangeLatch.countDown();
161             }
162         }
163     }
164 }
165