1 /* 2 * Copyright 2018 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.media.cts; 18 19 import static android.content.pm.PackageManager.MATCH_APEX; 20 21 import static org.junit.Assume.assumeTrue; 22 23 import android.content.Context; 24 import android.content.pm.ApplicationInfo; 25 import android.content.pm.PackageInfo; 26 import android.content.pm.PackageManager; 27 import android.os.Bundle; 28 import android.text.TextUtils; 29 import android.util.Log; 30 31 import androidx.test.InstrumentationRegistry; 32 import androidx.test.core.app.ApplicationProvider; 33 34 import org.junit.Assert; 35 import org.junit.AssumptionViolatedException; 36 37 import java.util.Objects; 38 39 /** 40 * Utilities for tests. 41 */ 42 public final class TestUtils { 43 private static String TAG = "TestUtils"; 44 private static final int WAIT_TIME_MS = 1000; 45 private static final int WAIT_SERVICE_TIME_MS = 5000; 46 47 /** 48 * Compares contents of two bundles. 49 * 50 * @param a a bundle 51 * @param b another bundle 52 * @return {@code true} if two bundles are the same. {@code false} otherwise. This may be 53 * incorrect if any bundle contains a bundle. 54 */ equals(Bundle a, Bundle b)55 public static boolean equals(Bundle a, Bundle b) { 56 if (a == b) { 57 return true; 58 } 59 if (a == null || b == null) { 60 return false; 61 } 62 if (!a.keySet().containsAll(b.keySet()) 63 || !b.keySet().containsAll(a.keySet())) { 64 return false; 65 } 66 for (String key : a.keySet()) { 67 if (!Objects.equals(a.get(key), b.get(key))) { 68 return false; 69 } 70 } 71 return true; 72 } 73 74 /** 75 * Checks {@code module} is at least {@code minVersion} 76 * 77 * The tests are skipped by throwing a {@link AssumptionViolatedException}. CTS test runners 78 * will report this as a {@code ASSUMPTION_FAILED}. 79 * 80 * @param module the apex module name 81 * @param minVersion the minimum version 82 * @throws AssumptionViolatedException if module version < minVersion 83 */ assumeMainlineModuleAtLeast(String module, long minVersion)84 public static void assumeMainlineModuleAtLeast(String module, long minVersion) { 85 try { 86 long actualVersion = getModuleVersion(module); 87 assumeTrue("Assume module " + module + " version " + actualVersion + " < minVersion" 88 + minVersion, actualVersion >= minVersion); 89 } catch (PackageManager.NameNotFoundException e) { 90 Assert.fail(e.getMessage()); 91 } 92 } 93 94 /** 95 * Checks if {@code module} is < {@code minVersion} 96 * 97 * <p> 98 * {@link AssumptionViolatedException} is not handled properly by {@code JUnit3} so just return 99 * the test 100 * early instead. 101 * 102 * @param module the apex module name 103 * @param minVersion the minimum version 104 * @deprecated convert test to JUnit4 and use 105 * {@link #assumeMainlineModuleAtLeast(String, long)} instead. 106 */ 107 @Deprecated skipTestIfMainlineLessThan(String module, long minVersion)108 public static boolean skipTestIfMainlineLessThan(String module, long minVersion) { 109 try { 110 long actualVersion = getModuleVersion(module); 111 if (actualVersion < minVersion) { 112 Log.i(TAG, "Skipping test because Module " + module + " minVersion " + minVersion 113 + " > " 114 + minVersion 115 ); 116 return true; 117 } else { 118 return false; 119 } 120 } catch (PackageManager.NameNotFoundException e) { 121 Assert.fail(e.getMessage()); 122 return false; 123 } 124 } 125 getModuleVersion(String module)126 private static long getModuleVersion(String module) 127 throws PackageManager.NameNotFoundException { 128 Context context = ApplicationProvider.getApplicationContext(); 129 PackageInfo info = context.getPackageManager().getPackageInfo(module, 130 MATCH_APEX); 131 return info.getLongVersionCode(); 132 } 133 134 135 /** 136 * Reports whether {@code module} is the version shipped with the original system image 137 * or if it has been updated via a mainline update. 138 * 139 * @param module the apex module name 140 * @return {@code true} if the apex module is the original version shipped with the device. 141 */ isMainlineModuleFactoryVersion(String module)142 public static boolean isMainlineModuleFactoryVersion(String module) { 143 try { 144 Context context = ApplicationProvider.getApplicationContext(); 145 PackageInfo info = context.getPackageManager().getPackageInfo(module, 146 MATCH_APEX); 147 if (info != null) { 148 return (info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 149 } 150 } catch (PackageManager.NameNotFoundException e) { 151 // Ignore the exception on devices that do not have this module 152 } 153 return true; 154 } 155 156 /* 157 * Report whether we are in MTS mode (vs in CTS) mode. 158 * Some tests (or parts of tests) are restricted to a particular mode. 159 */ isMtsMode()160 public static boolean isMtsMode() { 161 Bundle bundle = InstrumentationRegistry.getArguments(); 162 // null if not set 163 boolean isMTS = TextUtils.equals("true", bundle.getString("mts-media")); 164 165 return isMTS; 166 } 167 168 /* 169 * Report whether we want to test a particular code in the current test mode. 170 * CTS is pretty much "test them all". 171 * MTS should only be testing codecs that are part of the swcodec module; all of these 172 * begin with "c2.android." 173 * 174 * Used in spots throughout the test suite where we want to limit our testing to relevant 175 * codecs. This avoids false alarms that are sometimes triggered by non-compliant, 176 * non-mainline codecs. 177 * 178 * @param name the name of a codec 179 * @return {@code} true is the codec should be tested in the current operating mode. 180 */ isTestableCodecInCurrentMode(String name)181 public static boolean isTestableCodecInCurrentMode(String name) { 182 if (name == null) { 183 return false; 184 } 185 if (!isMtsMode()) { 186 // CTS mode -- test everything 187 return true; 188 } 189 // MTS mode, just the codecs that live in the modules 190 if (name.startsWith("c2.android.")) { 191 return true; 192 } 193 return false; 194 } 195 TestUtils()196 private TestUtils() { 197 } 198 199 public static class Monitor { 200 private int mNumSignal; 201 reset()202 public synchronized void reset() { 203 mNumSignal = 0; 204 } 205 signal()206 public synchronized void signal() { 207 mNumSignal++; 208 notifyAll(); 209 } 210 waitForSignal()211 public synchronized boolean waitForSignal() throws InterruptedException { 212 return waitForCountedSignals(1) > 0; 213 } 214 waitForCountedSignals(int targetCount)215 public synchronized int waitForCountedSignals(int targetCount) throws InterruptedException { 216 while (mNumSignal < targetCount) { 217 wait(); 218 } 219 return mNumSignal; 220 } 221 waitForSignal(long timeoutMs)222 public synchronized boolean waitForSignal(long timeoutMs) throws InterruptedException { 223 return waitForCountedSignals(1, timeoutMs) > 0; 224 } 225 waitForCountedSignals(int targetCount, long timeoutMs)226 public synchronized int waitForCountedSignals(int targetCount, long timeoutMs) 227 throws InterruptedException { 228 if (timeoutMs == 0) { 229 return waitForCountedSignals(targetCount); 230 } 231 long deadline = System.currentTimeMillis() + timeoutMs; 232 while (mNumSignal < targetCount) { 233 long delay = deadline - System.currentTimeMillis(); 234 if (delay <= 0) { 235 break; 236 } 237 wait(delay); 238 } 239 return mNumSignal; 240 } 241 isSignalled()242 public synchronized boolean isSignalled() { 243 return mNumSignal >= 1; 244 } 245 getNumSignal()246 public synchronized int getNumSignal() { 247 return mNumSignal; 248 } 249 } 250 } 251