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.media.cts; 18 19 import android.media.audiofx.AudioEffect; 20 import android.media.AudioFormat; 21 import android.media.AudioManager; 22 import android.media.audiofx.PresetReverb; 23 import android.os.Looper; 24 import android.platform.test.annotations.AppModeFull; 25 import android.test.AndroidTestCase; 26 import android.util.Log; 27 28 @AppModeFull(reason = "TODO: evaluate and port to instant") 29 public class PresetReverbTest extends PostProcTestBase { 30 31 private String TAG = "PresetReverbTest"; 32 private final static short FIRST_PRESET = PresetReverb.PRESET_NONE; 33 private final static short LAST_PRESET = PresetReverb.PRESET_PLATE; 34 private final static int MAX_LOOPER_WAIT_COUNT = 10; 35 36 private PresetReverb mReverb = null; 37 private PresetReverb mReverb2 = null; 38 private ListenerThread mEffectListenerLooper = null; 39 40 //----------------------------------------------------------------- 41 // PRESET REVERB TESTS: 42 //---------------------------------- 43 44 //----------------------------------------------------------------- 45 // 0 - constructor 46 //---------------------------------- 47 48 //Test case 0.0: test constructor and release 49 public void test0_0ConstructorAndRelease() throws Exception { 50 if (!isPresetReverbAvailable()) { 51 return; 52 } 53 PresetReverb reverb = null; 54 try { 55 reverb = new PresetReverb(0, 0); 56 try { 57 assertTrue("invalid effect ID", (reverb.getId() != 0)); 58 } catch (IllegalStateException e) { 59 fail("PresetReverb not initialized"); 60 } 61 } catch (IllegalArgumentException e) { 62 fail("PresetReverb not found"); 63 } catch (UnsupportedOperationException e) { 64 fail("Effect library not loaded"); 65 } finally { 66 if (reverb != null) { 67 reverb.release(); 68 } 69 } 70 } 71 72 //----------------------------------------------------------------- 73 // 1 - get/set parameters 74 //---------------------------------- 75 76 //Test case 1.0: test presets 77 public void test1_0Presets() throws Exception { 78 if (!isPresetReverbAvailable()) { 79 return; 80 } 81 getReverb(0); 82 try { 83 for (short preset = FIRST_PRESET; 84 preset <= LAST_PRESET; 85 preset++) { 86 mReverb.setPreset(preset); 87 assertEquals("got incorrect preset", preset, mReverb.getPreset()); 88 } 89 } catch (IllegalArgumentException e) { 90 fail("Bad parameter value"); 91 } catch (UnsupportedOperationException e) { 92 fail("get parameter() rejected"); 93 } catch (IllegalStateException e) { 94 fail("get parameter() called in wrong state"); 95 } finally { 96 releaseReverb(); 97 } 98 } 99 100 //Test case 1.1: test properties 101 public void test1_1Properties() throws Exception { 102 if (!isPresetReverbAvailable()) { 103 return; 104 } 105 getReverb(0); 106 try { 107 PresetReverb.Settings settings = mReverb.getProperties(); 108 String str = settings.toString(); 109 settings = new PresetReverb.Settings(str); 110 short preset = (settings.preset == PresetReverb.PRESET_SMALLROOM) ? 111 PresetReverb.PRESET_MEDIUMROOM : PresetReverb.PRESET_SMALLROOM; 112 settings.preset = preset; 113 mReverb.setProperties(settings); 114 settings = mReverb.getProperties(); 115 assertEquals("setProperties failed", settings.preset, preset); 116 } catch (IllegalArgumentException e) { 117 fail("Bad parameter value"); 118 } catch (UnsupportedOperationException e) { 119 fail("get parameter() rejected"); 120 } catch (IllegalStateException e) { 121 fail("get parameter() called in wrong state"); 122 } finally { 123 releaseReverb(); 124 } 125 } 126 127 //----------------------------------------------------------------- 128 // 2 - Effect enable/disable 129 //---------------------------------- 130 131 //Test case 2.0: test setEnabled() and getEnabled() in valid state 132 public void test2_0SetEnabledGetEnabled() throws Exception { 133 if (!isPresetReverbAvailable()) { 134 return; 135 } 136 getReverb(0); 137 try { 138 mReverb.setEnabled(true); 139 assertTrue("invalid state from getEnabled", mReverb.getEnabled()); 140 mReverb.setEnabled(false); 141 assertFalse("invalid state to getEnabled", mReverb.getEnabled()); 142 } catch (IllegalStateException e) { 143 fail("setEnabled() in wrong state"); 144 } finally { 145 releaseReverb(); 146 } 147 } 148 149 //Test case 2.1: test setEnabled() throws exception after release 150 public void test2_1SetEnabledAfterRelease() throws Exception { 151 if (!isPresetReverbAvailable()) { 152 return; 153 } 154 getReverb(0); 155 mReverb.release(); 156 try { 157 mReverb.setEnabled(true); 158 } catch (IllegalStateException e) { 159 // test passed 160 } finally { 161 releaseReverb(); 162 } 163 } 164 165 //----------------------------------------------------------------- 166 // 3 priority and listeners 167 //---------------------------------- 168 169 //Test case 3.0: test control status listener 170 public void test3_0ControlStatusListener() throws Exception { 171 if (!isPresetReverbAvailable()) { 172 return; 173 } 174 synchronized(mLock) { 175 mHasControl = true; 176 mInitialized = false; 177 createListenerLooper(true, false, false); 178 waitForLooperInitialization_l(); 179 180 getReverb(0); 181 int looperWaitCount = MAX_LOOPER_WAIT_COUNT; 182 while (mHasControl && (looperWaitCount-- > 0)) { 183 try { 184 mLock.wait(); 185 } catch(Exception e) { 186 } 187 } 188 terminateListenerLooper(); 189 releaseReverb(); 190 } 191 assertFalse("effect control not lost by effect1", mHasControl); 192 } 193 194 //Test case 3.1: test enable status listener 195 public void test3_1EnableStatusListener() throws Exception { 196 if (!isPresetReverbAvailable()) { 197 return; 198 } 199 synchronized(mLock) { 200 mInitialized = false; 201 createListenerLooper(false, true, false); 202 waitForLooperInitialization_l(); 203 204 mReverb2.setEnabled(true); 205 mIsEnabled = true; 206 getReverb(0); 207 mReverb.setEnabled(false); 208 int looperWaitCount = MAX_LOOPER_WAIT_COUNT; 209 while (mIsEnabled && (looperWaitCount-- > 0)) { 210 try { 211 mLock.wait(); 212 } catch(Exception e) { 213 } 214 } 215 terminateListenerLooper(); 216 releaseReverb(); 217 } 218 assertFalse("enable status not updated", mIsEnabled); 219 } 220 221 //Test case 3.2: test parameter changed listener 222 public void test3_2ParameterChangedListener() throws Exception { 223 if (!isPresetReverbAvailable()) { 224 return; 225 } 226 synchronized(mLock) { 227 mInitialized = false; 228 createListenerLooper(false, false, true); 229 waitForLooperInitialization_l(); 230 231 getReverb(0); 232 mChangedParameter = -1; 233 mReverb.setPreset(PresetReverb.PRESET_SMALLROOM); 234 235 int looperWaitCount = MAX_LOOPER_WAIT_COUNT; 236 while ((mChangedParameter == -1) && (looperWaitCount-- > 0)) { 237 try { 238 mLock.wait(); 239 } catch(Exception e) { 240 } 241 } 242 terminateListenerLooper(); 243 releaseReverb(); 244 } 245 assertEquals("parameter change not received", 246 PresetReverb.PARAM_PRESET, mChangedParameter); 247 } 248 249 //----------------------------------------------------------------- 250 // private methods 251 //---------------------------------- 252 253 private void getReverb(int session) { 254 if (mReverb == null || session != mSession) { 255 if (session != mSession && mReverb != null) { 256 mReverb.release(); 257 mReverb = null; 258 } 259 try { 260 mReverb = new PresetReverb(0, session); 261 mSession = session; 262 } catch (IllegalArgumentException e) { 263 Log.e(TAG, "getReverb() PresetReverb not found exception: "+e); 264 } catch (UnsupportedOperationException e) { 265 Log.e(TAG, "getReverb() Effect library not loaded exception: "+e); 266 } 267 } 268 assertNotNull("could not create mReverb", mReverb); 269 } 270 271 private void releaseReverb() { 272 if (mReverb != null) { 273 mReverb.release(); 274 mReverb = null; 275 } 276 } 277 278 private void waitForLooperInitialization_l() { 279 int looperWaitCount = MAX_LOOPER_WAIT_COUNT; 280 while (!mInitialized && (looperWaitCount-- > 0)) { 281 try { 282 mLock.wait(); 283 } catch(Exception e) { 284 } 285 } 286 assertTrue(mInitialized); 287 } 288 289 // Initializes the reverb listener looper 290 class ListenerThread extends Thread { 291 boolean mControl; 292 boolean mEnable; 293 boolean mParameter; 294 295 public ListenerThread(boolean control, boolean enable, boolean parameter) { 296 super(); 297 mControl = control; 298 mEnable = enable; 299 mParameter = parameter; 300 } 301 302 public void cleanUp() { 303 if (mReverb2 != null) { 304 mReverb2.setControlStatusListener(null); 305 mReverb2.setEnableStatusListener(null); 306 mReverb2.setParameterListener( 307 (PresetReverb.OnParameterChangeListener)null); 308 } 309 } 310 } 311 312 private void createListenerLooper(boolean control, boolean enable, boolean parameter) { 313 mEffectListenerLooper = new ListenerThread(control, enable, parameter) { 314 @Override 315 public void run() { 316 // Set up a looper 317 Looper.prepare(); 318 319 // Save the looper so that we can terminate this thread 320 // after we are done with it. 321 mLooper = Looper.myLooper(); 322 323 mReverb2 = new PresetReverb(0, 0); 324 assertNotNull("could not create Reverb2", mReverb2); 325 326 synchronized(mLock) { 327 if (mControl) { 328 mReverb2.setControlStatusListener( 329 new AudioEffect.OnControlStatusChangeListener() { 330 public void onControlStatusChange( 331 AudioEffect effect, boolean controlGranted) { 332 synchronized(mLock) { 333 if (effect == mReverb2) { 334 mHasControl = controlGranted; 335 mLock.notify(); 336 } 337 } 338 } 339 }); 340 } 341 if (mEnable) { 342 mReverb2.setEnableStatusListener( 343 new AudioEffect.OnEnableStatusChangeListener() { 344 public void onEnableStatusChange(AudioEffect effect, boolean enabled) { 345 synchronized(mLock) { 346 if (effect == mReverb2) { 347 mIsEnabled = enabled; 348 mLock.notify(); 349 } 350 } 351 } 352 }); 353 } 354 if (mParameter) { 355 mReverb2.setParameterListener(new PresetReverb.OnParameterChangeListener() { 356 public void onParameterChange(PresetReverb effect, 357 int status, int param, short value) 358 { 359 synchronized(mLock) { 360 if (effect == mReverb2) { 361 mChangedParameter = param; 362 mLock.notify(); 363 } 364 } 365 } 366 }); 367 } 368 369 mInitialized = true; 370 mLock.notify(); 371 } 372 Looper.loop(); // Blocks forever until Looper.quit() is called. 373 } 374 }; 375 mEffectListenerLooper.start(); 376 } 377 378 // Terminates the listener looper thread. 379 private void terminateListenerLooper() { 380 if (mEffectListenerLooper != null) { 381 mEffectListenerLooper.cleanUp(); 382 if (mLooper != null) { 383 mLooper.quit(); 384 mLooper = null; 385 } 386 try { 387 mEffectListenerLooper.join(); 388 } catch(InterruptedException e) { 389 } 390 mEffectListenerLooper = null; 391 } 392 393 if (mReverb2 != null) { 394 mReverb2.release(); 395 mReverb2 = null; 396 } 397 } 398 }