2 * Copyright (C) 2014 The CyanogenMod Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 package com.cyanogenmod.eleven.ui.fragments;
18 import android.content.BroadcastReceiver;
19 import android.content.ComponentName;
20 import android.content.Context;
21 import android.content.Intent;
22 import android.content.IntentFilter;
23 import android.content.ServiceConnection;
24 import android.graphics.Outline;
25 import android.media.AudioManager;
26 import android.os.Bundle;
27 import android.os.Handler;
28 import android.os.IBinder;
29 import android.os.Message;
30 import android.os.PowerManager;
31 import android.support.v4.app.Fragment;
32 import android.support.v4.view.ViewPager;
33 import android.text.Html;
34 import android.text.Spanned;
35 import android.text.TextUtils;
36 import android.util.Log;
37 import android.view.ContextMenu;
38 import android.view.LayoutInflater;
39 import android.view.Menu;
40 import android.view.MenuInflater;
41 import android.view.MenuItem;
42 import android.view.View;
43 import android.view.ViewGroup;
44 import android.view.ViewOutlineProvider;
45 import android.widget.ImageView;
46 import android.widget.PopupMenu;
47 import android.widget.TextView;
49 import com.cyanogenmod.eleven.MusicPlaybackService;
50 import com.cyanogenmod.eleven.R;
51 import com.cyanogenmod.eleven.adapters.AlbumArtPagerAdapter;
52 import com.cyanogenmod.eleven.cache.ImageFetcher;
53 import com.cyanogenmod.eleven.loaders.NowPlayingCursor;
54 import com.cyanogenmod.eleven.loaders.QueueLoader;
55 import com.cyanogenmod.eleven.menu.CreateNewPlaylist;
56 import com.cyanogenmod.eleven.menu.DeleteDialog;
57 import com.cyanogenmod.eleven.menu.FragmentMenuItems;
58 import com.cyanogenmod.eleven.ui.activities.HomeActivity;
59 import com.cyanogenmod.eleven.utils.ApolloUtils;
60 import com.cyanogenmod.eleven.utils.MusicUtils;
61 import com.cyanogenmod.eleven.utils.NavUtils;
62 import com.cyanogenmod.eleven.utils.PreferenceUtils;
63 import com.cyanogenmod.eleven.widgets.BrowseButton;
64 import com.cyanogenmod.eleven.widgets.LoadingEmptyContainer;
65 import com.cyanogenmod.eleven.widgets.NoResultsContainer;
66 import com.cyanogenmod.eleven.widgets.PlayPauseProgressButton;
67 import com.cyanogenmod.eleven.widgets.QueueButton;
68 import com.cyanogenmod.eleven.widgets.RepeatButton;
69 import com.cyanogenmod.eleven.widgets.RepeatingImageButton;
70 import com.cyanogenmod.eleven.widgets.ShuffleButton;
71 import com.cyanogenmod.eleven.widgets.VisualizerView;
73 import java.lang.ref.WeakReference;
75 import static com.cyanogenmod.eleven.utils.MusicUtils.mService;
77 public class AudioPlayerFragment extends Fragment implements ServiceConnection {
78 private static final String TAG = AudioPlayerFragment.class.getSimpleName();
81 * Used to keep context menu items from bleeding into other fragments
83 private static final int GROUP_ID = 15;
86 private ViewGroup mRootView;
89 private TextView mSongTitle;
90 private TextView mArtistName;
93 private ImageView mAddToPlaylistButton;
96 private ImageView mMenuButton;
98 // Message to refresh the time
99 private static final int REFRESH_TIME = 1;
102 private MusicUtils.ServiceToken mToken;
104 // Play pause and progress button
105 private PlayPauseProgressButton mPlayPauseProgressButton;
108 private RepeatButton mRepeatButton;
111 private ShuffleButton mShuffleButton;
114 private RepeatingImageButton mPreviousButton;
117 private RepeatingImageButton mNextButton;
119 // Album art ListView
120 private ViewPager mAlbumArtViewPager;
121 private LoadingEmptyContainer mQueueEmpty;
123 private AlbumArtPagerAdapter mAlbumArtPagerAdapter;
126 private TextView mCurrentTime;
129 private TextView mTotalTime;
132 private VisualizerView mVisualizerView;
134 // Broadcast receiver
135 private PlaybackStatus mPlaybackStatus;
137 // Handler used to update the current time
138 private TimeHandler mTimeHandler;
141 private ImageFetcher mImageFetcher;
143 // popup menu for pressing the menu icon
144 private PopupMenu mPopupMenu;
147 private TextView mLyricsText;
149 private long mSelectedId = -1;
151 private boolean mIsPaused = false;
154 public void onActivityCreated(Bundle savedInstanceState) {
155 super.onActivityCreated(savedInstanceState);
157 // Control the media volume
158 getActivity().setVolumeControlStream(AudioManager.STREAM_MUSIC);
160 // Bind Apollo's service
161 mToken = MusicUtils.bindToService(getActivity(), this);
163 // Initialize the image fetcher/cache
164 mImageFetcher = ApolloUtils.getImageFetcher(getActivity());
166 // Initialize the handler used to update the current time
167 mTimeHandler = new TimeHandler(this);
169 // Initialize the broadcast receiver
170 mPlaybackStatus = new PlaybackStatus(this);
177 public View onCreateView(final LayoutInflater inflater, final ViewGroup container,
178 final Bundle savedInstanceState) {
179 // The View for the fragment's UI
180 mRootView = (ViewGroup) inflater.inflate(R.layout.activity_player_fragment, null);
182 // Header title values
185 initPlaybackControls();
187 mVisualizerView = (VisualizerView) mRootView.findViewById(R.id.visualizerView);
188 mVisualizerView.initialize(getActivity());
189 updateVisualizerPowerSaveMode();
191 mLyricsText = (TextView) mRootView.findViewById(R.id.audio_player_lyrics);
200 public void onServiceConnected(final ComponentName name, final IBinder service) {
201 // Set the playback drawables
202 updatePlaybackControls();
204 createAndSetAdapter();
206 updateNowPlayingInfo();
210 public void onServiceDisconnected(ComponentName name) {
214 public void onStart() {
217 final IntentFilter filter = new IntentFilter();
218 // Play and pause changes
219 filter.addAction(MusicPlaybackService.PLAYSTATE_CHANGED);
220 // Shuffle and repeat changes
221 filter.addAction(MusicPlaybackService.SHUFFLEMODE_CHANGED);
222 filter.addAction(MusicPlaybackService.REPEATMODE_CHANGED);
224 filter.addAction(MusicPlaybackService.META_CHANGED);
225 // Update a list, probably the playlist fragment's
226 filter.addAction(MusicPlaybackService.REFRESH);
227 // Listen to changes to the entire queue
228 filter.addAction(MusicPlaybackService.QUEUE_CHANGED);
229 // Listen for lyrics text for the audio track
230 filter.addAction(MusicPlaybackService.NEW_LYRICS);
231 // Listen for power save mode changed
232 filter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED);
233 // Register the intent filters
234 getActivity().registerReceiver(mPlaybackStatus, filter);
235 // Refresh the current time
236 final long next = refreshCurrentTime();
237 queueNextRefresh(next);
239 // resumes the update callback for the play pause progress button
240 mPlayPauseProgressButton.resume();
244 public void onStop() {
247 // pause the update callback for the play pause progress button
248 mPlayPauseProgressButton.pause();
250 mImageFetcher.flush();
254 public void onDestroy() {
258 mTimeHandler.removeMessages(REFRESH_TIME);
259 // Unbind from the service
260 if (mService != null) {
261 MusicUtils.unbindFromService(mToken);
265 // Unregister the receiver
267 getActivity().unregisterReceiver(mPlaybackStatus);
268 } catch (final Throwable e) {
274 * Initializes the header bar
276 private void initHeaderBar() {
277 View headerBar = mRootView.findViewById(R.id.audio_player_header);
278 final int bottomActionBarHeight =
279 getResources().getDimensionPixelSize(R.dimen.bottom_action_bar_height);
281 headerBar.setOutlineProvider(new ViewOutlineProvider() {
283 public void getOutline(View view, Outline outline) {
284 // since we only want the top and bottom shadows, pad the horizontal width
285 // to hide the shadows. Can't seem to find a better way to do this
286 int padWidth = (int)(0.2f * view.getWidth());
287 outline.setRect(-padWidth, -bottomActionBarHeight, view.getWidth() + padWidth,
293 mSongTitle = (TextView) mRootView.findViewById(R.id.header_bar_song_title);
294 mArtistName = (TextView) mRootView.findViewById(R.id.header_bar_artist_title);
298 View v = mRootView.findViewById(R.id.header_bar_search_button);
299 v.setOnClickListener(new View.OnClickListener() {
301 public void onClick(View v) {
302 NavUtils.openSearch(getActivity(), "");
306 // Add to Playlist Button
307 // Setup the playlist button - add a click listener to show the context
308 mAddToPlaylistButton = (ImageView) mRootView.findViewById(R.id.header_bar_add_button);
310 // Create the context menu when requested
311 mAddToPlaylistButton.setOnCreateContextMenuListener(new View.OnCreateContextMenuListener() {
313 public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
314 MusicUtils.makePlaylistMenu(getActivity(), GROUP_ID, menu);
315 menu.setHeaderTitle(R.string.add_to_playlist);
319 // add a click listener to show the context
320 mAddToPlaylistButton.setOnClickListener(new View.OnClickListener() {
322 public void onClick(View v) {
323 // save the current track id
324 mSelectedId = MusicUtils.getCurrentAudioId();
325 mAddToPlaylistButton.showContextMenu();
329 // Add the menu button
331 mMenuButton = (ImageView) mRootView.findViewById(R.id.header_bar_menu_button);
332 mMenuButton.setOnClickListener(new View.OnClickListener() {
334 public void onClick(View v) {
341 * Initializes the items in the now playing screen
343 private void initPlaybackControls() {
344 mPlayPauseProgressButton = (PlayPauseProgressButton)mRootView.findViewById(R.id.playPauseProgressButton);
345 mPlayPauseProgressButton.setDragEnabled(true);
346 mShuffleButton = (ShuffleButton)mRootView.findViewById(R.id.action_button_shuffle);
347 mRepeatButton = (RepeatButton)mRootView.findViewById(R.id.action_button_repeat);
348 mPreviousButton = (RepeatingImageButton)mRootView.findViewById(R.id.action_button_previous);
349 mNextButton = (RepeatingImageButton)mRootView.findViewById(R.id.action_button_next);
351 // Album art view pager
352 mAlbumArtViewPager = (ViewPager)mRootView.findViewById(R.id.audio_player_album_art_viewpager);
353 mAlbumArtViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
355 public void onPageSelected(int position) {
356 super.onPageSelected(position);
358 int currentPosition = 0;
359 if (MusicUtils.getShuffleMode() == MusicPlaybackService.SHUFFLE_NONE) {
360 // if we aren't shuffling, base the position on the queue position
361 currentPosition = MusicUtils.getQueuePosition();
363 // if we are shuffling, use the history size as the position
364 currentPosition = MusicUtils.getQueueHistorySize();
367 // check if we are going to next or previous track
368 if (position - currentPosition == 1) {
369 MusicUtils.asyncNext(getActivity());
370 } else if (position - currentPosition == -1) {
371 MusicUtils.previous(getActivity(), true);
372 } else if (currentPosition != position) {
373 Log.w(TAG, "Unexpected page position of " + position
374 + " when current is: " + currentPosition);
378 // view to show in place of album art if queue is empty
379 mQueueEmpty = (LoadingEmptyContainer)mRootView.findViewById(R.id.loading_empty_container);
380 setupNoResultsContainer(mQueueEmpty.getNoResultsContainer());
383 mCurrentTime = (TextView)mRootView.findViewById(R.id.audio_player_current_time);
385 mTotalTime = (TextView)mRootView.findViewById(R.id.audio_player_total_time);
387 // Set the repeat listener for the previous button
388 mPreviousButton.setRepeatListener(mRewindListener);
389 // Set the repeat listener for the next button
390 mNextButton.setRepeatListener(mFastForwardListener);
392 mPlayPauseProgressButton.enableAndShow();
395 private void setupNoResultsContainer(NoResultsContainer empty) {
396 int color = getResources().getColor(R.color.no_results_light);
397 empty.setTextColor(color);
398 empty.setMainText(R.string.empty_queue_main);
399 empty.setSecondaryText(R.string.empty_queue_secondary);
403 * Sets the track name, album name, and album art.
405 private void updateNowPlayingInfo() {
406 // Set the track name
407 mSongTitle.setText(MusicUtils.getTrackName());
408 mArtistName.setText(MusicUtils.getArtistName());
410 // Set the total time
411 String totalTime = MusicUtils.makeShortTimeString(getActivity(), MusicUtils.duration() / 1000);
412 if (!mTotalTime.getText().equals(totalTime)) {
413 mTotalTime.setText(totalTime);
416 if (MusicUtils.getRepeatMode() == MusicPlaybackService.REPEAT_CURRENT) {
417 // we are repeating 1 so just jump to the 1st and only item
418 mAlbumArtViewPager.setCurrentItem(0, false);
419 } else if (MusicUtils.getShuffleMode() == MusicPlaybackService.SHUFFLE_NONE) {
420 // we are playing in-order, base the position on the queue position
421 mAlbumArtViewPager.setCurrentItem(MusicUtils.getQueuePosition(), true);
423 // if we are shuffling, just based our index based on the history
424 mAlbumArtViewPager.setCurrentItem(MusicUtils.getQueueHistorySize(), true);
427 // Update the current time
432 * This creates the adapter based on the repeat and shuffle configuration and sets it into the
435 private void createAndSetAdapter() {
436 mAlbumArtPagerAdapter = new AlbumArtPagerAdapter(getChildFragmentManager());
438 int repeatMode = MusicUtils.getRepeatMode();
441 int queueSize = MusicUtils.getQueueSize();
443 if (repeatMode == MusicPlaybackService.REPEAT_CURRENT) {
446 } else if (MusicUtils.getShuffleMode() == MusicPlaybackService.SHUFFLE_NONE) {
447 // if we aren't shuffling, use the queue to determine where we are
448 targetSize = queueSize;
449 targetIndex = MusicUtils.getQueuePosition();
451 // otherwise, set it to the max history size
452 targetSize = MusicPlaybackService.MAX_HISTORY_SIZE;
453 targetIndex = MusicUtils.getQueueHistorySize();
456 mAlbumArtPagerAdapter.setPlaylistLength(targetSize);
457 mAlbumArtViewPager.setAdapter(mAlbumArtPagerAdapter);
458 mAlbumArtViewPager.setCurrentItem(targetIndex);
461 mAlbumArtViewPager.setVisibility(View.GONE);
462 mQueueEmpty.showNoResults();
463 mAddToPlaylistButton.setVisibility(View.GONE);
465 mAlbumArtViewPager.setVisibility(View.VISIBLE);
466 mQueueEmpty.hideAll();
467 mAddToPlaylistButton.setVisibility(View.VISIBLE);
472 * Sets the correct drawable states for the playback controls.
474 private void updatePlaybackControls() {
475 // Set the play and pause image
476 mPlayPauseProgressButton.getPlayPauseButton().updateState();
477 // Set the shuffle image
478 mShuffleButton.updateShuffleState();
479 // Set the repeat image
480 mRepeatButton.updateRepeatState();
484 * @param delay When to update
486 private void queueNextRefresh(final long delay) {
488 final Message message = mTimeHandler.obtainMessage(REFRESH_TIME);
489 mTimeHandler.removeMessages(REFRESH_TIME);
490 mTimeHandler.sendMessageDelayed(message, delay);
495 * Used to seek forwards or backwards in time through the current track
497 * @param repcnt The repeat count
498 * @param delta The long press duration
499 * @param forwards Whether it was seeking forwards or backwards
501 private void seekRelative(final int repcnt, long delta, boolean forwards) {
502 if (mService == null) {
506 final long EXTRA_FAST_CUTOFF = 10000;
507 if (delta < EXTRA_FAST_CUTOFF) {
508 // seek at 10x speed for the first 5 seconds
511 // seek at 40x after that
512 delta = EXTRA_FAST_CUTOFF * 10 + (delta - EXTRA_FAST_CUTOFF) * 40;
515 MusicUtils.seekRelative(forwards ? delta : -delta);
517 refreshCurrentTime();
521 private void refreshCurrentTimeText(final long pos) {
522 if (mPlayPauseProgressButton.isDragging()) {
523 mCurrentTime.setText(MusicUtils.makeShortTimeString(getActivity(),
524 mPlayPauseProgressButton.getDragProgressInMs() / 1000));
526 mCurrentTime.setText(MusicUtils.makeShortTimeString(getActivity(), pos / 1000));
530 /* Used to update the current time string */
531 private long refreshCurrentTime() {
532 if (mService == null) {
533 return MusicUtils.UPDATE_FREQUENCY_MS;
536 final long pos = MusicUtils.position();
537 if (pos >= 0 && MusicUtils.duration() > 0) {
538 refreshCurrentTimeText(pos);
540 if (mPlayPauseProgressButton.isDragging()) {
541 mCurrentTime.setVisibility(View.VISIBLE);
542 return MusicUtils.UPDATE_FREQUENCY_FAST_MS;
543 } else if (MusicUtils.isPlaying()) {
544 mCurrentTime.setVisibility(View.VISIBLE);
546 // calculate the number of milliseconds until the next full second,
547 // so the counter can be updated at just the right time
548 return Math.max(20, 1000 - pos % 1000);
551 final int vis = mCurrentTime.getVisibility();
552 mCurrentTime.setVisibility(vis == View.INVISIBLE ? View.VISIBLE
556 mCurrentTime.setText("--:--");
558 } catch (final Exception ignored) {
559 if (ignored.getMessage() != null) {
560 Log.e(TAG, ignored.getMessage());
563 return MusicUtils.UPDATE_FREQUENCY_MS;
567 * Used to scan backwards through the track
569 private final RepeatingImageButton.RepeatListener mRewindListener = new RepeatingImageButton.RepeatListener() {
574 public void onRepeat(final View v, final long howlong, final int repcnt) {
575 seekRelative(repcnt, howlong, false);
580 * Used to scan ahead through the track
582 private final RepeatingImageButton.RepeatListener mFastForwardListener = new RepeatingImageButton.RepeatListener() {
587 public void onRepeat(final View v, final long howlong, final int repcnt) {
588 seekRelative(repcnt, howlong, true);
592 public void showPopupMenu() {
593 // create the popup menu
594 if (mPopupMenu == null) {
595 mPopupMenu = new PopupMenu(getActivity(), mMenuButton);
596 mPopupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
598 public boolean onMenuItemClick(MenuItem item) {
599 return onPopupMenuItemClick(item);
604 final Menu menu = mPopupMenu.getMenu();
605 final MenuInflater inflater = mPopupMenu.getMenuInflater();
609 inflater.inflate(R.menu.shuffle_all, menu);
610 if (MusicUtils.getQueueSize() > 0) {
611 // ringtone, and equalizer
612 inflater.inflate(R.menu.audio_player, menu);
614 if (!NavUtils.hasEffectsPanel(getActivity())) {
615 menu.removeItem(R.id.menu_audio_player_equalizer);
618 // save queue/clear queue
619 inflater.inflate(R.menu.queue, menu);
622 inflater.inflate(R.menu.activity_base, menu);
628 public boolean onPopupMenuItemClick(final MenuItem item) {
629 switch (item.getItemId()) {
630 case R.id.menu_shuffle_all:
631 // Shuffle all the songs
632 MusicUtils.shuffleAll(getActivity());
634 case R.id.menu_audio_player_ringtone:
635 // Set the current track as a ringtone
636 MusicUtils.setRingtone(getActivity(), MusicUtils.getCurrentAudioId());
638 case R.id.menu_audio_player_equalizer:
640 NavUtils.openEffectsPanel(getActivity(), HomeActivity.EQUALIZER);
642 case R.id.menu_settings:
644 NavUtils.openSettings(getActivity());
646 case R.id.menu_audio_player_more_by_artist:
647 NavUtils.openArtistProfile(getActivity(), MusicUtils.getArtistName());
649 case R.id.menu_audio_player_delete:
650 // Delete current song
651 DeleteDialog.newInstance(MusicUtils.getTrackName(), new long[]{
652 MusicUtils.getCurrentAudioId()
653 }, null).show(getActivity().getSupportFragmentManager(), "DeleteDialog");
655 case R.id.menu_save_queue:
656 NowPlayingCursor queue = (NowPlayingCursor) QueueLoader
657 .makeQueueCursor(getActivity());
658 CreateNewPlaylist.getInstance(MusicUtils.getSongListForCursor(queue)).show(
659 getFragmentManager(), "CreatePlaylist");
662 case R.id.menu_clear_queue:
663 MusicUtils.clearQueue();
672 public void dismissPopupMenu() {
673 if (mPopupMenu != null) {
674 mPopupMenu.dismiss();
679 public boolean onContextItemSelected(MenuItem item) {
680 if (item.getGroupId() == GROUP_ID) {
681 switch (item.getItemId()) {
682 case FragmentMenuItems.NEW_PLAYLIST:
683 CreateNewPlaylist.getInstance(new long[]{
685 }).show(getFragmentManager(), "CreatePlaylist");
687 case FragmentMenuItems.PLAYLIST_SELECTED:
688 final long mPlaylistId = item.getIntent().getLongExtra("playlist", 0);
689 MusicUtils.addToPlaylist(getActivity(), new long[]{
698 return super.onContextItemSelected(item);
701 public void onLyrics(String lyrics) {
702 if (TextUtils.isEmpty(lyrics)
703 || !PreferenceUtils.getInstance(getActivity()).getShowLyrics()) {
704 mLyricsText.animate().alpha(0).setDuration(200);
706 lyrics = lyrics.replace("\n", "<br/>");
707 Spanned span = Html.fromHtml(lyrics);
708 mLyricsText.setText(span);
710 mLyricsText.animate().alpha(1).setDuration(200);
714 public void setVisualizerVisible(boolean visible) {
715 if (visible && PreferenceUtils.getInstance(getActivity()).getShowVisualizer()) {
716 if (PreferenceUtils.canRecordAudio(getActivity())) {
717 mVisualizerView.setVisible(true);
719 PreferenceUtils.requestRecordAudio(getActivity());
722 mVisualizerView.setVisible(false);
726 public void updateVisualizerPowerSaveMode() {
727 PowerManager pm = (PowerManager) getActivity().getSystemService(Context.POWER_SERVICE);
728 mVisualizerView.setPowerSaveMode(pm.isPowerSaveMode());
731 public void setVisualizerColor(int color) {
732 mVisualizerView.setColor(color);
736 * Used to update the current time string
738 private static final class TimeHandler extends Handler {
740 private final WeakReference<AudioPlayerFragment> mAudioPlayer;
743 * Constructor of <code>TimeHandler</code>
745 public TimeHandler(final AudioPlayerFragment player) {
746 mAudioPlayer = new WeakReference<AudioPlayerFragment>(player);
750 public void handleMessage(final Message msg) {
753 final long next = mAudioPlayer.get().refreshCurrentTime();
754 mAudioPlayer.get().queueNextRefresh(next);
763 * Used to monitor the state of playback
765 private static final class PlaybackStatus extends BroadcastReceiver {
767 private final WeakReference<AudioPlayerFragment> mReference;
770 * Constructor of <code>PlaybackStatus</code>
772 public PlaybackStatus(final AudioPlayerFragment fragment) {
773 mReference = new WeakReference<AudioPlayerFragment>(fragment);
780 public void onReceive(final Context context, final Intent intent) {
781 final AudioPlayerFragment audioPlayerFragment = mReference.get();
782 final String action = intent.getAction();
783 if (action.equals(MusicPlaybackService.META_CHANGED)) {
784 // if we are repeating current and the track has changed, re-create the adapter
785 if (MusicUtils.getRepeatMode() == MusicPlaybackService.REPEAT_CURRENT) {
786 mReference.get().createAndSetAdapter();
790 audioPlayerFragment.updateNowPlayingInfo();
791 audioPlayerFragment.dismissPopupMenu();
792 } else if (action.equals(MusicPlaybackService.PLAYSTATE_CHANGED)) {
793 // Set the play and pause image
794 audioPlayerFragment.mPlayPauseProgressButton.getPlayPauseButton().updateState();
795 audioPlayerFragment.mVisualizerView.setPlaying(MusicUtils.isPlaying());
796 } else if (action.equals(MusicPlaybackService.REPEATMODE_CHANGED)
797 || action.equals(MusicPlaybackService.SHUFFLEMODE_CHANGED)) {
798 // Set the repeat image
799 audioPlayerFragment.mRepeatButton.updateRepeatState();
800 // Set the shuffle image
801 audioPlayerFragment.mShuffleButton.updateShuffleState();
804 audioPlayerFragment.createAndSetAdapter();
805 } else if (action.equals(MusicPlaybackService.QUEUE_CHANGED)) {
806 audioPlayerFragment.createAndSetAdapter();
807 } else if (action.equals(MusicPlaybackService.NEW_LYRICS)) {
808 audioPlayerFragment.onLyrics(intent.getStringExtra("lyrics"));
809 } else if (action.equals(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED)) {
810 audioPlayerFragment.updateVisualizerPowerSaveMode();