diff --git a/ultrasonic/src/main/java/org/moire/ultrasonic/activity/DownloadActivity.java b/ultrasonic/src/main/java/org/moire/ultrasonic/activity/DownloadActivity.java index fdd68673..7c9c8057 100644 --- a/ultrasonic/src/main/java/org/moire/ultrasonic/activity/DownloadActivity.java +++ b/ultrasonic/src/main/java/org/moire/ultrasonic/activity/DownloadActivity.java @@ -49,10 +49,14 @@ import android.widget.SeekBar; import android.widget.TextView; import android.widget.ViewFlipper; +import androidx.lifecycle.Observer; + import com.mobeta.android.dslv.DragSortListView; import org.koin.java.KoinJavaComponent; import org.moire.ultrasonic.R; +import org.moire.ultrasonic.audiofx.EqualizerController; +import org.moire.ultrasonic.audiofx.VisualizerController; import org.moire.ultrasonic.data.ActiveServerProvider; import org.moire.ultrasonic.domain.MusicDirectory; import org.moire.ultrasonic.domain.MusicDirectory.Entry; @@ -117,8 +121,6 @@ public class DownloadActivity extends SubsonicTabActivity implements OnGestureLi private int swipeDistance; private int swipeVelocity; private VisualizerView visualizerView; - private boolean visualizerAvailable; - private boolean equalizerAvailable; private boolean jukeboxAvailable; private SilentBackgroundTask onProgressChangedTask; LinearLayout visualizerViewLayout; @@ -133,6 +135,9 @@ public class DownloadActivity extends SubsonicTabActivity implements OnGestureLi private Drawable hollowStar; private Drawable fullStar; + private boolean isEqualizerAvailable; + private boolean isVisualizerAvailable; + /** * Called when the activity is first created. */ @@ -506,8 +511,55 @@ public class DownloadActivity extends SubsonicTabActivity implements OnGestureLi mediaPlayerController.setShufflePlayEnabled(true); } - visualizerAvailable = (mediaPlayerController != null) && (mediaPlayerController.getVisualizerController() != null); - equalizerAvailable = (mediaPlayerController != null) && (mediaPlayerController.getEqualizerController() != null); + visualizerViewLayout.setVisibility(View.GONE); + VisualizerController.get().observe(this, new Observer() { + @Override + public void onChanged(VisualizerController visualizerController) { + if (visualizerController != null) { + Timber.d("VisualizerController Observer.onChanged received controller"); + visualizerView = new VisualizerView(DownloadActivity.this); + visualizerViewLayout.addView(visualizerView, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT)); + + if (!visualizerView.isActive()) + { + visualizerViewLayout.setVisibility(View.GONE); + } + else + { + visualizerViewLayout.setVisibility(View.VISIBLE); + } + + visualizerView.setOnTouchListener(new View.OnTouchListener() + { + @Override + public boolean onTouch(final View view, final MotionEvent motionEvent) + { + visualizerView.setActive(!visualizerView.isActive()); + getMediaPlayerController().setShowVisualization(visualizerView.isActive()); + return true; + } + }); + isVisualizerAvailable = true; + } else { + Timber.d("VisualizerController Observer.onChanged has no controller"); + visualizerViewLayout.setVisibility(View.GONE); + isVisualizerAvailable = false; + } + } + }); + + EqualizerController.get().observe(this, new Observer() { + @Override + public void onChanged(EqualizerController equalizerController) { + if (equalizerController != null) { + Timber.d("EqualizerController Observer.onChanged received controller"); + isEqualizerAvailable = true; + } else { + Timber.d("EqualizerController Observer.onChanged has no controller"); + isEqualizerAvailable = false; + } + } + }); new Thread(new Runnable() { @@ -528,36 +580,6 @@ public class DownloadActivity extends SubsonicTabActivity implements OnGestureLi final View nowPlayingMenuItem = findViewById(R.id.menu_now_playing); menuDrawer.setActiveView(nowPlayingMenuItem); - - if (visualizerAvailable) - { - visualizerView = new VisualizerView(this); - visualizerViewLayout.addView(visualizerView, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT)); - - if (!visualizerView.isActive()) - { - visualizerViewLayout.setVisibility(View.GONE); - } - else - { - visualizerViewLayout.setVisibility(View.VISIBLE); - } - - visualizerView.setOnTouchListener(new View.OnTouchListener() - { - @Override - public boolean onTouch(final View view, final MotionEvent motionEvent) - { - visualizerView.setActive(!visualizerView.isActive()); - getMediaPlayerController().setShowVisualization(visualizerView.isActive()); - return true; - } - }); - } - else - { - visualizerViewLayout.setVisibility(View.GONE); - } } @Override @@ -768,14 +790,14 @@ public class DownloadActivity extends SubsonicTabActivity implements OnGestureLi if (equalizerMenuItem != null) { - equalizerMenuItem.setEnabled(equalizerAvailable); - equalizerMenuItem.setVisible(equalizerAvailable); + equalizerMenuItem.setEnabled(isEqualizerAvailable); + equalizerMenuItem.setVisible(isEqualizerAvailable); } if (visualizerMenuItem != null) { - visualizerMenuItem.setEnabled(visualizerAvailable); - visualizerMenuItem.setVisible(visualizerAvailable); + visualizerMenuItem.setEnabled(isVisualizerAvailable); + visualizerMenuItem.setVisible(isVisualizerAvailable); } final MediaPlayerController mediaPlayerController = getMediaPlayerController(); diff --git a/ultrasonic/src/main/java/org/moire/ultrasonic/activity/EqualizerActivity.java b/ultrasonic/src/main/java/org/moire/ultrasonic/activity/EqualizerActivity.java index 51c39876..c18072b6 100644 --- a/ultrasonic/src/main/java/org/moire/ultrasonic/activity/EqualizerActivity.java +++ b/ultrasonic/src/main/java/org/moire/ultrasonic/activity/EqualizerActivity.java @@ -30,6 +30,8 @@ import android.widget.LinearLayout; import android.widget.SeekBar; import android.widget.TextView; +import androidx.lifecycle.Observer; + import org.moire.ultrasonic.R; import org.moire.ultrasonic.audiofx.EqualizerController; import org.moire.ultrasonic.service.MediaPlayerController; @@ -38,6 +40,7 @@ import java.util.HashMap; import java.util.Map; import kotlin.Lazy; +import timber.log.Timber; import static org.koin.java.KoinJavaComponent.inject; @@ -55,21 +58,34 @@ public class EqualizerActivity extends ResultActivity private EqualizerController equalizerController; private Equalizer equalizer; - private Lazy mediaPlayerControllerLazy = inject(MediaPlayerController.class); - @Override public void onCreate(Bundle bundle) { super.onCreate(bundle); setContentView(R.layout.equalizer); - setup(); + EqualizerController.get().observe(this, new Observer() { + @Override + public void onChanged(EqualizerController controller) { + if (controller != null) { + Timber.d("EqualizerController Observer.onChanged received controller"); + equalizerController = controller; + equalizer = controller.equalizer; + setup(); + } else { + Timber.d("EqualizerController Observer.onChanged has no controller"); + equalizerController = null; + equalizer = null; + } + } + }); } @Override protected void onPause() { super.onPause(); + if (equalizerController == null) return; equalizerController.saveSettings(); } @@ -77,16 +93,13 @@ public class EqualizerActivity extends ResultActivity protected void onResume() { super.onResume(); - if (equalizerController == null) - { - setup(); - } } @Override public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo menuInfo) { super.onCreateContextMenu(menu, view, menuInfo); + if (equalizer == null) return; short currentPreset; try @@ -112,6 +125,7 @@ public class EqualizerActivity extends ResultActivity @Override public boolean onContextItemSelected(MenuItem menuItem) { + if (equalizer == null) return true; try { short preset = (short) menuItem.getItemId(); @@ -128,9 +142,6 @@ public class EqualizerActivity extends ResultActivity private void setup() { - equalizerController = mediaPlayerControllerLazy.getValue().getEqualizerController(); - equalizer = equalizerController.getEqualizer(); - initEqualizer(); final View presetButton = findViewById(R.id.equalizer_preset); @@ -158,12 +169,14 @@ public class EqualizerActivity extends ResultActivity private void setEqualizerEnabled(boolean enabled) { + if (equalizer == null) return; equalizer.setEnabled(enabled); updateBars(); } private void updateBars() { + if (equalizer == null) return; try { for (Map.Entry entry : bars.entrySet()) @@ -183,6 +196,7 @@ public class EqualizerActivity extends ResultActivity private void initEqualizer() { + if (equalizer == null) return; LinearLayout layout = (LinearLayout) findViewById(R.id.equalizer_layout); try diff --git a/ultrasonic/src/main/java/org/moire/ultrasonic/audiofx/EqualizerController.java b/ultrasonic/src/main/java/org/moire/ultrasonic/audiofx/EqualizerController.java index 7381a8c2..96cc3e3d 100644 --- a/ultrasonic/src/main/java/org/moire/ultrasonic/audiofx/EqualizerController.java +++ b/ultrasonic/src/main/java/org/moire/ultrasonic/audiofx/EqualizerController.java @@ -21,6 +21,10 @@ package org.moire.ultrasonic.audiofx; import android.content.Context; import android.media.MediaPlayer; import android.media.audiofx.Equalizer; + +import androidx.lifecycle.LiveData; +import androidx.lifecycle.MutableLiveData; + import timber.log.Timber; import org.moire.ultrasonic.util.FileUtil; @@ -35,61 +39,83 @@ import java.io.Serializable; */ public class EqualizerController { - private final Context context; - private Equalizer equalizer; - private boolean released; + private static Boolean available = null; + private static MutableLiveData instance = new MutableLiveData<>(); + + private Context context; + public Equalizer equalizer; private int audioSessionId; - // Class initialization fails when this throws an exception. - static + /** + * Retrieves the EqualizerController as LiveData + */ + public static LiveData get() { - try - { - Class.forName("android.media.audiofx.Equalizer"); - } - catch (Exception ex) - { - throw new RuntimeException(ex); - } + return instance; } /** - * Throws an exception if the {@link Equalizer} class is not available. + * Initializes the EqualizerController instance with a MediaPlayer */ - public static void checkAvailable() throws Throwable + public static void create(Context context, MediaPlayer mediaPlayer) { - // Calling here forces class initialization. - } + if (mediaPlayer == null) return; + if (!isAvailable()) return; - public EqualizerController(Context context, MediaPlayer mediaPlayer) - { - this.context = context; + EqualizerController controller = new EqualizerController(); + controller.context = context; try { - if (mediaPlayer == null) - { - return; - } + controller.audioSessionId = mediaPlayer.getAudioSessionId(); + controller.equalizer = new Equalizer(0, controller.audioSessionId); + controller.loadSettings(); - audioSessionId = mediaPlayer.getAudioSessionId(); - equalizer = new Equalizer(0, audioSessionId); + instance.postValue(controller); } catch (Throwable x) { - equalizer = null; Timber.w(x, "Failed to create equalizer."); } } - public void saveSettings() + /** + * Releases the EqualizerController instance when the underlying MediaPlayer is no longer available + */ + public static void release() { + EqualizerController controller = instance.getValue(); + if (controller == null) return; + + controller.equalizer.release(); + instance.postValue(null); + } + + /** + * Checks if the {@link Equalizer} class is available. + */ + private static boolean isAvailable() + { + if (available != null) return available; try { - if (isAvailable()) - { - FileUtil.serialize(context, new EqualizerSettings(equalizer), "equalizer.dat"); - } + Class.forName("android.media.audiofx.Equalizer"); + available = true; + } + catch (Exception ex) + { + Timber.i(ex, "CheckAvailable received an exception getting class for the Equalizer"); + available = false; + } + return available; + } + + public void saveSettings() + { + if (!available) return; + try + { + FileUtil.serialize(context, new EqualizerSettings(equalizer), "equalizer.dat"); } catch (Throwable x) { @@ -99,16 +125,14 @@ public class EqualizerController public void loadSettings() { + if (!available) return; try { - if (isAvailable()) - { - EqualizerSettings settings = FileUtil.deserialize(context, "equalizer.dat"); + EqualizerSettings settings = FileUtil.deserialize(context, "equalizer.dat"); - if (settings != null) - { - settings.apply(equalizer); - } + if (settings != null) + { + settings.apply(equalizer); } } catch (Throwable x) @@ -117,46 +141,8 @@ public class EqualizerController } } - public boolean isAvailable() - { - return equalizer != null; - } - - public void release() - { - if (isAvailable()) - { - released = true; - equalizer.release(); - } - } - - public Equalizer getEqualizer() - { - if (released) - { - released = false; - - try - { - equalizer = new Equalizer(0, audioSessionId); - } - catch (Throwable x) - { - equalizer = null; - Timber.w(x, "Failed to create equalizer."); - } - } - - return equalizer; - } - private static class EqualizerSettings implements Serializable { - - /** - * - */ private static final long serialVersionUID = 626565082425206061L; private final short[] bandLevels; private short preset; diff --git a/ultrasonic/src/main/java/org/moire/ultrasonic/audiofx/VisualizerController.java b/ultrasonic/src/main/java/org/moire/ultrasonic/audiofx/VisualizerController.java index 8d14d3ae..c463d44c 100644 --- a/ultrasonic/src/main/java/org/moire/ultrasonic/audiofx/VisualizerController.java +++ b/ultrasonic/src/main/java/org/moire/ultrasonic/audiofx/VisualizerController.java @@ -20,6 +20,10 @@ package org.moire.ultrasonic.audiofx; import android.media.MediaPlayer; import android.media.audiofx.Visualizer; + +import androidx.lifecycle.LiveData; +import androidx.lifecycle.MutableLiveData; + import timber.log.Timber; /** @@ -31,89 +35,76 @@ import timber.log.Timber; public class VisualizerController { private static final int PREFERRED_CAPTURE_SIZE = 128; // Must be a power of two. + private static Boolean available = null; + private static MutableLiveData instance = new MutableLiveData<>(); - private Visualizer visualizer; - private boolean released; + public Visualizer visualizer; private int audioSessionId; - // Class initialization fails when this throws an exception. - static + /** + * Retrieves the VisualizerController as LiveData + */ + public static LiveData get() { - try - { - Class.forName("android.media.audiofx.Visualizer"); - } - catch (Exception ex) - { - throw new RuntimeException(ex); - } + return instance; } /** - * Throws an exception if the {@link Visualizer} class is not available. + * Initializes the VisualizerController instance with a MediaPlayer */ - public static void checkAvailable() throws Throwable + public static void create(MediaPlayer mediaPlayer) { - // Calling here forces class initialization. - } + if (mediaPlayer == null) return; + if (!isAvailable()) return; + + VisualizerController controller = new VisualizerController(); - public VisualizerController(MediaPlayer mediaPlayer) - { try { - if (mediaPlayer == null) - { - return; - } + controller.audioSessionId = mediaPlayer.getAudioSessionId(); + controller.visualizer = new Visualizer(controller.audioSessionId); - audioSessionId = mediaPlayer.getAudioSessionId(); - visualizer = new Visualizer(audioSessionId); + int[] captureSizeRange = Visualizer.getCaptureSizeRange(); + int captureSize = Math.max(PREFERRED_CAPTURE_SIZE, captureSizeRange[0]); + captureSize = Math.min(captureSize, captureSizeRange[1]); + controller.visualizer.setCaptureSize(captureSize); + + instance.postValue(controller); } catch (Throwable x) { Timber.w(x, "Failed to create visualizer."); } - - if (visualizer != null) - { - int[] captureSizeRange = Visualizer.getCaptureSizeRange(); - int captureSize = Math.max(PREFERRED_CAPTURE_SIZE, captureSizeRange[0]); - captureSize = Math.min(captureSize, captureSizeRange[1]); - visualizer.setCaptureSize(captureSize); - } } - public boolean isAvailable() + /** + * Releases the VisualizerController instance when the underlying MediaPlayer is no longer available + */ + public static void release() { - return visualizer != null; + VisualizerController controller = instance.getValue(); + if (controller == null) return; + + controller.visualizer.release(); + instance.postValue(null); } - public void release() + /** + * Checks if the {@link Visualizer} class is available. + */ + private static boolean isAvailable() { - if (isAvailable()) + if (available != null) return available; + try { - visualizer.release(); - released = true; + Class.forName("android.media.audiofx.Visualizer"); + available = true; } - } - - public Visualizer getVisualizer() - { - if (released) + catch (Exception ex) { - released = false; - - try - { - visualizer = new Visualizer(audioSessionId); - } - catch (Throwable x) - { - visualizer = null; - Timber.w(x, "Failed to create visualizer."); - } + Timber.i(ex, "CheckAvailable received an exception getting class for the Visualizer"); + available = false; } - - return visualizer; + return available; } } \ No newline at end of file diff --git a/ultrasonic/src/main/java/org/moire/ultrasonic/service/LocalMediaPlayer.java b/ultrasonic/src/main/java/org/moire/ultrasonic/service/LocalMediaPlayer.java index d606928c..a9fc4d0f 100644 --- a/ultrasonic/src/main/java/org/moire/ultrasonic/service/LocalMediaPlayer.java +++ b/ultrasonic/src/main/java/org/moire/ultrasonic/service/LocalMediaPlayer.java @@ -55,9 +55,6 @@ public class LocalMediaPlayer public Runnable onPrepared; public Runnable onNextSongRequested; - public static boolean equalizerAvailable; - public static boolean visualizerAvailable; - public PlayerState playerState = IDLE; public DownloadFile currentPlaying; public DownloadFile nextPlaying; @@ -77,8 +74,6 @@ public class LocalMediaPlayer private AudioManager audioManager; private RemoteControlClient remoteControlClient; - private EqualizerController equalizerController; - private VisualizerController visualizerController; private CancellableTask bufferTask; private PositionCache positionCache; private int secondaryProgress = -1; @@ -86,32 +81,6 @@ public class LocalMediaPlayer private final AudioFocusHandler audioFocusHandler; private final Context context; - static - { - try - { - EqualizerController.checkAvailable(); - equalizerAvailable = true; - } - catch (Throwable t) - { - equalizerAvailable = false; - } - } - - static - { - try - { - VisualizerController.checkAvailable(); - visualizerAvailable = true; - } - catch (Throwable t) - { - visualizerAvailable = false; - } - } - public LocalMediaPlayer(AudioFocusHandler audioFocusHandler, Context context) { this.audioFocusHandler = audioFocusHandler; @@ -164,6 +133,15 @@ public class LocalMediaPlayer } }).start(); + // Create Equalizer and Visualizer on a new thread as this can potentially take some time + new Thread(new Runnable() { + @Override + public void run() { + EqualizerController.create(context, mediaPlayer); + VisualizerController.create(mediaPlayer); + } + }).start(); + PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE); wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, this.getClass().getName()); wakeLock.setReferenceCounted(false); @@ -172,28 +150,6 @@ public class LocalMediaPlayer Util.registerMediaButtonEventReceiver(context, true); setUpRemoteControlClient(); - if (equalizerAvailable) - { - equalizerController = new EqualizerController(context, mediaPlayer); - if (!equalizerController.isAvailable()) - { - equalizerController = null; - } - else - { - equalizerController.loadSettings(); - } - } - - if (visualizerAvailable) - { - visualizerController = new VisualizerController(mediaPlayer); - if (!visualizerController.isAvailable()) - { - visualizerController = null; - } - } - Timber.i("LocalMediaPlayer created"); } @@ -208,6 +164,9 @@ public class LocalMediaPlayer i.putExtra(AudioEffect.EXTRA_PACKAGE_NAME, context.getPackageName()); context.sendBroadcast(i); + EqualizerController.release(); + VisualizerController.release(); + mediaPlayer.release(); if (nextMediaPlayer != null) { @@ -216,16 +175,6 @@ public class LocalMediaPlayer mediaPlayerLooper.quit(); - if (equalizerController != null) - { - equalizerController.release(); - } - - if (visualizerController != null) - { - visualizerController.release(); - } - if (bufferTask != null) { bufferTask.cancel(); @@ -249,36 +198,6 @@ public class LocalMediaPlayer Timber.i("LocalMediaPlayer destroyed"); } - public EqualizerController getEqualizerController() - { - if (equalizerAvailable && equalizerController == null) - { - equalizerController = new EqualizerController(context, mediaPlayer); - if (!equalizerController.isAvailable()) - { - equalizerController = null; - } - else - { - equalizerController.loadSettings(); - } - } - return equalizerController; - } - - public VisualizerController getVisualizerController() - { - if (visualizerAvailable && visualizerController == null) - { - visualizerController = new VisualizerController(mediaPlayer); - if (!visualizerController.isAvailable()) - { - visualizerController = null; - } - } - return visualizerController; - } - public synchronized void setPlayerState(final PlayerState playerState) { Timber.i("%s -> %s (%s)", this.playerState.name(), playerState.name(), currentPlaying); diff --git a/ultrasonic/src/main/java/org/moire/ultrasonic/service/MediaPlayerController.java b/ultrasonic/src/main/java/org/moire/ultrasonic/service/MediaPlayerController.java index ad6eb2e0..de94b05a 100644 --- a/ultrasonic/src/main/java/org/moire/ultrasonic/service/MediaPlayerController.java +++ b/ultrasonic/src/main/java/org/moire/ultrasonic/service/MediaPlayerController.java @@ -93,10 +93,6 @@ public interface MediaPlayerController String getSuggestedPlaylistName(); - EqualizerController getEqualizerController(); - - VisualizerController getVisualizerController(); - boolean isJukeboxEnabled(); boolean isJukeboxAvailable(); diff --git a/ultrasonic/src/main/java/org/moire/ultrasonic/service/MediaPlayerControllerImpl.java b/ultrasonic/src/main/java/org/moire/ultrasonic/service/MediaPlayerControllerImpl.java index 740e9b41..c3201de7 100644 --- a/ultrasonic/src/main/java/org/moire/ultrasonic/service/MediaPlayerControllerImpl.java +++ b/ultrasonic/src/main/java/org/moire/ultrasonic/service/MediaPlayerControllerImpl.java @@ -510,22 +510,6 @@ public class MediaPlayerControllerImpl implements MediaPlayerController return suggestedPlaylistName; } - @Override - public EqualizerController getEqualizerController() - { - MediaPlayerService mediaPlayerService = MediaPlayerService.getRunningInstance(); - if (mediaPlayerService == null) return null; - return localMediaPlayer.getEqualizerController(); - } - - @Override - public VisualizerController getVisualizerController() - { - MediaPlayerService mediaPlayerService = MediaPlayerService.getRunningInstance(); - if (mediaPlayerService == null) return null; - return localMediaPlayer.getVisualizerController(); - } - @Override public boolean isJukeboxEnabled() { diff --git a/ultrasonic/src/main/java/org/moire/ultrasonic/view/VisualizerView.java b/ultrasonic/src/main/java/org/moire/ultrasonic/view/VisualizerView.java index e4cc2cdf..1de45b44 100644 --- a/ultrasonic/src/main/java/org/moire/ultrasonic/view/VisualizerView.java +++ b/ultrasonic/src/main/java/org/moire/ultrasonic/view/VisualizerView.java @@ -25,11 +25,15 @@ import android.graphics.Paint; import android.media.audiofx.Visualizer; import android.view.View; +import androidx.lifecycle.LifecycleOwner; +import androidx.lifecycle.Observer; + import org.moire.ultrasonic.audiofx.VisualizerController; import org.moire.ultrasonic.domain.PlayerState; import org.moire.ultrasonic.service.MediaPlayerController; import kotlin.Lazy; +import timber.log.Timber; import static org.koin.java.KoinJavaComponent.inject; @@ -45,20 +49,35 @@ public class VisualizerView extends View private static final int PREFERRED_CAPTURE_RATE_MILLIHERTZ = 20000; private final Paint paint = new Paint(); + private Lazy mediaPlayerControllerLazy = inject(MediaPlayerController.class); private byte[] data; private float[] points; private boolean active; + private Visualizer visualizer; - private Lazy mediaPlayerControllerLazy = inject(MediaPlayerController.class); - - public VisualizerView(Context context) + public VisualizerView(final Context context) { super(context); paint.setStrokeWidth(2f); paint.setAntiAlias(true); paint.setColor(Color.rgb(0, 153, 204)); + + VisualizerController.get().observe((LifecycleOwner) context, new Observer() { + @Override + public void onChanged(VisualizerController controller) { + if (controller != null) { + Timber.d("VisualizerController Observer.onChanged received controller"); + visualizer = controller.visualizer; + setActive(true); + } else { + Timber.d("VisualizerController Observer.onChanged has no controller"); + visualizer = null; + setActive(false); + } + } + }); } public boolean isActive() @@ -66,15 +85,9 @@ public class VisualizerView extends View return active; } - public void setActive(boolean active) + public void setActive(boolean value) { - this.active = active; - Visualizer visualizer = getVizualizer(); - if (visualizer == null) - { - return; - } - + active = value; int captureRate = Math.min(PREFERRED_CAPTURE_RATE_MILLIHERTZ, Visualizer.getMaxCaptureRate()); if (active) { @@ -94,19 +107,13 @@ public class VisualizerView extends View } else { - visualizer.setDataCaptureListener(null, captureRate, false, false); + if (visualizer != null) visualizer.setDataCaptureListener(null, captureRate, false, false); } - visualizer.setEnabled(active); + if (visualizer != null) visualizer.setEnabled(active); invalidate(); } - private Visualizer getVizualizer() - { - VisualizerController visualizerController = mediaPlayerControllerLazy.getValue().getVisualizerController(); - return visualizerController == null ? null : visualizerController.getVisualizer(); - } - private void updateVisualizer(byte[] waveform) { this.data = waveform;