package com.simplecity.amp_library.ui.activities;
import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.ActivityManager;
import android.app.SearchManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.ContentUris;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.preference.PreferenceManager;
import android.provider.MediaStore;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v4.view.ViewCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBar;
import android.support.v7.widget.Toolbar;
import android.transition.Fade;
import android.transition.Transition;
import android.transition.TransitionInflater;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.SubMenu;
import android.view.View;
import android.view.Window;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.Toast;
import com.android.vending.billing.utils.IabHelper;
import com.android.vending.billing.utils.IabResult;
import com.android.vending.billing.utils.Purchase;
import com.crashlytics.android.Crashlytics;
import com.crashlytics.android.core.CrashlyticsCore;
import com.readystatesoftware.systembartint.SystemBarTintManager;
import com.simplecity.amp_library.BuildConfig;
import com.simplecity.amp_library.IabManager;
import com.simplecity.amp_library.R;
import com.simplecity.amp_library.ShuttleApplication;
import com.simplecity.amp_library.constants.Config;
import com.simplecity.amp_library.interfaces.BackPressListener;
import com.simplecity.amp_library.lyrics.LyricsFragment;
import com.simplecity.amp_library.model.Album;
import com.simplecity.amp_library.model.AlbumArtist;
import com.simplecity.amp_library.model.DrawerGroupItem;
import com.simplecity.amp_library.model.Genre;
import com.simplecity.amp_library.model.Playlist;
import com.simplecity.amp_library.model.Query;
import com.simplecity.amp_library.model.Song;
import com.simplecity.amp_library.playback.MusicService;
import com.simplecity.amp_library.search.SearchActivity;
import com.simplecity.amp_library.sql.sqlbrite.SqlBriteUtils;
import com.simplecity.amp_library.tagger.TaggerDialog;
import com.simplecity.amp_library.ui.fragments.AlbumArtistFragment;
import com.simplecity.amp_library.ui.fragments.AlbumFragment;
import com.simplecity.amp_library.ui.fragments.DetailFragment;
import com.simplecity.amp_library.ui.fragments.FolderFragment;
import com.simplecity.amp_library.ui.fragments.GenreFragment;
import com.simplecity.amp_library.ui.fragments.MainFragment;
import com.simplecity.amp_library.ui.fragments.MiniPlayerFragment;
import com.simplecity.amp_library.ui.fragments.NavigationDrawerFragment;
import com.simplecity.amp_library.ui.fragments.PlayerFragment;
import com.simplecity.amp_library.ui.fragments.PlaylistFragment;
import com.simplecity.amp_library.ui.fragments.QueueFragment;
import com.simplecity.amp_library.ui.fragments.QueuePagerFragment;
import com.simplecity.amp_library.ui.fragments.SuggestedFragment;
import com.simplecity.amp_library.ui.views.CustomDrawerLayout;
import com.simplecity.amp_library.utils.ActionBarUtils;
import com.simplecity.amp_library.utils.AnalyticsManager;
import com.simplecity.amp_library.utils.ColorUtils;
import com.simplecity.amp_library.utils.DataManager;
import com.simplecity.amp_library.utils.DialogUtils;
import com.simplecity.amp_library.utils.MusicServiceConnectionUtils;
import com.simplecity.amp_library.utils.MusicUtils;
import com.simplecity.amp_library.utils.PlaylistUtils;
import com.simplecity.amp_library.utils.ResourceUtils;
import com.simplecity.amp_library.utils.SettingsManager;
import com.simplecity.amp_library.utils.ShuttleUtils;
import com.simplecity.amp_library.utils.SleepTimer;
import com.simplecity.amp_library.utils.ThemeUtils;
import com.sothree.slidinguppanel.SlidingUpPanelLayout;
import java.io.Serializable;
import java.lang.ref.WeakReference;
import java.util.Collections;
import java.util.List;
import rx.Observable;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;
import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
@SuppressWarnings("ResourceAsColor")
public class MainActivity extends BaseCastActivity implements
AlbumArtistFragment.AlbumArtistClickListener,
AlbumFragment.AlbumClickListener,
GenreFragment.GenreClickListener,
PlaylistFragment.PlaylistClickListener,
NavigationDrawerFragment.DrawerClickListener,
SuggestedFragment.SuggestedClickListener,
MusicUtils.Defs {
private static final String TAG = "MainActivity";
public static final int REQUEST_SEARCH = 100;
public static final String ARG_MODEL = "model";
private static final int REQUEST_EXPAND = 200;
private static final String ARG_EXPANDED = "is_expanded";
SharedPreferences mPrefs;
private WeakReference<BackPressListener> mBackPressListenerReference;
private SlidingUpPanelLayout mSlidingUpPanelLayout;
private CustomDrawerLayout mDrawerLayout;
//Request code for the purchase flow
static final int RC_REQUEST = 300;
/**
* Fragment managing the behaviors, interactions and presentation of the
* navigation drawer.
*/
NavigationDrawerFragment mNavigationDrawerFragment;
/**
* Used to store the last screen title. For use in
* {@link #restoreActionBar()}.
*/
CharSequence mTitle;
private Toolbar mToolbar;
private FrameLayout mDummyStatusBar;
private boolean mIsSlidingEnabled;
private Drawable mActionBarBackButton;
private SystemBarTintManager mTintManager;
private float mAlpha;
private BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(MusicService.InternalIntents.FAVORITE_CHANGED)) {
supportInvalidateOptionsMenu();
}
}
};
private boolean mHasPendingPlaybackRequest;
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
handleIntent(intent);
}
@SuppressLint("NewApi")
@Override
public void onCreate(Bundle savedInstanceState) {
if (!ShuttleUtils.isUpgraded() && !ShuttleUtils.isAmazonBuild()) {
IabManager.getInstance();
}
ThemeUtils.setTheme(this);
if (!ShuttleUtils.hasLollipop() && ShuttleUtils.hasKitKat()) {
getWindow().setFlags(FLAG_TRANSLUCENT_STATUS, FLAG_TRANSLUCENT_STATUS);
mTintManager = new SystemBarTintManager(this);
}
if (ShuttleUtils.hasLollipop()) {
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
getWindow().setStatusBarColor(Color.TRANSPARENT);
}
if (SettingsManager.getInstance().canTintNavBar()) {
getWindow().setNavigationBarColor(ColorUtils.getPrimaryColorDark(this));
}
supportRequestWindowFeature(Window.FEATURE_ACTION_BAR_OVERLAY);
mPrefs = PreferenceManager.getDefaultSharedPreferences(this);
// Now call super to ensure the theme was properly set
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mIsSlidingEnabled = getResources().getBoolean(R.bool.isSlidingEnabled);
mToolbar = (Toolbar) findViewById(R.id.toolbar);
mDummyStatusBar = (FrameLayout) findViewById(R.id.dummyStatusBar);
if (ShuttleUtils.hasKitKat()) {
mDummyStatusBar.setVisibility(View.VISIBLE);
mDummyStatusBar.setBackgroundColor(ColorUtils.getPrimaryColorDark(this));
LinearLayout.LayoutParams statusBarParams = new LinearLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, (int) ActionBarUtils.getStatusBarHeight(this));
mDummyStatusBar.setLayoutParams(statusBarParams);
}
setSupportActionBar(mToolbar);
ThemeUtils.themeStatusBar(this, mTintManager);
mNavigationDrawerFragment = (NavigationDrawerFragment) getSupportFragmentManager().findFragmentById(R.id.navigation_drawer);
mTitle = getString(R.string.library_title);
mDrawerLayout = (CustomDrawerLayout) findViewById(R.id.drawer_layout);
if (ShuttleUtils.hasLollipop() && ShuttleUtils.hasKitKat()) {
getWindow().setStatusBarColor(Color.TRANSPARENT);
}
mDrawerLayout.setStatusBarBackgroundColor(ShuttleUtils.hasLollipop() ? ColorUtils.getPrimaryColorDark(this) : ColorUtils.getPrimaryColor());
mNavigationDrawerFragment.setup((DrawerLayout) findViewById(R.id.drawer_layout));
if (mIsSlidingEnabled) {
mSlidingUpPanelLayout = (SlidingUpPanelLayout) findViewById(R.id.container);
setDragView(null, false);
//The second panel slide offset is mini player height + toolbar height + status bar height.
//This gets our 'up next' sitting snugly underneath the toolbar
int offset = (int) (ActionBarUtils.getActionBarHeight(this)
+ (ShuttleUtils.hasKitKat() ? ActionBarUtils.getStatusBarHeight(this) : 0)
- getResources().getDimension(R.dimen.mini_player_height));
mSlidingUpPanelLayout.setSlidePanelOffset(-offset);
mSlidingUpPanelLayout.hidePanel();
mSlidingUpPanelLayout.addPanelSlideListener(new SlidingUpPanelLayout.PanelSlideListener() {
@Override
public void onPanelSlide(View panel, float slideOffset) {
setActionBarAlpha(slideOffset, false);
boolean canChangeElevation = true;
Fragment playingFragment = getSupportFragmentManager().findFragmentById(R.id.player_container);
if (playingFragment != null) {
Fragment childFragment = playingFragment.getChildFragmentManager().findFragmentById(R.id.queue_container);
if (childFragment != null && childFragment instanceof QueueFragment) {
canChangeElevation = false;
}
}
if (canChangeElevation) {
getSupportActionBar().setElevation(ResourceUtils.toPixels(4) * slideOffset);
}
mNavigationDrawerFragment.animateDrawerToggle(slideOffset);
}
@Override
public void onPanelStateChanged(View panel, SlidingUpPanelLayout.PanelState previousState, SlidingUpPanelLayout.PanelState newState) {
switch (newState) {
case COLLAPSED: {
setDragView(null, false);
mTitle = getString(R.string.library_title);
supportInvalidateOptionsMenu();
toggleQueue(false);
mNavigationDrawerFragment.toggleDrawerLock(false);
break;
}
case EXPANDED: {
Fragment playerFragment = getSupportFragmentManager().findFragmentById(R.id.player_container);
if (playerFragment != null && playerFragment instanceof PlayerFragment) {
setDragView(((PlayerFragment) playerFragment).getDragView(), true);
if (((PlayerFragment) playerFragment).isQueueShowing()) {
toggleQueue(true);
}
}
mTitle = getString(R.string.nowplaying_title);
supportInvalidateOptionsMenu();
mNavigationDrawerFragment.toggleDrawerLock(true);
break;
}
}
}
});
}
if (savedInstanceState != null && mIsSlidingEnabled) {
if (savedInstanceState.getBoolean(ARG_EXPANDED, false)) {
final ActionBar actionBar = getSupportActionBar();
//If the sliding panel was previously expanded, expand it again.
mSlidingUpPanelLayout.post(() -> {
mSlidingUpPanelLayout.setPanelState(SlidingUpPanelLayout.PanelState.EXPANDED, false);
setActionBarAlpha(1f, false);
});
mTitle = getString(R.string.nowplaying_title);
if (actionBar != null) {
actionBar.setTitle(mTitle);
}
Fragment playingFragment = getSupportFragmentManager().findFragmentById(R.id.player_container);
if (playingFragment != null) {
Fragment childFragment = playingFragment.getChildFragmentManager().findFragmentById(R.id.queue_container);
if (childFragment != null && childFragment instanceof QueueFragment) {
toggleQueue(true);
}
}
}
}
if (savedInstanceState == null) {
getSupportFragmentManager()
.beginTransaction()
.add(R.id.main_container, MainFragment.newInstance())
.commit();
getSupportFragmentManager()
.beginTransaction()
.add(R.id.mini_player_container, MiniPlayerFragment.newInstance())
.commit();
if (mIsSlidingEnabled) {
getSupportFragmentManager()
.beginTransaction()
.add(R.id.player_container, PlayerFragment.newInstance())
.commit();
}
}
themeTaskDescription();
handleIntent(getIntent());
showChangelogDialog();
}
private void showChangelogDialog() {
int storedVersionCode = SettingsManager.getInstance().getStoredVersionCode();
int launchCount = SettingsManager.getInstance().getLaunchCount();
// If we've stored a version code in the past, and it's lower than the current version code,
// we can show the changelog.
// Don't show the changelog for first time users.
// Todo: Remove launchCount check after 1.6.5 release.
if ((storedVersionCode != -1 || launchCount > 0) && storedVersionCode < BuildConfig.VERSION_CODE) {
if (SettingsManager.getInstance().getShowChangelogOnLaunch()) {
DialogUtils.showChangelog(this);
}
SettingsManager.getInstance().setVersionCode();
}
}
public void setDragView(View dragView, boolean fromExpandedView) {
if (mSlidingUpPanelLayout == null) {
return;
}
if (fromExpandedView) {
if (mSlidingUpPanelLayout.getPanelState() != SlidingUpPanelLayout.PanelState.EXPANDED) {
dragView = null;
}
}
if (dragView == null) {
dragView = findViewById(R.id.mini_player_container);
}
mSlidingUpPanelLayout.setDragView(dragView);
}
public void setScrollableView(View scrollableView) {
if (mSlidingUpPanelLayout == null) {
return;
}
mSlidingUpPanelLayout.setScrollableView(scrollableView);
}
public void togglePane() {
if (!mIsSlidingEnabled) {
return;
}
if (mSlidingUpPanelLayout == null) {
return;
}
if (mSlidingUpPanelLayout.getPanelState() == SlidingUpPanelLayout.PanelState.EXPANDED) {
mSlidingUpPanelLayout.setPanelState(SlidingUpPanelLayout.PanelState.COLLAPSED, true);
} else if (mSlidingUpPanelLayout.getPanelState() != SlidingUpPanelLayout.PanelState.HIDDEN) {
mSlidingUpPanelLayout.setPanelState(SlidingUpPanelLayout.PanelState.EXPANDED, true);
}
}
public void onSectionAttached(String title) {
mTitle = title;
}
public void restoreActionBar() {
ActionBar actionBar = getSupportActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
actionBar.setDisplayShowTitleEnabled(true);
actionBar.setTitle(mTitle);
}
@Override
protected void onPause() {
super.onPause();
LocalBroadcastManager.getInstance(this).unregisterReceiver(receiver);
}
@Override
public void onResume() {
super.onResume();
DialogUtils.showUpgradeNagDialog(this, (materialDialog, dialogAction) -> {
if (ShuttleUtils.isAmazonBuild()) {
ShuttleUtils.openShuttleLink(MainActivity.this, "com.simplecity.amp_pro");
} else {
AnalyticsManager.logUpgrade(AnalyticsManager.UpgradeType.NAG);
purchasePremiumUpgrade();
}
});
LocalBroadcastManager.getInstance(this).registerReceiver(receiver, new IntentFilter(MusicService.InternalIntents.FAVORITE_CHANGED));
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
//The user has chosen an item from the search activity, so expand the sliding panel
if (resultCode == RESULT_OK) {
switch (requestCode) {
case REQUEST_EXPAND:
if (mSlidingUpPanelLayout != null) {
mSlidingUpPanelLayout.setPanelState(SlidingUpPanelLayout.PanelState.EXPANDED, true);
}
return;
case REQUEST_SEARCH:
swapFragments(DetailFragment.newInstance(data.getSerializableExtra(ARG_MODEL)), true);
return;
case TaggerDialog.DOCUMENT_TREE_REQUEST_CODE:
if (getSupportFragmentManager().findFragmentByTag(TaggerDialog.TAG) != null) {
getSupportFragmentManager().findFragmentByTag(TaggerDialog.TAG).onActivityResult(requestCode, resultCode, data);
}
return;
}
}
if (!ShuttleUtils.isUpgraded() && !ShuttleUtils.isAmazonBuild()) {
if (IabManager.getInstance().iabHelper == null) return;
if (!IabManager.getInstance().iabHelper.handleActivityResult(requestCode, resultCode, data)) {
super.onActivityResult(requestCode, resultCode, data);
}
}
}
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
if (mIsSlidingEnabled) {
savedInstanceState.putBoolean(ARG_EXPANDED, mSlidingUpPanelLayout.getPanelState() == SlidingUpPanelLayout.PanelState.EXPANDED);
}
super.onSaveInstanceState(savedInstanceState);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
if (!mNavigationDrawerFragment.isDrawerOpen()) {
getMenuInflater().inflate(R.menu.menu_main_activity, menu);
restoreActionBar();
if (!ShuttleUtils.isUpgraded()) {
menu.findItem(R.id.media_route_menu_item).setVisible(false);
} else {
if (mCastManager != null) {
mCastManager.addMediaRouterButton(menu, R.id.media_route_menu_item);
}
}
menu.add(0, EQUALIZER, 2, R.string.equalizer);
SubMenu gotoMenu = menu.addSubMenu(0, GO_TO, 3, R.string.go_to);
gotoMenu.add(0, GO_TO_ARTIST, 0, R.string.artist_title);
gotoMenu.add(0, GO_TO_ALBUM, 1, R.string.album_title);
menu.add(0, TIMER, TIMER, R.string.timer);
if (mSlidingUpPanelLayout == null || mSlidingUpPanelLayout.getPanelState() != SlidingUpPanelLayout.PanelState.EXPANDED) {
menu.findItem(R.id.menu_favorite).setVisible(false);
menu.findItem(R.id.menu_share).setVisible(false);
menu.findItem(R.id.menu_queue).setVisible(false);
menu.findItem(R.id.menu_lyrics).setVisible(false);
if (menu.findItem(GO_TO) != null) {
menu.findItem(GO_TO).setVisible(false);
}
menu.findItem(R.id.action_search).setVisible(true);
} else {
menu.findItem(R.id.action_search).setVisible(false);
menu.findItem(R.id.menu_favorite).setVisible(true);
menu.findItem(R.id.menu_lyrics).setVisible(true);
menu.findItem(R.id.menu_share).setVisible(true);
if (!ShuttleUtils.isTablet() && ShuttleUtils.isLandscape()) {
menu.findItem(R.id.menu_queue).setVisible(true);
} else {
menu.findItem(R.id.menu_queue).setVisible(false);
}
if (menu.findItem(GO_TO) != null) {
menu.findItem(GO_TO).setVisible(true);
}
if (ShuttleUtils.isUpgraded()) {
menu.add(0, TAGGER, 3, R.string.edit_tags);
}
SubMenu sub = menu.addSubMenu(0, ADD_TO_PLAYLIST, 4, R.string.save_as_playlist);
PlaylistUtils.makePlaylistMenu(this, sub, 0);
menu.add(0, CLEAR_QUEUE, 5, R.string.clear_queue);
menu.add(0, DELETE_ITEM, 6, R.string.delete_item);
menu.add(0, VIEW_INFO, 7, R.string.song_info);
}
return true;
}
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
PlaylistUtils.isFavorite(this, MusicUtils.getSong())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(isFavorite -> {
if (isFavorite) {
final MenuItem favItem = menu.findItem(R.id.menu_favorite);
int[] attrs = new int[]{R.attr.btn_fav_pressed};
TypedArray ta = obtainStyledAttributes(attrs);
if (ta != null) {
Drawable drawableFromTheme = ta.getDrawable(0);
ta.recycle();
if (favItem != null) {
favItem.setIcon(drawableFromTheme);
}
}
}
});
MenuItem whiteListItem = menu.findItem(R.id.whitelist);
MenuItem sortingItem = menu.findItem(R.id.sort);
MenuItem viewAsItem = menu.findItem(R.id.view_as);
if (mSlidingUpPanelLayout == null || !mIsSlidingEnabled || mSlidingUpPanelLayout.getPanelState() != SlidingUpPanelLayout.PanelState.EXPANDED) {
if (whiteListItem != null) {
whiteListItem.setVisible(true);
}
if (sortingItem != null) {
sortingItem.setVisible(true);
}
if (viewAsItem != null) {
viewAsItem.setVisible(true);
}
} else {
if (whiteListItem != null) {
whiteListItem.setVisible(false);
}
if (sortingItem != null) {
sortingItem.setVisible(false);
}
if (viewAsItem != null) {
viewAsItem.setVisible(false);
}
}
if (getCurrentFragment() instanceof DetailFragment) {
if (sortingItem != null) {
sortingItem.setVisible(false);
}
}
return super.onPrepareOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_search:
Intent intent = new Intent(MainActivity.this, SearchActivity.class);
intent.putExtra(SearchManager.QUERY, "");
startActivityForResult(intent, REQUEST_SEARCH);
return true;
case EQUALIZER:
final Intent equalizerIntent = new Intent(this, EqualizerActivity.class);
startActivity(equalizerIntent);
return true;
case GO_TO_ARTIST:
long time = System.currentTimeMillis();
Album currentAlbum = MusicUtils.getAlbum();
if (currentAlbum != null) {
DataManager.getInstance().getAlbumArtistsRelay()
.first()
.flatMap(Observable::from)
.filter(albumArtist -> albumArtist.name.equals(currentAlbum.albumArtistName)
&& com.annimon.stream.Stream.of(albumArtist.albums).anyMatch(album -> album.id == currentAlbum.id))
.observeOn(AndroidSchedulers.mainThread())
.subscribe(albumArtist -> {
swapFragments(DetailFragment.newInstance(albumArtist), true);
new Handler().postDelayed(() ->
mSlidingUpPanelLayout.setPanelState(SlidingUpPanelLayout.PanelState.COLLAPSED, true), time - System.currentTimeMillis() + 250);
});
}
return true;
case GO_TO_ALBUM:
time = System.currentTimeMillis();
currentAlbum = MusicUtils.getAlbum();
if (currentAlbum != null) {
DataManager.getInstance().getAlbumsRelay()
.first()
.flatMap(Observable::from)
.filter(album -> album.id == currentAlbum.id)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(album -> {
swapFragments(DetailFragment.newInstance(album), true);
new Handler().postDelayed(() ->
mSlidingUpPanelLayout.setPanelState(SlidingUpPanelLayout.PanelState.COLLAPSED, true), time - System.currentTimeMillis() + 250);
});
}
return true;
case TIMER:
SleepTimer.createTimer(this, MusicUtils.getTimerActive(), MusicUtils.getTimeRemaining());
return true;
case DELETE_ITEM:
new DialogUtils.DeleteDialogBuilder()
.context(this)
.singleMessageId(R.string.delete_song_desc)
.multipleMessage(R.string.delete_song_desc_multiple)
.itemNames(Collections.singletonList(MusicUtils.getSongName()))
.songsToDelete(Observable.just(Collections.singletonList(MusicUtils.getSong())))
.build()
.show();
return true;
case NEW_PLAYLIST:
PlaylistUtils.createPlaylistDialog(this, MusicUtils.getQueue());
return true;
case PLAYLIST_SELECTED:
List<Song> songs = MusicUtils.getQueue();
Playlist playlist = (Playlist) item.getIntent().getSerializableExtra(ShuttleUtils.ARG_PLAYLIST);
PlaylistUtils.addToPlaylist(this, playlist, songs);
return true;
case CLEAR_QUEUE:
MusicUtils.clearQueue();
intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
finish();
return true;
case TAGGER:
TaggerDialog.newInstance(MusicUtils.getSong())
.show(getSupportFragmentManager());
return true;
case VIEW_INFO:
DialogUtils.showSongInfoDialog(this, MusicUtils.getSong());
return true;
case R.id.menu_favorite:
PlaylistUtils.toggleFavorite(this);
return true;
case R.id.menu_share:
DialogUtils.showShareDialog(MainActivity.this, MusicUtils.getSong());
return true;
case R.id.menu_queue:
Fragment playingFragment = getSupportFragmentManager().findFragmentById(R.id.player_container);
if (playingFragment != null) {
((PlayerFragment) playingFragment).toggleQueue();
}
return true;
case R.id.menu_lyrics:
playingFragment = getSupportFragmentManager().findFragmentById(R.id.player_container);
if (playingFragment != null) {
Fragment fragment = playingFragment.getChildFragmentManager().findFragmentById(R.id.main_container);
if (fragment instanceof LyricsFragment)
((LyricsFragment) fragment).remove();
else
((PlayerFragment) playingFragment).toggleLyrics();
}
return true;
case android.R.id.home:
playingFragment = getSupportFragmentManager().findFragmentById(R.id.player_container);
if (playingFragment != null) {
Fragment childFragment = playingFragment.getChildFragmentManager().findFragmentById(R.id.queue_container);
if (childFragment != null && childFragment instanceof QueueFragment) {
((PlayerFragment) playingFragment).toggleQueue();
toggleQueue(false);
return true;
}
}
if (mSlidingUpPanelLayout != null) {
if (mSlidingUpPanelLayout.getPanelState() != SlidingUpPanelLayout.PanelState.COLLAPSED && mSlidingUpPanelLayout.getPanelState() != SlidingUpPanelLayout.PanelState.HIDDEN) {
mSlidingUpPanelLayout.setPanelState(SlidingUpPanelLayout.PanelState.COLLAPSED, true);
return true;
}
}
break;
}
return super.onOptionsItemSelected(item);
}
@Override
public void onServiceConnected(ComponentName name, IBinder obj) {
super.onServiceConnected(name, obj);
supportInvalidateOptionsMenu();
if (mIsSlidingEnabled) {
PlayerFragment playerFragment = (PlayerFragment) getSupportFragmentManager().findFragmentById(R.id.player_container);
if (playerFragment != null) {
playerFragment.update();
// If the QueuePagerFragment's adapter is empty, it's because it was created before the service
// was connected. We need to recreate it now that we know the service is connected.
Fragment fragment = playerFragment.getChildFragmentManager().findFragmentById(R.id.main_container);
if (fragment instanceof QueueFragment) {
((QueueFragment) fragment).scrollToCurrentItem();
} else if (fragment instanceof QueuePagerFragment) {
((QueuePagerFragment) fragment).resetAdapter();
((QueuePagerFragment) fragment).updateQueuePosition();
}
}
}
handlePendingPlaybackRequest();
togglePanelVisibility(!(MusicServiceConnectionUtils.sServiceBinder == null || MusicUtils.getSongId() == -1));
}
@Override
public void onServiceDisconnected(ComponentName name) {
super.onServiceDisconnected(name);
}
@Override
public void onBackPressed() {
Fragment playingFragment = getSupportFragmentManager().findFragmentById(R.id.player_container);
if (playingFragment != null) {
Fragment childFragment = playingFragment.getChildFragmentManager().findFragmentById(R.id.queue_container);
if (childFragment != null && childFragment instanceof QueueFragment) {
((PlayerFragment) playingFragment).toggleQueue();
toggleQueue(false);
return;
}
}
if (mIsSlidingEnabled) {
if (mSlidingUpPanelLayout.getPanelState() == SlidingUpPanelLayout.PanelState.EXPANDED) {
mSlidingUpPanelLayout.setPanelState(SlidingUpPanelLayout.PanelState.COLLAPSED, true);
return;
}
}
boolean isShowingFolders = false;
Fragment containerFragment = getSupportFragmentManager().findFragmentById(R.id.main_container);
if (containerFragment != null && containerFragment instanceof FolderFragment) {
isShowingFolders = true;
} else if (containerFragment instanceof MainFragment) {
Fragment currentPagerFragment = ((MainFragment) containerFragment).getCurrentFragment();
if (currentPagerFragment != null && currentPagerFragment instanceof FolderFragment) {
isShowingFolders = true;
}
}
if (isShowingFolders) {
if (mBackPressListenerReference != null && mBackPressListenerReference.get() != null) {
if (mBackPressListenerReference.get().onBackPressed()) {
return;
}
}
}
super.onBackPressed();
if (isShowingFolders || containerFragment instanceof MainFragment) {
if (mNavigationDrawerFragment != null) {
mNavigationDrawerFragment.setDrawerItem(0);
}
mTitle = getString(R.string.library_title);
supportInvalidateOptionsMenu();
}
}
/**
* Perform a fragment transaction for the passed in fragment
*
* @param fragment the fragment to transition to
*/
public void swapFragments(Fragment fragment, boolean addToBackStack) {
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.setCustomAnimations(R.anim.fade_in, R.anim.fade_out, R.anim.fade_in, R.anim.fade_out);
fragmentTransaction.replace(R.id.main_container, fragment);
if (addToBackStack) {
fragmentTransaction.addToBackStack(null);
}
fragmentTransaction.commitAllowingStateLoss();
}
public void swapFragments(Serializable item, View transitionView) {
String transitionName = ViewCompat.getTransitionName(transitionView);
DetailFragment detailFragment = DetailFragment.newInstance(item, transitionName);
if (ShuttleUtils.hasLollipop()) {
Transition moveTransition = TransitionInflater.from(this).inflateTransition(R.transition.image_transition);
detailFragment.setSharedElementEnterTransition(moveTransition);
detailFragment.setEnterTransition(new Fade());
getCurrentFragment().setExitTransition(new Fade());
}
getSupportFragmentManager().beginTransaction()
.addSharedElement(transitionView, transitionName)
.replace(R.id.main_container, detailFragment)
.addToBackStack(null)
.commit();
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
@Override
public void themeColorChanged() {
if (mDummyStatusBar != null) {
mDummyStatusBar.setBackgroundColor(ShuttleUtils.hasLollipop() ? ColorUtils.getPrimaryColorDark(this) : ColorUtils.getPrimaryColor());
}
if (mDrawerLayout != null && ShuttleUtils.hasKitKat()) {
mDrawerLayout.setStatusBarBackgroundColor(ShuttleUtils.hasLollipop() ? ColorUtils.getPrimaryColorDark(MainActivity.this) : ColorUtils.getPrimaryColor());
}
if (SettingsManager.getInstance().canTintNavBar()) {
getWindow().setNavigationBarColor(ColorUtils.getPrimaryColorDark(MainActivity.this));
}
themeTaskDescription();
}
@Override
public void onItemClicked(AlbumArtist albumArtist, View transitionView) {
mTitle = getString(R.string.library_title);
swapFragments(albumArtist, transitionView);
}
@Override
public void onItemClicked(Album album, View transitionView) {
mTitle = getString(R.string.library_title);
swapFragments(album, transitionView);
}
@Override
public void onItemClicked(Genre genre) {
mTitle = getString(R.string.library_title);
swapFragments(DetailFragment.newInstance(genre), true);
}
@Override
public void onItemClicked(Playlist playlist) {
mTitle = getString(R.string.library_title);
swapFragments(DetailFragment.newInstance(playlist), true);
}
@Override
public void onItemClicked(Serializable item, View transitionView) {
mTitle = getString(R.string.library_title);
if (transitionView != null) {
swapFragments(item, transitionView);
} else {
swapFragments(DetailFragment.newInstance(item), true);
}
}
@Override
public void onItemClicked(DrawerGroupItem drawerGroupItem) {
switch (drawerGroupItem.type) {
case DrawerGroupItem.Type.LIBRARY:
if (getCurrentFragment() instanceof MainFragment) {
return;
} else {
for (int i = 0, count = getSupportFragmentManager().getBackStackEntryCount(); i < count; i++) {
try {
getSupportFragmentManager().popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
} catch (IllegalStateException e) {
Log.e(TAG, "Error popping backstack: " + e);
CrashlyticsCore.getInstance().logException(e);
}
}
mTitle = getString(R.string.library_title);
}
break;
case DrawerGroupItem.Type.FOLDERS:
if (getCurrentFragment() instanceof FolderFragment) {
return;
}
if (ShuttleUtils.isUpgraded()) {
//Folder
swapFragments(FolderFragment.newInstance(null), true);
} else {
DialogUtils.showUpgradeDialog(this, (materialDialog, dialogAction) -> {
if (ShuttleUtils.isAmazonBuild()) {
ShuttleUtils.openShuttleLink(MainActivity.this, "com.simplecity.amp_pro");
} else {
AnalyticsManager.logUpgrade(AnalyticsManager.UpgradeType.FOLDER);
purchasePremiumUpgrade();
}
});
}
break;
case DrawerGroupItem.Type.SETTINGS:
startActivity(new Intent(this, SettingsActivity.class));
break;
case DrawerGroupItem.Type.SUPPORT:
Intent intent = new Intent(this, SettingsActivity.class);
intent.putExtra(SettingsActivity.EXTRA_SUPPORT, true);
startActivity(intent);
break;
}
}
private Fragment getCurrentFragment() {
return getSupportFragmentManager().findFragmentById(R.id.main_container);
}
private void handleIntent(Intent intent) {
boolean handled = false;
if (MusicService.ShortcutCommands.PLAYLIST.equals(intent.getAction())) {
new Handler().postDelayed(() -> swapFragments(DetailFragment.newInstance(intent.getExtras().getSerializable(ShuttleUtils.ARG_PLAYLIST)), true), 50);
handled = true;
} else if (MusicService.ShortcutCommands.FOLDERS.equals(intent.getAction())) {
new Handler().postDelayed(() -> swapFragments(FolderFragment.newInstance(null), true), 50);
handled = true;
}
if (!handled) {
handlePlaybackRequest(intent);
} else {
setIntent(new Intent());
}
}
private void handlePendingPlaybackRequest() {
if (mHasPendingPlaybackRequest) {
handlePlaybackRequest(getIntent());
}
}
private void handlePlaybackRequest(Intent intent) {
if (intent == null) {
return;
} else if (MusicServiceConnectionUtils.sServiceBinder == null) {
mHasPendingPlaybackRequest = true;
return;
}
final Uri uri = intent.getData();
final String mimeType = intent.getType();
if (uri != null && uri.toString().length() > 0) {
MusicUtils.playFile(uri);
// Make sure to process intent only once
setIntent(new Intent());
} else if (MediaStore.Audio.Playlists.CONTENT_TYPE.equals(mimeType)) {
long id = parseIdFromIntent(intent, "playlistId", "playlist", -1);
if (id >= 0) {
Query query = Playlist.getQuery();
query.uri = ContentUris.withAppendedId(query.uri, id);
SqlBriteUtils.createSingleQuery(this, Playlist::new, query)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(playlist -> {
MusicUtils.playAll(this, playlist.getSongsObservable(this));
// Make sure to process intent only once
setIntent(new Intent());
});
}
}
mHasPendingPlaybackRequest = false;
}
private long parseIdFromIntent(Intent intent, String longKey,
String stringKey, long defaultId) {
long id = intent.getLongExtra(longKey, -1);
if (id < 0) {
String idString = intent.getStringExtra(stringKey);
if (idString != null) {
try {
id = Long.parseLong(idString);
} catch (NumberFormatException e) {
Log.e(TAG, e.getMessage());
}
}
}
return id;
}
private IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener = new IabHelper.OnIabPurchaseFinishedListener() {
public void onIabPurchaseFinished(IabResult result, Purchase purchase) {
// if we were disposed of in the meantime, quit.
if (IabManager.getInstance().iabHelper == null) return;
if (result.isFailure()) {
Log.e(TAG, "Error purchasing: " + result);
return;
}
String sku = purchase.getSku();
if (sku.equals(Config.SKU_PREMIUM)) {
mPrefs.edit().putBoolean("pref_theme_gold", true).apply();
ShuttleApplication.getInstance().setIsUpgraded(true);
DialogUtils.showUpgradeThankyouDialog(MainActivity.this);
}
}
};
public void purchasePremiumUpgrade() {
try {
IabManager.getInstance().iabHelper.launchPurchaseFlow(this, Config.SKU_PREMIUM, RC_REQUEST,
mPurchaseFinishedListener, "");
} catch (IllegalStateException | NullPointerException e) {
Toast.makeText(this, R.string.toast_purchase_failed, Toast.LENGTH_SHORT).show();
Crashlytics.log("purchasePremiumUpgrade failed.. " + e.getMessage());
}
}
public void togglePanelVisibility(boolean show) {
if (!mIsSlidingEnabled) {
findViewById(R.id.mini_player_container).setVisibility(show ? View.VISIBLE : View.GONE);
} else {
if (mSlidingUpPanelLayout != null) {
if (show) {
mSlidingUpPanelLayout.showPanel();
} else {
mSlidingUpPanelLayout.hidePanel();
}
}
}
}
public void toggleQueue(boolean show) {
if (mToolbar == null) {
return;
}
if (mActionBarBackButton == null) {
mActionBarBackButton = mToolbar.getNavigationIcon();
}
if (show) {
mToolbar.setNavigationIcon(R.drawable.ic_action_navigation_close);
mTitle = getString(R.string.up_next_title);
mToolbar.setTitle(mTitle);
animateElevationChange(4, 0);
} else {
mToolbar.setNavigationIcon(mActionBarBackButton);
if (mSlidingUpPanelLayout != null) {
if (mSlidingUpPanelLayout.getPanelState() == SlidingUpPanelLayout.PanelState.EXPANDED) {
mTitle = getResources().getString(R.string.nowplaying_title);
} else {
mTitle = getResources().getString(R.string.library_title);
}
}
mToolbar.setTitle(mTitle);
animateElevationChange(0, 4);
}
}
private void animateElevationChange(int currentElevationDips, int targetElevationDips) {
currentElevationDips = ResourceUtils.toPixels(currentElevationDips);
targetElevationDips = ResourceUtils.toPixels(targetElevationDips);
final ActionBar actionBar = getSupportActionBar();
if (actionBar == null) {
return;
}
ValueAnimator valueAnimator = ValueAnimator.ofInt(currentElevationDips, targetElevationDips);
valueAnimator.setIntValues(currentElevationDips, targetElevationDips);
valueAnimator.addUpdateListener(animation -> {
int value = (Integer) animation.getAnimatedValue();
actionBar.setElevation(value);
});
valueAnimator.setDuration(250);
valueAnimator.start();
}
public void setOnBackPressedListener(BackPressListener listener) {
if (listener == null) {
mBackPressListenerReference.clear();
} else {
mBackPressListenerReference = new WeakReference<>(listener);
}
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public void setActionBarAlpha(float alpha, boolean store) {
Fragment mainFragment = getSupportFragmentManager().findFragmentById(R.id.main_container);
if (mainFragment != null && !(mainFragment instanceof DetailFragment)) {
if (alpha > 0f) {
alpha = 1f;
} else {
alpha = 0f;
}
} else {
if (store) {
mAlpha = alpha;
} else {
alpha = Math.max(0f, Math.min(1f, mAlpha + alpha));
}
}
if (mToolbar != null) {
mToolbar.setBackgroundColor(ColorUtils.adjustAlpha(ColorUtils.getPrimaryColor(), alpha));
}
if (mDummyStatusBar != null) {
mDummyStatusBar.setBackgroundColor(ColorUtils.adjustAlpha(ShuttleUtils.hasLollipop() ? ColorUtils.getPrimaryColorDark(this) : ColorUtils.getPrimaryColor(), alpha));
}
if (ShuttleUtils.hasKitKat()) {
if (mTintManager != null) {
mTintManager.setStatusBarTintColor(ColorUtils.adjustAlpha(ShuttleUtils.hasLollipop() ? ColorUtils.getPrimaryColorDark(this) : ColorUtils.getPrimaryColor(), alpha));
}
}
if (ShuttleUtils.hasLollipop()) {
getWindow().setStatusBarColor(ColorUtils.adjustAlpha(ColorUtils.getPrimaryColorDark(this), alpha));
}
}
private void themeTaskDescription() {
if (ShuttleUtils.hasLollipop()) {
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);
if (bitmap != null) {
ActivityManager.TaskDescription td = new ActivityManager.TaskDescription(null, bitmap, ColorUtils.getPrimaryColor());
setTaskDescription(td);
bitmap.recycle();
}
}
}
public boolean canSetAlpha() {
boolean canSetAlpha = true;
if (mIsSlidingEnabled
&& mSlidingUpPanelLayout != null
&& (mSlidingUpPanelLayout.getPanelState() == SlidingUpPanelLayout.PanelState.DRAGGING
|| mSlidingUpPanelLayout.getPanelState() == SlidingUpPanelLayout.PanelState.EXPANDED)) {
canSetAlpha = false;
}
return canSetAlpha;
}
@Override
protected String screenName() {
return TAG;
}
}