@UiThread
 private void updatePlayPauseIcon(@PlayerState.PlayState String playStatus) {
   playPauseButton.setImageResource(
       (PlayerState.PLAY_STATE_PLAY.equals(playStatus))
           ? mActivity.getAttributeValue(R.attr.ic_action_av_pause)
           : mActivity.getAttributeValue(R.attr.ic_action_av_play));
 }
  @MainThread
  public void onEventMainThread(HandshakeComplete event) {
    // Event might arrive before this fragment has connected to the service (e.g.,
    // the activity connected before this fragment did).
    // XXX: Verify that this is possible, since the fragment can't register for events
    // until it's connected to the service.
    if (mService == null) {
      return;
    }

    Log.d(TAG, "Handshake complete");

    dismissConnectingDialog();

    if (mFullHeightLayout) {
      nextButton.setEnabled(true);
      prevButton.setEnabled(true);
      shuffleButton.setEnabled(true);
      repeatButton.setEnabled(true);

      nextButton.setImageResource(mActivity.getAttributeValue(R.attr.ic_action_av_next));
      prevButton.setImageResource(mActivity.getAttributeValue(R.attr.ic_action_av_previous));
      seekBar.setEnabled(true);
    } else {
      mProgressBar.setEnabled(true);
    }

    PlayerState playerState = getPlayerState();

    // May be no players connected.
    // TODO: These views should be cleared if there's no player connected.
    if (playerState == null) return;

    updateUiFromPlayerState(playerState);
  }
  @MainThread
  public void onEventMainThread(ConnectionChanged event) {
    Log.d(TAG, "ConnectionChanged: " + event);

    // The fragment may no longer be attached to the parent activity.  If so, do nothing.
    if (!isAdded()) {
      return;
    }

    // Handle any of the reasons for disconnection, clear the dialog and show the
    // DisconnectedActivity.
    if (event.connectionState == ConnectionState.DISCONNECTED) {
      dismissConnectingDialog();
      DisconnectedActivity.show(mActivity);
      return;
    }

    if (event.connectionState == ConnectionState.CONNECTION_FAILED) {
      dismissConnectingDialog();
      DisconnectedActivity.showConnectionFailed(mActivity);
      return;
    }

    if (event.connectionState == ConnectionState.LOGIN_FAILED) {
      dismissConnectingDialog();
      DisconnectedActivity.showLoginFailed(mActivity);
      return;
    }

    // Any other event means that a connection is in progress, make sure the dialog is showing.
    showConnectingDialog();

    // Ensure that option menu item state is adjusted as appropriate.
    getActivity().supportInvalidateOptionsMenu();

    playPauseButton.setImageResource(mActivity.getAttributeValue(R.attr.ic_action_av_connect));

    if (mFullHeightLayout) {
      nextButton.setEnabled(false);
      prevButton.setEnabled(false);
      shuffleButton.setEnabled(false);
      repeatButton.setEnabled(false);

      albumArt.setImageResource(R.drawable.icon_album_noart_fullscreen);
      nextButton.setImageResource(0);
      prevButton.setImageResource(0);
      shuffleButton.setImageResource(0);
      repeatButton.setImageResource(0);
      updatePlayerDropDown(Collections.<Player>emptyList(), null);
      artistText.setText(getText(R.string.disconnected_text));
      currentTime.setText("--:--");
      totalTime.setText("--:--");
      seekBar.setEnabled(false);
      seekBar.setProgress(0);
    } else {
      albumArt.setImageResource(R.drawable.icon_album_noart);
      mProgressBar.setEnabled(false);
      mProgressBar.setProgress(0);
    }
  }
  @Override
  public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
      case R.id.menu_item_settings:
        SettingsActivity.show(mActivity);
        return true;
      case R.id.menu_item_search:
        mActivity.onSearchRequested();
        return true;
      case R.id.menu_item_connect:
        onUserInitiatesConnect();
        return true;
      case R.id.menu_item_disconnect:
        mService.disconnect();
        return true;
      case R.id.menu_item_poweron:
        mService.powerOn();
        return true;
      case R.id.menu_item_poweroff:
        mService.powerOff();
        return true;
      case R.id.menu_item_playlist:
        CurrentPlaylistActivity.show(mActivity);
        break;
      case R.id.menu_item_players:
        PlayerListActivity.show(mActivity);
        return true;
      case R.id.menu_item_about:
        new AboutDialog().show(getFragmentManager(), "AboutDialog");
        return true;
    }

    return super.onOptionsItemSelected(item);
  }
  /**
   * Handles clicks on the context menu.
   *
   * <p>{@inheritDoc}
   *
   * @param item
   * @return
   */
  @Override
  public boolean onContextItemSelected(MenuItem item) {
    Song song = getCurrentSong();
    if (song == null || song.isRemote()) {
      return false;
    }

    // Note: Very similar to code in SongView:doItemContext().  Refactor?
    switch (item.getItemId()) {
      case R.id.download:
        mActivity.downloadItem(song);
        return true;

      case R.id.view_this_album:
        SongListActivity.show(getActivity(), song.getAlbum());
        return true;

      case R.id.view_albums_by_song:
        AlbumListActivity.show(getActivity(), new Artist(song.getArtistId(), song.getArtist()));
        return true;

      case R.id.view_songs_by_artist:
        SongListActivity.show(getActivity(), new Artist(song.getArtistId(), song.getArtist()));
        return true;

      default:
        throw new IllegalStateException("Unknown menu ID.");
    }
  }
 @Override
 public void onDestroy() {
   super.onDestroy();
   if (mService != null) {
     mActivity.unbindService(serviceConnection);
   }
 }
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setHasOptionsMenu(true);

    mActivity.bindService(
        new Intent(mActivity, SqueezeService.class), serviceConnection, Context.BIND_AUTO_CREATE);
    Log.d(TAG, "did bindService; serviceStub = " + mService);
  }
  @Override
  public void onResume() {
    super.onResume();
    Log.d(TAG, "onResume...");

    // Start it and have it run forever (until it shuts itself down).
    // This is required so swapping out the activity (and unbinding the
    // service connection in onDestroy) doesn't cause the service to be
    // killed due to zero refcount.  This is our signal that we want
    // it running in the background.
    mActivity.startService(new Intent(mActivity, SqueezeService.class));

    if (mService != null) {
      maybeRegisterCallbacks(mService);
    }

    if (new Preferences(mActivity).isAutoConnect()) {
      mActivity.registerReceiver(
          broadcastReceiver, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
    }
  }
 @MainThread
 public void onEventMainThread(ShuffleStatusChanged event) {
   if (event.player.equals(mService.getActivePlayer())) {
     updateShuffleStatus(event.shuffleStatus);
     if (!event.initial) {
       Toast.makeText(
               mActivity,
               mActivity.getServerString(event.shuffleStatus.getText()),
               Toast.LENGTH_SHORT)
           .show();
     }
   }
 }
  /**
   * @see android.support.v4.app.Fragment#onCreateOptionsMenu(android.view.Menu,
   *     android.view.MenuInflater)
   */
  @Override
  public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    // I confess that I don't understand why using the inflater passed as
    // an argument here doesn't work -- but if you do it crashes without
    // a stracktrace on API 7.
    MenuInflater i = mActivity.getMenuInflater();
    i.inflate(R.menu.now_playing_fragment, menu);

    menu_item_connect = menu.findItem(R.id.menu_item_connect);
    menu_item_disconnect = menu.findItem(R.id.menu_item_disconnect);
    menu_item_poweron = menu.findItem(R.id.menu_item_poweron);
    menu_item_poweroff = menu.findItem(R.id.menu_item_poweroff);
    menu_item_players = menu.findItem(R.id.menu_item_players);
    menu_item_playlists = menu.findItem(R.id.menu_item_playlist);
    menu_item_search = menu.findItem(R.id.menu_item_search);
  }
  @Override
  public void onPause() {
    Log.d(TAG, "onPause...");

    dismissConnectingDialog();

    if (new Preferences(mActivity).isAutoConnect()) {
      mActivity.unregisterReceiver(broadcastReceiver);
    }

    if (mRegisteredCallbacks) {
      mService.cancelSubscriptions(this);
      mService.getEventBus().unregister(this);
      mRegisteredCallbacks = false;
    }

    super.onPause();
  }
  public void startVisibleConnection() {
    Log.v(TAG, "startVisibleConnection");
    if (mService == null) {
      return;
    }

    Preferences preferences = new Preferences(mActivity);

    // If we are configured to automatically connect on Wi-Fi availability
    // we will also give the user the opportunity to enable Wi-Fi
    if (preferences.isAutoConnect()) {
      WifiManager wifiManager = (WifiManager) mActivity.getSystemService(Context.WIFI_SERVICE);
      if (!wifiManager.isWifiEnabled()) {
        FragmentManager fragmentManager = getFragmentManager();
        if (fragmentManager != null) {
          EnableWifiDialog.show(getFragmentManager());
        } else {
          Log.i(getTag(), "fragment manager is null so we can't show EnableWifiDialog");
        }
        return;
        // When a Wi-Fi connection is made this method will be called again by the
        // broadcastReceiver
      }
    }

    Preferences.ServerAddress serverAddress = preferences.getServerAddress();
    String ipPort = serverAddress.address;
    if (ipPort == null) {
      // Set up a server connection, if it is not present
      DisconnectedActivity.show(mActivity);
      return;
    }

    if (isConnectInProgress()) {
      Log.v(TAG, "Connection is already in progress, connecting aborted");
      return;
    }
    Log.v(TAG, "startConnect, ipPort: " + ipPort);
    mService.startConnect(
        ipPort,
        preferences.getUserName(serverAddress, "test"),
        preferences.getPassword(serverAddress, "test1"));
  }
  /**
   * Manages the list of connected players in the action bar.
   *
   * @param players A list of players to show. May be empty (use {@code
   *     Collections.&lt;Player>emptyList()}) but not null.
   * @param activePlayer The currently active player. May be null.
   */
  @UiThread
  private void updatePlayerDropDown(
      @NonNull Collection<Player> players, @Nullable Player activePlayer) {
    if (!isAdded()) {
      return;
    }

    // Only include players that are connected to the server.
    ArrayList<Player> connectedPlayers = new ArrayList<Player>();
    for (Player player : players) {
      if (player.getConnected()) {
        connectedPlayers.add(player);
      }
    }

    ActionBar actionBar = mActivity.getSupportActionBar();

    // If there are multiple players connected then show a spinner allowing the user to
    // choose between them.
    if (connectedPlayers.size() > 1) {
      actionBar.setDisplayShowTitleEnabled(false);
      actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
      final ArrayAdapter<Player> playerAdapter =
          new ArrayAdapter<Player>(
              actionBar.getThemedContext(),
              android.R.layout.simple_spinner_dropdown_item,
              connectedPlayers) {
            @Override
            public View getDropDownView(int position, View convertView, ViewGroup parent) {
              return Util.getActionBarSpinnerItemView(
                  getContext(), convertView, parent, getItem(position).getName());
            }

            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
              return Util.getActionBarSpinnerItemView(
                  getContext(), convertView, parent, getItem(position).getName());
            }
          };
      actionBar.setListNavigationCallbacks(
          playerAdapter,
          new ActionBar.OnNavigationListener() {
            @Override
            public boolean onNavigationItemSelected(int position, long id) {
              if (!playerAdapter.getItem(position).equals(mService.getActivePlayer())) {
                Log.i(
                    TAG,
                    "onNavigationItemSelected.setActivePlayer("
                        + playerAdapter.getItem(position)
                        + ")");
                mService.setActivePlayer(playerAdapter.getItem(position));
                updateUiFromPlayerState(mService.getActivePlayerState());
              }
              return true;
            }
          });
      if (activePlayer != null) {
        actionBar.setSelectedNavigationItem(playerAdapter.getPosition(activePlayer));
      }
    } else {
      // 0 or 1 players, disable the spinner, and either show the sole player in the
      // action bar, or the app name if there are no players.
      actionBar.setDisplayShowTitleEnabled(true);
      actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);

      if (connectedPlayers.size() == 1) {
        actionBar.setTitle(connectedPlayers.get(0).getName());
      } else {
        // TODO: Alert the user if there are no connected players.
        actionBar.setTitle(R.string.app_name);
      }
    }
  }
 @UiThread
 private void updateRepeatStatus(RepeatStatus repeatStatus) {
   if (mFullHeightLayout && repeatStatus != null) {
     repeatButton.setImageResource(mActivity.getAttributeValue(repeatStatus.getIcon()));
   }
 }
 @UiThread
 private void updateShuffleStatus(ShuffleStatus shuffleStatus) {
   if (mFullHeightLayout && shuffleStatus != null) {
     shuffleButton.setImageResource(mActivity.getAttributeValue(shuffleStatus.getIcon()));
   }
 }