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 static org.junit.Assert.assertTrue; 20 21 import android.app.Activity; 22 import android.content.pm.ActivityInfo; 23 import android.content.res.Resources; 24 import android.view.DisplayInfo; 25 26 import java.util.concurrent.CountDownLatch; 27 import java.util.concurrent.TimeUnit; 28 import java.util.concurrent.atomic.AtomicReference; 29 30 public class OrientationTestUtils { 31 /** 32 * Change the activity's orientation to something different and then switch back. This is used 33 * to trigger {@link Activity#onConfigurationChanged(android.content.res.Configuration)}. 34 * 35 * @param activity whose orientation will be changed and restored 36 */ toggleOrientation(Activity activity)37 public static void toggleOrientation(Activity activity) { 38 final int[] orientations = getOrientations(activity); 39 activity.setRequestedOrientation(orientations[1]); 40 activity.setRequestedOrientation(orientations[0]); 41 } 42 43 /** 44 * Switches the device's orientation from landscape to portrait or portrait to landscape. 45 * 46 * @param activity whose orientation will be changed 47 * @return original orientation 48 */ switchOrientation(final Activity activity)49 public static void switchOrientation(final Activity activity) { 50 final int[] orientations = getOrientations(activity); 51 activity.setRequestedOrientation(orientations[1]); 52 } 53 54 /** 55 * Returns display original orientation and toggled orientation. 56 * @param activity context to get the display info 57 * @return The first element is original orientation and the second element is toggled 58 * orientation. 59 */ getOrientations(final Activity activity)60 private static int[] getOrientations(final Activity activity) { 61 // Check the display dimension to get the current device orientation. 62 final DisplayInfo displayInfo = new DisplayInfo(); 63 activity.getDisplay().getDisplayInfo(displayInfo); 64 final int originalOrientation = displayInfo.logicalWidth > displayInfo.logicalHeight 65 ? ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE 66 : ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; 67 final int newOrientation = originalOrientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT 68 ? ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE 69 : ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; 70 return new int[] { originalOrientation, newOrientation }; 71 } 72 73 /** Checks whether the display dimension is close to square. */ isCloseToSquareDisplay(final Activity activity)74 public static boolean isCloseToSquareDisplay(final Activity activity) { 75 final Resources resources = activity.getResources(); 76 final float closeToSquareMaxAspectRatio; 77 try { 78 closeToSquareMaxAspectRatio = resources.getFloat(resources.getIdentifier( 79 "config_closeToSquareDisplayMaxAspectRatio", "dimen", "android")); 80 } catch (Resources.NotFoundException e) { 81 // Assume device is not close to square. 82 return false; 83 } 84 final DisplayInfo displayInfo = new DisplayInfo(); 85 activity.getDisplay().getDisplayInfo(displayInfo); 86 final int w = displayInfo.logicalWidth; 87 final int h = displayInfo.logicalHeight; 88 final float aspectRatio = Math.max(w, h) / (float) Math.min(w, h); 89 return aspectRatio <= closeToSquareMaxAspectRatio; 90 } 91 92 /** 93 * Observer used in stub activities to wait for some event. 94 */ 95 public static class Observer { 96 private static final int TIMEOUT_SEC = 3; 97 private final AtomicReference<CountDownLatch> mLatch = new AtomicReference(); 98 99 /** 100 * Starts observing event. 101 * The returned CountDownLatch will get activated when onObserved is invoked after this 102 * call. The method cannot be called multiple times unless reset() is invoked. 103 * @return CountDownLatch will get activated when onObserved is invoked after this call. 104 */ startObserving()105 public void startObserving() { 106 final CountDownLatch latch = new CountDownLatch(1); 107 assertTrue(mLatch.compareAndSet(null, latch)); 108 } 109 110 /** 111 * Waits until onObserved is invoked. 112 */ await()113 public void await() throws InterruptedException { 114 try { 115 assertTrue(mLatch.get().await(TIMEOUT_SEC, TimeUnit.SECONDS)); 116 } finally { 117 mLatch.set(null); 118 } 119 } 120 121 /** 122 * Notifies an event is observed. 123 * If this method is invoked after startObserving, the returned CountDownLatch will get 124 * activated. Otherwise it does nothing. 125 */ onObserved()126 public void onObserved() { 127 final CountDownLatch latch = mLatch.get(); 128 if (latch != null) { 129 latch.countDown(); 130 } 131 } 132 } 133 } 134