diff --git a/src/ch/blinkenlights/android/vanilla/FullPlaybackActivity.java b/src/ch/blinkenlights/android/vanilla/FullPlaybackActivity.java index 57126bc2..84c4d5e9 100644 --- a/src/ch/blinkenlights/android/vanilla/FullPlaybackActivity.java +++ b/src/ch/blinkenlights/android/vanilla/FullPlaybackActivity.java @@ -29,8 +29,6 @@ import java.util.ArrayList; import android.content.Intent; import android.content.SharedPreferences; -import android.graphics.Color; -import android.os.Build; import android.os.Bundle; import android.os.Message; import android.util.Log; @@ -40,13 +38,10 @@ import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; -import android.widget.ImageButton; import android.widget.LinearLayout; -import android.widget.SeekBar; import android.widget.TableLayout; import android.widget.TableRow; import android.widget.TextView; -import android.widget.Toast; import android.app.AlertDialog; import android.content.DialogInterface; @@ -308,6 +303,7 @@ public class FullPlaybackActivity extends SlidingPlaybackActivity menu.add(0, MENU_ENQUEUE_GENRE, 30, R.string.enqueue_current_genre); menu.add(0, MENU_ADD_TO_PLAYLIST, 30, R.string.add_to_playlist); menu.add(0, MENU_SHARE, 30, R.string.share); + menu.add(0, MENU_PLUGINS, 30, R.string.plugins); mFavorites = menu.add(0, MENU_SONG_FAVORITE, 0, R.string.add_to_favorites).setIcon(R.drawable.btn_rating_star_off_mtrl_alpha).setShowAsActionFlags(MenuItem.SHOW_AS_ACTION_IF_ROOM); // ensure that mFavorites is updated @@ -383,6 +379,11 @@ public class FullPlaybackActivity extends SlidingPlaybackActivity dialog.create().show(); } break; + case MENU_PLUGINS: + Intent songIntent = new Intent(); + songIntent.putExtra("id", song.id); + queryPluginsForIntent(songIntent); + break; default: return super.onOptionsItemSelected(item); } diff --git a/src/ch/blinkenlights/android/vanilla/LibraryActivity.java b/src/ch/blinkenlights/android/vanilla/LibraryActivity.java index 0e187b37..2709a918 100644 --- a/src/ch/blinkenlights/android/vanilla/LibraryActivity.java +++ b/src/ch/blinkenlights/android/vanilla/LibraryActivity.java @@ -26,20 +26,14 @@ package ch.blinkenlights.android.vanilla; import ch.blinkenlights.android.medialibrary.MediaLibrary; import android.app.AlertDialog; -import android.content.BroadcastReceiver; -import android.content.Context; import android.content.DialogInterface; import android.content.Intent; -import android.content.IntentFilter; import android.content.SharedPreferences; -import android.content.pm.ApplicationInfo; -import android.content.pm.ResolveInfo; import android.content.res.Resources; import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.Color; import android.graphics.drawable.PaintDrawable; -import android.net.Uri; import android.os.Bundle; import android.os.Handler; import android.os.Message; @@ -60,10 +54,6 @@ import android.widget.TextView; import android.widget.SearchView; import java.io.File; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; import junit.framework.Assert; @@ -143,19 +133,6 @@ public class LibraryActivity * The last used action from the menu. Used with ACTION_LAST_USED. */ private int mLastAction = ACTION_PLAY; - /** - * Holds last intent that was passed to the context menu - */ - private Intent mLastRequestedCtx; - /** - * Plugin descriptions and packages. - * Keys are plugin names, values are their packages - */ - private Map mPlugins = new HashMap<>(); - /** - * Broadcast receiver for plugin collecting - */ - private BroadcastReceiver mPluginInfoReceiver; /** * The pager adapter that manages each media ListView. */ @@ -189,7 +166,6 @@ public class LibraryActivity mViewPager = pager; SharedPreferences settings = PlaybackService.getSettings(this); - mPluginInfoReceiver = new PluginBroadcastReceiver(); mBottomBarControls = (BottomBarControls)findViewById(R.id.bottombar_controls); mBottomBarControls.setOnClickListener(this); @@ -213,43 +189,6 @@ public class LibraryActivity bindControlButtons(); } - /** - * Shows plugin selection dialog. Be sure that {@link #mLastRequestedCtx} is initialized - * and {@link #mPlugins} are populated before calling this. - * - * @see PluginBroadcastReceiver - */ - private void showPluginMenu() { - Set pluginNames = mPlugins.keySet(); - final String[] pNamesArr = pluginNames.toArray(new String[pluginNames.size()]); - new AlertDialog.Builder(this) - .setItems(pNamesArr, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - long id = mLastRequestedCtx.getLongExtra("id", LibraryAdapter.INVALID_ID); - Song resolved = MediaUtils.getSongByTypeId(LibraryActivity.this, MediaUtils.TYPE_SONG, id); - if (resolved != null) { - ApplicationInfo selected = mPlugins.get(pNamesArr[which]); - Intent request = new Intent(PluginUtils.ACTION_LAUNCH_PLUGIN); - request.setPackage(selected.packageName); - request.putExtra(PluginUtils.EXTRA_PARAM_URI, Uri.fromFile(new File(resolved.path))); - request.putExtra(PluginUtils.EXTRA_PARAM_SONG_TITLE, resolved.title); - request.putExtra(PluginUtils.EXTRA_PARAM_SONG_ARTIST, resolved.artist); - request.putExtra(PluginUtils.EXTRA_PARAM_SONG_ALBUM, resolved.album); - startService(request); - } - - mLastRequestedCtx = null; - } - }) - .setOnCancelListener(new DialogInterface.OnCancelListener() { - @Override - public void onCancel(DialogInterface dialog) { - mLastRequestedCtx = null; - } - }).create().show(); - } - @Override public void onRestart() { @@ -267,18 +206,6 @@ public class LibraryActivity updateHeaders(); } - @Override - public void onResume() { - super.onResume(); - registerReceiver(mPluginInfoReceiver, new IntentFilter(PluginUtils.ACTION_HANDLE_PLUGIN_PARAMS)); - } - - @Override - public void onPause() { - super.onPause(); - unregisterReceiver(mPluginInfoReceiver); - } - /** * Load the tab order and update the tab bars if needed. */ @@ -776,12 +703,7 @@ public class LibraryActivity break; } case CTX_MENU_PLUGINS: { - // obtain list of plugins anew - some plugins may be installed/deleted - mPlugins.clear(); - mLastRequestedCtx = intent; - Intent requestPlugins = new Intent(PluginUtils.ACTION_REQUEST_PLUGIN_PARAMS); - intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); - sendBroadcast(requestPlugins); + queryPluginsForIntent(intent); break; } case CTX_MENU_MORE_FROM_ARTIST: { @@ -1004,21 +926,4 @@ public class LibraryActivity handler.sendMessage(mHandler.obtainMessage(MSG_SAVE_PAGE, position, 0)); } } - - private class PluginBroadcastReceiver extends BroadcastReceiver { - @Override - public void onReceive(Context context, Intent intent) { - List resolved = getPackageManager().queryBroadcastReceivers(new Intent(PluginUtils.ACTION_REQUEST_PLUGIN_PARAMS), 0); - if (PluginUtils.ACTION_HANDLE_PLUGIN_PARAMS.equals(intent.getAction())) { - // plugin answered, store it in the map - String pluginName = intent.getStringExtra(PluginUtils.EXTRA_PARAM_PLUGIN_NAME); - ApplicationInfo info = intent.getParcelableExtra(PluginUtils.EXTRA_PARAM_PLUGIN_APP); - mPlugins.put(pluginName, info); - - if (mPlugins.size() == resolved.size()) { // got all plugins - showPluginMenu(); - } - } - } - } } diff --git a/src/ch/blinkenlights/android/vanilla/PlaybackActivity.java b/src/ch/blinkenlights/android/vanilla/PlaybackActivity.java index e3284588..fc204b51 100644 --- a/src/ch/blinkenlights/android/vanilla/PlaybackActivity.java +++ b/src/ch/blinkenlights/android/vanilla/PlaybackActivity.java @@ -25,13 +25,24 @@ package ch.blinkenlights.android.vanilla; import java.io.File; import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; import android.app.Activity; +import android.app.AlertDialog; +import android.content.BroadcastReceiver; +import android.content.Context; import android.content.DialogInterface; import android.content.Intent; +import android.content.IntentFilter; import android.content.SharedPreferences; +import android.content.pm.ApplicationInfo; +import android.content.pm.ResolveInfo; import android.content.res.Resources; import android.media.AudioManager; +import android.net.Uri; import android.os.Bundle; import android.os.Handler; import android.os.HandlerThread; @@ -75,6 +86,19 @@ public abstract class PlaybackActivity extends Activity * The looper for the worker thread. */ protected Looper mLooper; + /** + * Broadcast receiver for plugin collecting + */ + private BroadcastReceiver mPluginInfoReceiver; + /** + * Holds last intent that was passed to the context menu + */ + private Intent mLastRequestedCtx; + /** + * Plugin descriptions and packages. + * Keys are plugin names, values are their packages + */ + private Map mPlugins = new HashMap<>(); protected CoverView mCoverView; protected ImageButton mPlayPauseButton; @@ -92,6 +116,8 @@ public abstract class PlaybackActivity extends Activity PlaybackService.addTimelineCallback(this); + mPluginInfoReceiver = new PluginBroadcastReceiver(); + setVolumeControlStream(AudioManager.STREAM_MUSIC); HandlerThread thread = new HandlerThread(getClass().getName(), Process.THREAD_PRIORITY_LOWEST); @@ -138,6 +164,7 @@ public abstract class PlaybackActivity extends Activity public void onResume() { super.onResume(); + registerReceiver(mPluginInfoReceiver, new IntentFilter(PluginUtils.ACTION_HANDLE_PLUGIN_PARAMS)); if (PlaybackService.hasInstance()) { PlaybackService service = PlaybackService.get(this); service.userActionTriggered(); @@ -145,6 +172,11 @@ public abstract class PlaybackActivity extends Activity } + @Override + protected void onPause() { + super.onPause(); + unregisterReceiver(mPluginInfoReceiver); + } @Override public boolean onKeyDown(int keyCode, KeyEvent event) @@ -375,7 +407,8 @@ public abstract class PlaybackActivity extends Activity static final int MENU_EMPTY_QUEUE = 16; static final int MENU_ADD_TO_PLAYLIST = 17; static final int MENU_SHARE = 18; - static final int MENU_GO_HOME= 19; + static final int MENU_GO_HOME = 19; + static final int MENU_PLUGINS = 20; // used in FullPlaybackActivity @Override public boolean onCreateOptionsMenu(Menu menu) @@ -661,4 +694,80 @@ public abstract class PlaybackActivity extends Activity return true; } + /** + * Sends broadcast query that wakes plugins are queries them for info. + * Answers are later processed in {@link PluginBroadcastReceiver} + * + * @param songIntent intent containing song id as {@link Long} in its "id" extra. + */ + protected void queryPluginsForIntent(Intent songIntent) { + // obtain list of plugins anew - some plugins may be installed/deleted + mPlugins.clear(); + mLastRequestedCtx = songIntent; + Intent requestPlugins = new Intent(PluginUtils.ACTION_REQUEST_PLUGIN_PARAMS); + requestPlugins.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); + sendBroadcast(requestPlugins); + } + + /** + * Broadcast receiver that handles return intents from queried plugins. + * Answered ones are stored in {@link #mPlugins}. + * Shows plugin menu once all queried plugins have answered. + * + * @see #showPluginMenu() + */ + private class PluginBroadcastReceiver extends BroadcastReceiver { + @Override + public void onReceive(Context context, Intent intent) { + List resolved = getPackageManager().queryBroadcastReceivers(new Intent(PluginUtils.ACTION_REQUEST_PLUGIN_PARAMS), 0); + if (PluginUtils.ACTION_HANDLE_PLUGIN_PARAMS.equals(intent.getAction())) { + // plugin answered, store it in the map + String pluginName = intent.getStringExtra(PluginUtils.EXTRA_PARAM_PLUGIN_NAME); + ApplicationInfo info = intent.getParcelableExtra(PluginUtils.EXTRA_PARAM_PLUGIN_APP); + mPlugins.put(pluginName, info); + + if (mPlugins.size() == resolved.size()) { // got all plugins + showPluginMenu(); + } + } + } + } + + /** + * Shows plugin selection dialog. Be sure that {@link #mLastRequestedCtx} is initialized + * and {@link #mPlugins} are populated before calling this. + * + * @see PluginBroadcastReceiver + */ + private void showPluginMenu() { + Set pluginNames = mPlugins.keySet(); + final String[] pNamesArr = pluginNames.toArray(new String[pluginNames.size()]); + new AlertDialog.Builder(this) + .setItems(pNamesArr, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + long id = mLastRequestedCtx.getLongExtra("id", LibraryAdapter.INVALID_ID); + Song resolved = MediaUtils.getSongByTypeId(PlaybackActivity.this, MediaUtils.TYPE_SONG, id); + if (resolved != null) { + ApplicationInfo selected = mPlugins.get(pNamesArr[which]); + Intent request = new Intent(PluginUtils.ACTION_LAUNCH_PLUGIN); + request.setPackage(selected.packageName); + request.putExtra(PluginUtils.EXTRA_PARAM_URI, Uri.fromFile(new File(resolved.path))); + request.putExtra(PluginUtils.EXTRA_PARAM_SONG_TITLE, resolved.title); + request.putExtra(PluginUtils.EXTRA_PARAM_SONG_ARTIST, resolved.artist); + request.putExtra(PluginUtils.EXTRA_PARAM_SONG_ALBUM, resolved.album); + startService(request); + } + + mLastRequestedCtx = null; + } + }) + .setOnCancelListener(new DialogInterface.OnCancelListener() { + @Override + public void onCancel(DialogInterface dialog) { + mLastRequestedCtx = null; + } + }).create().show(); + } + }