Android Open Source - PlayerHater Song Queue






From Project

Back to project page PlayerHater.

License

The source code is released under:

Apache License

If you think the Android project PlayerHater listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/*******************************************************************************
 * Copyright 2013 Chris Rhoden, Rebecca Nesson, Public Radio Exchange
 * //  w  ww  .  j a v a 2 s  .  co m
 * 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 org.prx.playerhater.songs;

import java.util.ArrayList;
import java.util.List;

import org.prx.playerhater.Song;

import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;

public class SongQueue {

  private static Handler sHandler;
  private static final int CURRENT_SONG = 1;
  private static final int NEXT_SONG = 2;

  private static Handler getHandler() {
    if (sHandler == null) {
      HandlerThread thread = new HandlerThread("SongQueue");
      thread.start();
      sHandler = new Handler(thread.getLooper()) {

        @Override
        public void handleMessage(Message msg) {
          SongMessage m = (SongMessage) msg.obj;
          switch (msg.what) {
          case CURRENT_SONG:
            m.queue.sendSongChanged(m.song, m.oldSong);
            break;
          case NEXT_SONG:
            m.queue.sendNextSongChanged(m.song, m.oldSong);
          }
        }

      };
    }
    return sHandler;
  }

  private static class SongMessage {
    private final SongQueue queue;
    private final Song song;
    private final Song oldSong;

    public SongMessage(SongQueue songQueue, Song newSong, Song lastSong) {
      queue = songQueue;
      song = newSong;
      oldSong = lastSong;
    }
  }

  public interface OnQueuedSongsChangedListener {
    public void onNowPlayingChanged(Song nowPlaying, Song nowPlayingWas);

    public void onNextSongChanged(Song nextSong, Song nextSongWas);
  }

  private int mPlayheadPosition = -1;
  private final List<Song> mSongs = new ArrayList<Song>();

  private Song mNextSongWas = null;
  private Song mCurrentSongWas = null;
  private OnQueuedSongsChangedListener mListener;

  public synchronized void setQueuedSongsChangedListener(
      OnQueuedSongsChangedListener listener) {
    mListener = listener;
  }

  public synchronized int appendSong(Song song) {
    return addSongAtPosition(song, mSongs.size() + 1);
  }

  public synchronized int addSongAtPosition(Song song, int position) {
    if (position < 0) {
      throw new IllegalArgumentException("Illegal position: " + position);
    } else if (position == 0) {
      position = 1;
    }
    
    if (position <= getPlayheadPosition()) {
      setPlayheadPosition(getPlayheadPosition() + 1);
    }
    
    mSongs.add(position - 1, song);
    songOrderChanged();
    return mSongs.size() - getPosition();
  }

  public synchronized Song next() {
    setPlayheadPosition(getPlayheadPosition() + 1);
    if (getPlayheadPosition() > size()) {
      setPlayheadPosition(1);
    }
    songOrderChanged();
    return getNowPlaying();
  }

  public synchronized Song back() {
    setPlayheadPosition(getPlayheadPosition() - 1);
    if (getPlayheadPosition() <= 0) {
      setPlayheadPosition(1);
    }
    songOrderChanged();
    return getNowPlaying();
  }

  public synchronized void skipToEnd() {
    setPlayheadPosition(mSongs.size());
    songOrderChanged();
  }

  public synchronized boolean isAtLastSong() {
    return getPlayheadPosition() == mSongs.size();
  }

  public synchronized Song getNowPlaying() {
    if (getPlayheadPosition() <= 0) {
      return null;
    }
    return mSongs.get(getPlayheadPosition() - 1);
  }

  public synchronized Song getNextPlaying() {
    return getNextSong();
  }

  public synchronized void empty() {
    mSongs.clear();
    setPlayheadPosition(-1);
    songOrderChanged();
  }

  private void songOrderChanged() {
    songOrderChanged(true);
  }

  private void songOrderChanged(boolean notify) {
    songOrderChanged(notify, notify);
  }

  private void songOrderChanged(boolean notifyCurrent, boolean notifyNext) {
    if (mSongs.size() > 0) {
      if (getPlayheadPosition() == -1) {
        setPlayheadPosition(1);
      }

      if (mCurrentSongWas == null || mCurrentSongWas != getNowPlaying()) {
        currentSongChanged(notifyCurrent);
      }
      if (mSongs.size() > 1) {
        if (mNextSongWas == null || mNextSongWas != getNextSong()) {
          nextSongChanged(notifyNext);
        }
      } else if (mNextSongWas != null) {
        nextSongChanged(notifyNext);
      }
    } else {
      if (mCurrentSongWas != null) {
        currentSongChanged(notifyCurrent);
      }
      if (mNextSongWas != null) {
        nextSongChanged(notifyNext);
      }
    }
  }

  private void currentSongChanged(boolean notify) {
    if (notify && mListener != null) {
      getHandler().obtainMessage(CURRENT_SONG,
          new SongMessage(this, getNowPlaying(), mCurrentSongWas))
          .sendToTarget();
    }
    mCurrentSongWas = getNowPlaying();
  }

  private void sendSongChanged(Song newSong, Song oldSong) {
    mListener.onNowPlayingChanged(newSong, oldSong);
  }

  private void nextSongChanged(boolean notify) {
    if (notify && mListener != null) {
      getHandler().obtainMessage(NEXT_SONG,
          new SongMessage(this, getNextSong(), mNextSongWas))
          .sendToTarget();
    }
    mNextSongWas = getNextSong();
  }

  private void sendNextSongChanged(Song newNextSong, Song oldNextSong) {
    mListener.onNextSongChanged(newNextSong, oldNextSong);
  }

  private Song getNextSong() {
    if (getPlayheadPosition() >= mSongs.size()
        || getPlayheadPosition() <= 0) {
      return null;
    } else {
      return mSongs.get(getPlayheadPosition());
    }
  }

  public synchronized boolean skipTo(int position) {
    if (position <= mSongs.size()) {
      if (position < 0) {
        return skipTo(mSongs.size() + position + 1);
      }
      setPlayheadPosition(position);
      songOrderChanged();
      return true;
    }
    return false;
  }

  public synchronized int size() {
    return mSongs.size();
  }

  public synchronized boolean remove(int position) {
    if (position < 1 || position > mSongs.size()) {
      return false;
    } else {
      mSongs.remove(position - 1);
      if (position < getPlayheadPosition()) {
        setPlayheadPosition(getPlayheadPosition() - 1);
      }
      if (getPlayheadPosition() >= mSongs.size()) {
        setPlayheadPosition(mSongs.size() >= 1 ? -1 : 1);
      }
      songOrderChanged();
      return true;
    }
  }

  private int getPlayheadPosition() {
    return mPlayheadPosition;
  }

  private void setPlayheadPosition(int playheadPosition) {
    mPlayheadPosition = playheadPosition;
  }

  // XXX Should do some more here.
  public int getPosition() {
    if (getPlayheadPosition() < 0) {
      return 0;
    } else {
      return getPlayheadPosition();
    }
  }

  public void appendAndSkip(Song song) {
    mSongs.add(mSongs.size(), song);
    setPlayheadPosition(mSongs.size());
    songOrderChanged(false, true);
  }
}




Java Source Code List

.AbstractPlugin.java
.AudioFocusPlugin.java
.BackgroundedPlugin.java
.BoundPlayerHater.java
.BroadcastReceiver.java
.ClientPlugin.java
.Config.java
.ExpandableNotificationPlugin.java
.HeadphoneButtonGestureHelper.java
.IPlayerHater.java
.LockScreenControlsPlugin.java
.Log.java
.MediaPlayerPool.java
.NotificationPlugin.java
.OnAudioFocusChangedListener.java
.PebblePlugin.java
.PlaybackService.java
.PlayerHaterClient.java
.PlayerHaterListenerPlugin.java
.PlayerHaterListener.java
.PlayerHaterPlugin.java
.PlayerHaterServer.java
.PlayerHaterService.java
.PlayerHater.java
.PlayerStateWatcher.java
.Player.java
.PlaylistParser.java
.PlaylistSupportingPlayer.java
.PluginCollection.java
.Receiver.java
.RemoteControlButtonReceiver.java
.RemoteSong.java
.ServerPlayerHater.java
.ServicePlayerHater.java
.SongHost.java
.SongQueue.java
.Song.java
.Songs.java
.StatelyPlayer.java
.SynchronousPlayer.java
.ThreadsafePlayerHater.java
.ThreadsafeServicePlayerHater.java
.TouchableNotificationPlugin.java
org.prx.playerhater.BroadcastReceiver.java
org.prx.playerhater.PlaybackService.java
org.prx.playerhater.PlayerHaterListener.java
org.prx.playerhater.PlayerHaterPlugin.java
org.prx.playerhater.PlayerHater.java
org.prx.playerhater.Song.java
org.prx.playerhater.broadcast.HeadphoneButtonGestureHelper.java
org.prx.playerhater.broadcast.OnAudioFocusChangedListener.java
org.prx.playerhater.broadcast.Receiver.java
org.prx.playerhater.broadcast.RemoteControlButtonReceiver.java
org.prx.playerhater.ipc.ClientPlugin.java
org.prx.playerhater.ipc.PlayerHaterClient.java
org.prx.playerhater.ipc.PlayerHaterServer.java
org.prx.playerhater.ipc.ServerPlayerHater.java
org.prx.playerhater.mediaplayer.MediaPlayerPool.java
org.prx.playerhater.mediaplayer.Player.java
org.prx.playerhater.mediaplayer.PlaylistSupportingPlayer.java
org.prx.playerhater.mediaplayer.StatelyPlayer.java
org.prx.playerhater.mediaplayer.SynchronousPlayer.java
org.prx.playerhater.plugins.AbstractPlugin.java
org.prx.playerhater.plugins.AudioFocusPlugin.java
org.prx.playerhater.plugins.BackgroundedPlugin.java
org.prx.playerhater.plugins.ExpandableNotificationPlugin.java
org.prx.playerhater.plugins.LockScreenControlsPlugin.java
org.prx.playerhater.plugins.NotificationPlugin.java
org.prx.playerhater.plugins.PebblePlugin.java
org.prx.playerhater.plugins.PlayerHaterListenerPlugin.java
org.prx.playerhater.plugins.PluginCollection.java
org.prx.playerhater.plugins.ScrubbableLockScreenControlsPlugin.java
org.prx.playerhater.plugins.TouchableNotificationPlugin.java
org.prx.playerhater.service.PlayerHaterService.java
org.prx.playerhater.service.PlayerStateWatcher.java
org.prx.playerhater.songs.RemoteSong.java
org.prx.playerhater.songs.SongHost.java
org.prx.playerhater.songs.SongQueue.java
org.prx.playerhater.songs.Songs.java
org.prx.playerhater.util.Config.java
org.prx.playerhater.util.IPlayerHater.java
org.prx.playerhater.util.Log.java
org.prx.playerhater.util.PlaylistParser.java
org.prx.playerhater.wrappers.BoundPlayerHater.java
org.prx.playerhater.wrappers.ServicePlayerHater.java
org.prx.playerhater.wrappers.ThreadsafePlayerHater.java
org.prx.playerhater.wrappers.ThreadsafeServicePlayerHater.java