1 /*
2  * Copyright (C) 2010 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.stubs;
18 
19 import android.app.Activity;
20 import android.content.pm.ActivityInfo;
21 import java.util.concurrent.CountDownLatch;
22 import java.util.concurrent.TimeUnit;
23 import java.util.concurrent.atomic.AtomicReference;
24 
25 import static org.junit.Assert.assertTrue;
26 
27 public class OrientationTestUtils {
28     /**
29      * Change the activity's orientation to something different and then switch back. This is used
30      * to trigger {@link Activity#onConfigurationChanged(android.content.res.Configuration)}.
31      *
32      * @param activity whose orientation will be changed and restored
33      */
toggleOrientation(Activity activity)34     public static void toggleOrientation(Activity activity) {
35         final int[] orientations = getOrientations(activity);
36         activity.setRequestedOrientation(orientations[1]);
37         activity.setRequestedOrientation(orientations[0]);
38     }
39 
40     /**
41      * Switches the device's orientation from landscape to portrait or portrait to landscape.
42      *
43      * @param activity whose orientation will be changed
44      * @return original orientation
45      */
switchOrientation(final Activity activity)46     public static void switchOrientation(final Activity activity) {
47         final int[] orientations = getOrientations(activity);
48         activity.setRequestedOrientation(orientations[1]);
49     }
50 
51     /**
52      * Returns original orientation and toggled orientation.
53      * @param activity whose orienetaion will be returned
54      * @return The first element is original orientation adn the second element is toggled
55      *     orientation.
56      */
getOrientations(final Activity activity)57     private static int[] getOrientations(final Activity activity) {
58         final int originalOrientation = activity.getResources().getConfiguration().orientation;
59         final int newOrientation = originalOrientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
60             ? ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
61             : ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
62         return new int[] { originalOrientation, newOrientation };
63     }
64 
65     /**
66      * Observer used in stub activities to wait for some event.
67      */
68     public static class Observer {
69         private static final int TIMEOUT_SEC = 3;
70         private final AtomicReference<CountDownLatch> mLatch = new AtomicReference();
71 
72         /**
73          * Starts observing event.
74          * The returned CountDownLatch will get activated when onObserved is invoked after this
75          * call. The method cannot be called multiple times unless reset() is invoked.
76          * @return CountDownLatch will get activated when onObserved is invoked after this call.
77          */
startObserving()78         public void startObserving() {
79             final CountDownLatch latch = new CountDownLatch(1);
80             assertTrue(mLatch.compareAndSet(null, latch));
81         }
82 
83         /**
84          * Waits until onObserved is invoked.
85          */
await()86         public void await() throws InterruptedException {
87             try {
88                 assertTrue(mLatch.get().await(TIMEOUT_SEC, TimeUnit.SECONDS));
89             } finally {
90                 mLatch.set(null);
91             }
92         }
93 
94         /**
95          * Notifies an event is observed.
96          * If this method is invoked after startObserving, the returned CountDownLatch will get
97          * activated. Otherwise it does nothing.
98          */
onObserved()99         public void onObserved() {
100             final CountDownLatch latch = mLatch.get();
101             if (latch != null) {
102                 latch.countDown();
103             }
104         }
105     }
106 }
107