/* * Copyright (C) 2014 Fastboot Mobile, LLC. * * This program is free software; you can redistribute it and/or modify it under the terms of the * GNU General Public License as published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See * the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with this program; * if not, see <http://www.gnu.org/licenses>. */ package com.fastbootmobile.encore.app; import android.app.ProgressDialog; import android.content.Context; import android.content.Intent; import android.media.AudioManager; import android.os.Bundle; import android.os.RemoteException; import android.preference.CheckBoxPreference; import android.preference.EditTextPreference; import android.preference.ListPreference; import android.preference.MultiSelectListPreference; import android.preference.Preference; import android.preference.PreferenceActivity; import android.preference.PreferenceManager; import android.support.v7.widget.Toolbar; import android.util.Log; import android.view.MenuItem; import android.widget.LinearLayout; import android.widget.Toast; import com.fastbootmobile.encore.api.echonest.AutoMixBucket; import com.fastbootmobile.encore.api.echonest.AutoMixManager; import com.fastbootmobile.encore.app.ui.FilteredMultiSelectListPreference; import com.fastbootmobile.encore.framework.PluginsLookup; import com.fastbootmobile.encore.providers.IMusicProvider; import com.fastbootmobile.encore.providers.ProviderAggregator; import com.fastbootmobile.encore.providers.ProviderConnection; import com.fastbootmobile.encore.providers.ProviderIdentifier; import com.fastbootmobile.encore.utils.Utils; import java.util.List; import java.util.Set; import uk.co.chrisjenx.calligraphy.CalligraphyContextWrapper; /** * Activity presenting the settings to create an AutoMix Bucket */ public class AutomixCreateActivity extends PreferenceActivity { private static final String TAG = "AutomixCreateActivity"; public static final String EXTRA_MODE = "mode"; public static final int MODE_DYNAMIC = 0; public static final int MODE_STATIC = 1; private static final String KEY_NAME = "automix_bucket_name"; private static final String KEY_STYLES = "automix_styles"; private static final String KEY_MOODS = "automix_moods"; private static final String KEY_TASTE = "automix_use_taste"; private static final String KEY_ADVENTUROUS = "automix_adventurous"; private static final String KEY_SONG_TYPES = "automix_song_types"; private static final String KEY_SPEECHINESS = "automix_target_speechiness"; private static final String KEY_ENERGY = "automix_target_energy"; private static final String KEY_FAMILIAR = "automix_target_familiarity"; private AutoMixManager mAutoMixManager = AutoMixManager.getDefault(); private int mMode; private ProgressDialog mProgressDialog; private Toolbar mToolbar; private final Runnable mInvalidSettingsError = new Runnable() { @Override public void run() { mProgressDialog.dismiss(); Utils.shortToast(AutomixCreateActivity.this, R.string.bucket_settings_invalid); } }; private final Runnable mInvalidMinimalSettings = new Runnable() { @Override public void run() { mProgressDialog.dismiss(); Utils.shortToast(AutomixCreateActivity.this, R.string.automix_minimal_settings_error); } }; private final Runnable mInvalidNameError = new Runnable() { @Override public void run() { mProgressDialog.dismiss(); Utils.shortToast(AutomixCreateActivity.this, R.string.automix_bucket_name_error); } }; private final Runnable mCreationDone = new Runnable() { @Override public void run() { mProgressDialog.dismiss(); if (mMode == MODE_STATIC) { Toast.makeText(AutomixCreateActivity.this, "Playlist created", Toast.LENGTH_SHORT).show(); } finish(); } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Lollipop removes toolbars LinearLayout root = (LinearLayout)findViewById(android.R.id.list).getParent().getParent().getParent(); mToolbar = (Toolbar) getLayoutInflater().inflate(R.layout.toolbar_automix, root, false); mToolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem menuItem) { int id = menuItem.getItemId(); if (id == android.R.id.home) { finish(); return true; } else if (id == R.id.menu_create) { createBucket(); } return true; } }); root.addView(mToolbar, 0); mToolbar.inflateMenu(R.menu.automix); // Set the title mMode = getIntent().getIntExtra(EXTRA_MODE, 0); if (mMode == MODE_STATIC) { mToolbar.setTitle(R.string.title_activity_automix_create_static); } else if (mMode == MODE_DYNAMIC) { mToolbar.setTitle(R.string.title_activity_automix_create_dynamic); } // Inflate preferences addPreferencesFromResource(R.xml.automix_create); // Turn on static/dynamic specific preferences // Taste-biased playlists only work with static playlists boolean hasTasteSettings = (mMode == MODE_STATIC); findPreference(KEY_ADVENTUROUS).setEnabled(hasTasteSettings); findPreference(KEY_TASTE).setEnabled(hasTasteSettings); } @Override protected void onResume() { super.onResume(); setVolumeControlStream(AudioManager.STREAM_MUSIC); } @Override protected void attachBaseContext(Context newBase) { super.attachBaseContext(new CalligraphyContextWrapper(newBase)); } private void createBucket() { // TODO: Remove the progress dialog and show progress and status in the main Automix // fragment to avoid locking the user out of the app for multiple seconds mProgressDialog = new ProgressDialog(this); mProgressDialog.setIndeterminate(true); mProgressDialog.setMessage( getString(mMode == MODE_DYNAMIC ? R.string.bucket_creating_dialog : R.string.playlist_creating_dialog) ); mProgressDialog.show(); new Thread() { public void run() { String name = getPrefStringValue(KEY_NAME); String[] styles = getPrefStringArray(KEY_STYLES); String[] moods = getPrefStringArray(KEY_MOODS); boolean taste = getPrefBool(KEY_TASTE); float advent = getPrefFloat(KEY_ADVENTUROUS); String[] songtype = getPrefStringArray(KEY_SONG_TYPES); float speech = getPrefFloat(KEY_SPEECHINESS); float energy = getPrefFloat(KEY_ENERGY); float familiar = getPrefFloat(KEY_FAMILIAR); if (name == null || name.trim().isEmpty()) { runOnUiThread(mInvalidNameError); } else if (styles.length == 0 && moods.length == 0 && (mMode == MODE_DYNAMIC || !taste)) { runOnUiThread(mInvalidMinimalSettings); } else { Log.i(TAG, "Creating bucket (mode=" + mMode + ")..."); if (mMode == MODE_DYNAMIC) { AutoMixBucket bucket = mAutoMixManager.createBucket(name, styles, moods, taste, advent, songtype, speech, energy, familiar); if (bucket.isPlaylistSessionError()) { runOnUiThread(mInvalidSettingsError); } else { Log.d(TAG, "Bucket created!"); runOnUiThread(mCreationDone); } } else { AutoMixBucket bucket = mAutoMixManager.createStaticBucket(name, styles, moods, taste, advent, songtype, speech, energy, familiar); List<String> songRefs = bucket.generateStaticPlaylist(); if (songRefs != null) { ProviderAggregator aggregator = ProviderAggregator.getDefault(); ProviderIdentifier providerId = aggregator.getRosettaStoneIdentifier(aggregator.getPreferredRosettaStonePrefix()); if (providerId != null) { ProviderConnection conn = PluginsLookup.getDefault().getProvider(providerId); if (conn != null) { IMusicProvider binder = conn.getBinder(); if (binder != null) { try { String playlistRef = binder.addPlaylist(bucket.getName()); for (String songRef : songRefs) { binder.addSongToPlaylist(songRef, playlistRef, providerId); } Intent intent = PlaylistActivity.craftIntent(AutomixCreateActivity.this, aggregator.retrievePlaylist(playlistRef, providerId), null); startActivity(intent); runOnUiThread(mCreationDone); } catch (RemoteException e) { Log.e(TAG, "Error in provider while creating playlist", e); } } } } } else { runOnUiThread(mInvalidSettingsError); } } } } }.start(); } private String getPrefStringValue(String key) { PreferenceManager p = getPreferenceManager(); return ((EditTextPreference) p.findPreference(key)).getText(); } private String[] getPrefStringArray(String key) { PreferenceManager p = getPreferenceManager(); Preference pref = p.findPreference(key); Set<String> stringSet; if (pref instanceof MultiSelectListPreference) { stringSet = ((MultiSelectListPreference) p.findPreference(key)).getValues(); } else if (pref instanceof FilteredMultiSelectListPreference) { stringSet = ((FilteredMultiSelectListPreference) p.findPreference(key)).getValues(); } else { throw new RuntimeException("Invalid type of preference for a string array"); } return stringSet.toArray(new String[stringSet.size()]); } private float getPrefFloat(String key) { PreferenceManager p = getPreferenceManager(); return Float.parseFloat(((ListPreference) p.findPreference(key)).getValue()); } private boolean getPrefBool(String key) { PreferenceManager p = getPreferenceManager(); return ((CheckBoxPreference) p.findPreference(key)).isChecked(); } }