Home | History | Annotate | Download | only in cts
      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 }