diff options
Diffstat (limited to 'tests/src')
8 files changed, 610 insertions, 0 deletions
diff --git a/tests/src/com/cyngn/audiofx/PresetParcelTests.java b/tests/src/com/cyngn/audiofx/PresetParcelTests.java new file mode 100644 index 0000000..8ea0c68 --- /dev/null +++ b/tests/src/com/cyngn/audiofx/PresetParcelTests.java @@ -0,0 +1,94 @@ +package com.cyngn.audiofx; + +import android.os.Parcel; +import android.support.test.runner.AndroidJUnit4; +import android.test.AndroidTestCase; +import android.test.suitebuilder.annotation.SmallTest; +import com.cyngn.audiofx.Preset; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Created by roman on 9/29/15. + */ +@RunWith(AndroidJUnit4.class) +public class PresetParcelTests { + + private Preset.PermCustomPreset permPreset; + private Preset.PermCustomPreset permPresetCopy; + private Preset.CustomPreset customPreset; + + @Before + public void setUp() throws Exception { + permPreset = new Preset.PermCustomPreset("test perm preset", new float[]{10, 50, 20, 30, 10000}); + permPresetCopy = new Preset.PermCustomPreset("test perm preset", new float[]{10, 50, 20, 30, 10000}); + customPreset = new Preset.CustomPreset("test custom preset", new float[]{10, 50, 20, 30, 10000}, false); + } + + @Test + public void testPresetsEqual() { + assertNotEquals(permPreset, customPreset); + assertEquals(permPreset, permPresetCopy); + } + + @Test + public void testPresetsFromString() { + final String permPresetTest = permPreset.toString(); + final Preset.PermCustomPreset fromString = Preset.PermCustomPreset.fromString(permPresetTest); + + assertEquals(permPreset, fromString); + } + + @Test + public void testPermPresetParcelable() { + Parcel parcel = Parcel.obtain(); + + // write the parcel + permPreset.writeToParcel(parcel, 0); + + // reset position for reading + parcel.setDataPosition(0); + + // reconstruct object + final Preset.PermCustomPreset fromParcel = Preset.PermCustomPreset.CREATOR.createFromParcel(parcel); + + assertNotNull(fromParcel); + + assertEquals(permPreset.getName(), fromParcel.getName()); + assertPresetLevels(permPreset, fromParcel); + + assertEquals(permPreset, fromParcel); + } + + @Test + public void testCustomPresetParcelable() { + Parcel parcel = Parcel.obtain(); + + // write the parcel + customPreset.writeToParcel(parcel, 0); + + // reset position for reading + parcel.setDataPosition(0); + + // reconstruct object + final Preset.CustomPreset fromParcel = Preset.CustomPreset.CREATOR.createFromParcel(parcel); + + assertNotNull(fromParcel); + + assertEquals(customPreset.getName(), fromParcel.getName()); + assertPresetLevels(customPreset, fromParcel); + assertEquals(customPreset.isLocked(), fromParcel.isLocked()); + + assertEquals(customPreset, fromParcel); + } + + private void assertPresetLevels(Preset p1, Preset p2) { + for(int i = 0; i < p1.getLevels().length; i++) { + assertEquals(p1.getLevels()[i], p2.getLevels()[i], 0); + } + } +} diff --git a/tests/src/com/cyngn/audiofx/eq/EqUtilTests.java b/tests/src/com/cyngn/audiofx/eq/EqUtilTests.java new file mode 100644 index 0000000..bca4b85 --- /dev/null +++ b/tests/src/com/cyngn/audiofx/eq/EqUtilTests.java @@ -0,0 +1,40 @@ +package com.cyngn.audiofx.eq; + +import android.test.suitebuilder.annotation.SmallTest; +import com.cyngn.audiofx.Preset; +import com.cyngn.audiofx.eq.EqUtils; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +/** + * Created by roman on 9/29/15. + */ +public class EqUtilTests { + + private Preset.PermCustomPreset permPreset; + private Preset.PermCustomPreset permPresetCopy; + private Preset.CustomPreset customPreset; + + @Before + public void setUp() throws Exception { + permPreset = new Preset.PermCustomPreset("test perm preset", new float[]{10, 50, 20, 30, 10000}); + permPresetCopy = new Preset.PermCustomPreset("test perm preset", new float[]{10, 50, 20, 30, 10000}); + customPreset = new Preset.CustomPreset("test custom preset", new float[]{10, 50, 20, 30, 10000}, false); + } + + @Test + public void testConvertDecibelsToMillibels() { + final float[] convertedMillibels = EqUtils.convertDecibelsToMillibels(permPreset.getLevels()); + + float[] manualMillibels = new float[permPreset.getLevels().length]; + for (int i = 0; i < manualMillibels.length; i++) { + manualMillibels[i] = permPreset.getLevels()[i] * 100; + } + + for (int i = 0; i < manualMillibels.length; i++) { + Assert.assertEquals(manualMillibels[i], convertedMillibels[i], 0); + } + } + +} diff --git a/tests/src/com/cyngn/audiofx/service/AudioFxServiceTests.java b/tests/src/com/cyngn/audiofx/service/AudioFxServiceTests.java new file mode 100644 index 0000000..1bf531c --- /dev/null +++ b/tests/src/com/cyngn/audiofx/service/AudioFxServiceTests.java @@ -0,0 +1,178 @@ +package com.cyngn.audiofx.service; + +import android.content.Intent; +import android.media.audiofx.AudioEffect; +import android.support.test.InstrumentationRegistry; +import android.support.test.runner.AndroidJUnit4; +import android.test.suitebuilder.annotation.LargeTest; + +import android.util.Log; +import com.cyngn.audiofx.util.BaseAudioFxServiceInstrumentationTest; +import com.cyngn.audiofx.util.TestMediaPlayer; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +import com.cyngn.audiofx.tests.R; + +import static org.junit.Assert.*; + +/** + * Created by roman on 3/1/16. + */ +@RunWith(AndroidJUnit4.class) +public class AudioFxServiceTests extends BaseAudioFxServiceInstrumentationTest { + + private static final String TAG = "AudioFxServiceTests"; + + private static final int SANE_MAX_LOOP_TIME = 1000 * 20; // 20 seconds !? + private static final int LOOP_SLEEP_TIME = 25; + + TestMediaPlayer mPlayer; + + @Before + public void setUp() throws Exception { + mPlayer = new TestMediaPlayer(getContext(), R.raw.testmp3); + assertNotNull(mPlayer); + } + + @After + public void tearDown() throws Exception { + if (mPlayer != null) { + mPlayer.release(); + mPlayer = null; + } + } + + @Test + public void testServiceCreatesEffectsDirect() throws Exception { + setupService(); // this might be reused + + Intent intent = new Intent(getTargetContext(), AudioFxService.class); + intent.setAction(AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION); + intent.putExtra(AudioEffect.EXTRA_AUDIO_SESSION, mPlayer.getAudioSessionId()); + intent.putExtra(AudioEffect.EXTRA_PACKAGE_NAME, getTargetContext().getPackageName()); + + mServiceRule.startService(intent); + Thread.sleep(100); + assertNotNull(mService.getEffect(mPlayer.getAudioSessionId())); + } + + @Test + public void testServiceDestroysEffectsDirect() throws Exception { + testServiceCreatesEffectsDirect(); + + Intent intent = new Intent(getTargetContext(), AudioFxService.class); + intent.setAction(AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION); + intent.putExtra(AudioEffect.EXTRA_AUDIO_SESSION, mPlayer.getAudioSessionId()); + intent.putExtra(AudioEffect.EXTRA_PACKAGE_NAME, getTargetContext().getPackageName()); + + mServiceRule.startService(intent); + + // sleep for 10s to let effects die + Thread.sleep(10100); + assertNull(mService.getEffect(mPlayer.getAudioSessionId())); + } + + @Test + public void testServiceCreatesEffects() throws Exception { + setupService(); + + openFxSession(true); + assertNotNull(mService.getEffect(mPlayer.getAudioSessionId())); + } + + @Test + @LargeTest + public void testServiceDestroysEffects() throws Exception { + testServiceCreatesEffects(); + + closeFxSession(true); + // sleep for 10s to let effects die + assertNull(mService.getEffect(mPlayer.getAudioSessionId())); + } + + @Test + public void testServiceDoesNotDestroyDeferredEffect() throws Exception { + setupService(); + assertNull(mService.getEffect(mPlayer.getAudioSessionId())); + + openFxSession(false); + assertNotNull(mService.getEffect(mPlayer.getAudioSessionId())); + + closeFxSession(false); + // shouldn't go away immediately after we close it + assertNotNull(mService.getEffect(mPlayer.getAudioSessionId())); + + Thread.sleep(8000); + + // it should *still* be there not destroyed + assertNotNull(mService.getEffect(mPlayer.getAudioSessionId())); + + // reopen the session + openFxSession(false); + + // session should still be there + assertNotNull(mService.getEffect(mPlayer.getAudioSessionId())); + + Thread.sleep(10000); + + // it's been more than 10s (deferred destroy time) and we re-opened it, so it should be + // alive still + assertNotNull(mService.getEffect(mPlayer.getAudioSessionId())); + } + + private void openFxSession(boolean block) throws InterruptedException { + InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() { + @Override + public void run() { + Intent intent = new Intent(AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION); + intent.putExtra(AudioEffect.EXTRA_AUDIO_SESSION, mPlayer.getAudioSessionId()); + intent.putExtra(AudioEffect.EXTRA_PACKAGE_NAME, getTargetContext().getPackageName()); + getContext().sendBroadcast(intent); + } + }); + InstrumentationRegistry.getInstrumentation().waitForIdleSync(); + + if (block) { + int cnt = 0; + while (mService.getEffect(mPlayer.getAudioSessionId()) == null + && (cnt * LOOP_SLEEP_TIME < SANE_MAX_LOOP_TIME)) { + cnt++; + Thread.sleep(LOOP_SLEEP_TIME); + } + Log.d(TAG, "took " + (cnt * LOOP_SLEEP_TIME) + "ms to open effect"); + } else { + // TODO have a timeout here for failure based on time limits? + Thread.sleep(300); + } + } + + private void closeFxSession(boolean block) throws InterruptedException { + InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() { + @Override + public void run() { + Intent intent = new Intent(AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION); + intent.putExtra(AudioEffect.EXTRA_AUDIO_SESSION, mPlayer.getAudioSessionId()); + intent.putExtra(AudioEffect.EXTRA_PACKAGE_NAME, getTargetContext().getPackageName()); + getContext().sendBroadcast(intent); + } + }); + InstrumentationRegistry.getInstrumentation().waitForIdleSync(); + + if (block) { + int cnt = 0; + while (mService.getEffect(mPlayer.getAudioSessionId()) != null + && (cnt * LOOP_SLEEP_TIME < SANE_MAX_LOOP_TIME)) { + cnt++; + Thread.sleep(LOOP_SLEEP_TIME); + } + Log.d(TAG, "took " + (cnt * LOOP_SLEEP_TIME) + "ms to close effect"); + } else { + // TODO have a timeout here for failure based on time limits? + Thread.sleep(300); + } + } + +} diff --git a/tests/src/com/cyngn/audiofx/tests/DebugActivity.java b/tests/src/com/cyngn/audiofx/tests/DebugActivity.java new file mode 100644 index 0000000..9c98f59 --- /dev/null +++ b/tests/src/com/cyngn/audiofx/tests/DebugActivity.java @@ -0,0 +1,87 @@ +package com.cyngn.audiofx.tests; + +import android.media.AudioManager; +import android.media.AudioSystem; +import android.media.RingtoneManager; +import android.os.AsyncTask; +import android.util.Log; + +import com.cyngn.audiofx.util.TestDuckingMediaPlayer; + +/** + * Created by roman on 3/8/16. + */ +public class DebugActivity extends TestActivity { + + @Override + protected String tag() { + return DebugActivity.class.getSimpleName(); + } + + @Override + protected Test[] tests() { + return new Test[]{ + testAudioDucking() + }; + } + + private Test testAudioDucking() { + return new Test("Test Audio Ducking") { + @Override + protected void run() { + try { + final TestDuckingMediaPlayer songMediaPlayer = new TestDuckingMediaPlayer(getApplication()); + songMediaPlayer.setAudioSessionId(AudioSystem.newAudioSessionId()); + songMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); + songMediaPlayer.setDataSource(getApplication(), + RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE)); + songMediaPlayer.prepare(); + + final TestDuckingMediaPlayer interruptPlayer = new TestDuckingMediaPlayer( + DebugActivity.this, R.raw.testmp3); + + final Integer focusResult = songMediaPlayer.start(AudioManager.AUDIOFOCUS_GAIN); + Log.d(tag(), "requestFocus returns: " + focusResult); + + new AsyncTask<Void, Void, Void>() { + + @Override + protected Void doInBackground(Void... params) { + try { + Thread.sleep(400); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + interruptPlayer.start(AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK); + + try { + Thread.sleep(500); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + interruptPlayer.stop(); + + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + songMediaPlayer.stop(); + + interruptPlayer.release(); + songMediaPlayer.release(); + + return null; + } + }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null); + } catch (Exception e) { + e.printStackTrace(); + finish(); + } + } + }; + } +} diff --git a/tests/src/com/cyngn/audiofx/tests/TestActivity.java b/tests/src/com/cyngn/audiofx/tests/TestActivity.java new file mode 100644 index 0000000..61a6b34 --- /dev/null +++ b/tests/src/com/cyngn/audiofx/tests/TestActivity.java @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.cyngn.audiofx.tests; + +import android.app.ListActivity; +import android.os.Bundle; +import android.view.View; +import android.widget.ArrayAdapter; +import android.widget.ListView; + +public abstract class TestActivity extends ListActivity +{ + Test[] mTests; + + protected abstract String tag(); + protected abstract Test[] tests(); + + protected abstract class Test { + protected String name; + protected Test(String n) { + name = n; + } + protected abstract void run(); + } + + @Override + public void onCreate(Bundle icicle) { + super.onCreate(icicle); + + mTests = tests(); + + String[] labels = new String[mTests.length]; + for (int i=0; i<mTests.length; i++) { + labels[i] = mTests[i].name; + } + + setListAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, labels)); + } + + @Override + public void onListItemClick(ListView l, View v, int position, long id) + { + Test t = mTests[position]; + android.util.Log.d(tag(), "Test: " + t.name); + t.run(); + } + +}
\ No newline at end of file diff --git a/tests/src/com/cyngn/audiofx/util/BaseAudioFxServiceInstrumentationTest.java b/tests/src/com/cyngn/audiofx/util/BaseAudioFxServiceInstrumentationTest.java new file mode 100644 index 0000000..e882c9d --- /dev/null +++ b/tests/src/com/cyngn/audiofx/util/BaseAudioFxServiceInstrumentationTest.java @@ -0,0 +1,59 @@ +package com.cyngn.audiofx.util; + +import android.content.Context; +import android.content.Intent; +import android.media.audiofx.AudioEffect; +import android.os.IBinder; +import android.support.test.InstrumentationRegistry; +import android.support.test.rule.ServiceTestRule; +import android.support.test.runner.AndroidJUnit4; +import com.cyngn.audiofx.service.AudioFxService; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.util.concurrent.TimeoutException; + +import static org.junit.Assert.*; + +/** + * Created by roman on 3/1/16. + */ +@RunWith(AndroidJUnit4.class) +public abstract class BaseAudioFxServiceInstrumentationTest { + + private static final int MAX_ITERATION = 100; + + protected AudioFxService.LocalBinder mService; + + @Rule + public ServiceTestRule mServiceRule = new ServiceTestRule(); + + protected void setupService() throws TimeoutException { + int it = 0; + + /** + * lol + * https://code.google.com/p/android/issues/detail?id=180396 + */ + IBinder binder; + while((binder = mServiceRule.bindService( + new Intent(InstrumentationRegistry.getTargetContext(), + AudioFxService.class))) == null && it < MAX_ITERATION){ + it++; + } + mService = (AudioFxService.LocalBinder) binder; + assertNotNull(mService); + } + + protected final Context getContext() { + return InstrumentationRegistry.getContext(); + } + + protected final Context getTargetContext() { + return InstrumentationRegistry.getTargetContext(); + } + +} diff --git a/tests/src/com/cyngn/audiofx/util/TestDuckingMediaPlayer.java b/tests/src/com/cyngn/audiofx/util/TestDuckingMediaPlayer.java new file mode 100644 index 0000000..fc67cc2 --- /dev/null +++ b/tests/src/com/cyngn/audiofx/util/TestDuckingMediaPlayer.java @@ -0,0 +1,59 @@ +package com.cyngn.audiofx.util; + +import android.content.Context; +import android.media.AudioManager; +import android.util.Log; + +import com.cyngn.audiofx.tests.R; + +import static junit.framework.Assert.assertNotNull; + +/** + * Created by roman on 3/4/16. + */ +public class TestDuckingMediaPlayer extends TestMediaPlayer { + + private static final String TAG = TestDuckingMediaPlayer.class.getSimpleName(); + private AudioManager mAudioManager; + + private AudioManager.OnAudioFocusChangeListener mAudioFocusChangeListener + = new AudioManager.OnAudioFocusChangeListener() { + public void onAudioFocusChange(int focusChange) { + Log.i(TAG, "onAudioFocusChange() called with " + "focusChange = [" + focusChange + "]"); + switch(focusChange) { + case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK: + setVolume(0.4f); + break; + + case AudioManager.AUDIOFOCUS_GAIN: + setVolume(1.f); + break; + } + } + }; + + public int start(int focus) throws IllegalStateException { + int result = mAudioManager.requestAudioFocus(mAudioFocusChangeListener, AudioManager.STREAM_MUSIC, + focus); + super.start(); + return result; + } + + @Override + public void stop() throws IllegalStateException { + mAudioManager.abandonAudioFocus(mAudioFocusChangeListener); + super.stop(); + } + + public TestDuckingMediaPlayer(Context context) { + mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); + } + + public TestDuckingMediaPlayer(Context context, int withResource) throws Exception { + super(context, withResource); + mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); + } + + + +} diff --git a/tests/src/com/cyngn/audiofx/util/TestMediaPlayer.java b/tests/src/com/cyngn/audiofx/util/TestMediaPlayer.java new file mode 100644 index 0000000..ef08d1c --- /dev/null +++ b/tests/src/com/cyngn/audiofx/util/TestMediaPlayer.java @@ -0,0 +1,31 @@ +package com.cyngn.audiofx.util; + +import android.content.Context; +import android.content.res.AssetFileDescriptor; +import android.media.AudioAttributes; +import android.media.AudioManager; +import android.media.MediaPlayer; + +import com.cyngn.audiofx.tests.R; + +import static junit.framework.Assert.assertNotNull; + +/** + * Created by roman on 3/4/16. + */ +public class TestMediaPlayer extends MediaPlayer { + + public TestMediaPlayer() { + setAudioStreamType(AudioManager.STREAM_MUSIC); + } + + public TestMediaPlayer(Context testContext, int withResource) throws Exception { + this(); + AssetFileDescriptor afd = testContext.getResources().openRawResourceFd(withResource); + assertNotNull(afd); + setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength()); + afd.close(); + prepare(); + } + +} |