/*
* Copyright (C) 2015 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.fragments;
import android.app.AlertDialog;
import android.content.ActivityNotFoundException;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.app.ListFragment;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.ListView;
import com.fastbootmobile.encore.app.R;
import com.fastbootmobile.encore.app.adapters.DspAdapter;
import com.fastbootmobile.encore.framework.PlaybackProxy;
import com.fastbootmobile.encore.framework.PluginsLookup;
import com.fastbootmobile.encore.providers.DSPConnection;
import com.fastbootmobile.encore.providers.ProviderIdentifier;
import com.fastbootmobile.encore.utils.Utils;
import java.util.List;
/**
* A simple {@link android.app.Fragment} subclass.
* Use the {@link com.fastbootmobile.encore.app.fragments.DspProvidersFragment#newInstance} factory method to
* create an instance of this fragment.
*
*/
public class DspProvidersFragment extends ListFragment {
private static final String TAG = "DspProvidersFragment";
private DspAdapter mAdapter;
private Handler mHandler;
private DspAdapter.ClickListener mClickListener = new DspAdapter.ClickListener() {
@Override
public void onDeleteClicked(int position) {
List<ProviderIdentifier> chain = PlaybackProxy.getDSPChain();
if (position < chain.size()) {
chain.remove(position);
PlaybackProxy.setDSPChain(chain);
} else {
Log.w(TAG, "Invalid element position: " + position + " (size=" + chain.size() + ")");
}
postUpdateDspChain();
}
@Override
public void onUpClicked(int position) {
List<ProviderIdentifier> chain = PlaybackProxy.getDSPChain();
ProviderIdentifier item = chain.remove(position);
position = Math.max(position - 1, 0);
chain.add(position, item);
PlaybackProxy.setDSPChain(chain);
postUpdateDspChain();
}
@Override
public void onDownClicked(int position) {
List<ProviderIdentifier> chain = PlaybackProxy.getDSPChain();
ProviderIdentifier item = chain.remove(position);
position = Math.min(chain.size(), position + 1);
chain.add(position, item);
PlaybackProxy.setDSPChain(chain);
postUpdateDspChain();
}
};
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
* @return A new instance of fragment SettingsProviders.
*/
public static DspProvidersFragment newInstance() {
return new DspProvidersFragment();
}
public DspProvidersFragment() {
// Required empty public constructor
}
private void postUpdateDspChain() {
mHandler.post(new Runnable() {
@Override
public void run() {
updateDspChain();
}
});
}
public void updateDspChain() {
List<ProviderIdentifier> chain = PlaybackProxy.getDSPChain();
if (mAdapter == null) {
mAdapter = new DspAdapter(chain);
} else {
mAdapter.updateChain(chain);
}
mAdapter.setClickListener(mClickListener);
setListAdapter(mAdapter);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
mHandler = new Handler();
updateDspChain();
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
setEmptyText("Sound effects plugins allows you to enhance your sound experience (via bass boosting, equalizer, etc). Tap '+' to add an installed plugin to the chain, or tap the cloud icon to discover more effects.");
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
menu.clear();
inflater.inflate(R.menu.dsp_settings, menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_add_effect:
showAddEffect();
return true;
case R.id.menu_download_effect:
ProviderDownloadDialog.newInstance(true).show(getFragmentManager(), "DSPDownload");
return true;
default:
return false;
}
}
@Override
public void onListItemClick(ListView l, View v, int position, long id) {
DSPConnection connection = ((DspAdapter) getListAdapter()).getItem(position);
if (connection.getConfigurationActivity() != null) {
Intent i = new Intent();
i.setClassName(connection.getPackage(),
connection.getConfigurationActivity());
try {
startActivity(i);
} catch (SecurityException e) {
Utils.shortToast(getActivity(), R.string.plugin_error);
Log.e(TAG, "Unable to start configuration activity. Is it exported in the manifest?", e);
} catch (ActivityNotFoundException e) {
Utils.shortToast(getActivity(), R.string.plugin_error);
Log.e(TAG, "Unable to start configuration activity, as the activity wasn't found", e);
}
} else {
Utils.shortToast(getActivity(), R.string.no_settings_dsp);
}
}
public void showAddEffect() {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle(R.string.add_effect);
// Lookup all the DSP effects providers that aren't already in the chain
final List<DSPConnection> availableDsp = PluginsLookup.getDefault().getAvailableDSPs();
final List<ProviderIdentifier> chain = PlaybackProxy.getDSPChain();
final List<DSPConnection> dsps = PluginsLookup.getDefault().getAvailableDSPs();
for (ProviderIdentifier pi : chain) {
for (DSPConnection dsp : dsps) {
if (dsp.getIdentifier().equals(pi)) {
availableDsp.remove(dsp);
}
}
}
if (availableDsp.size() > 0) {
CharSequence[] items = new CharSequence[availableDsp.size()];
int i = 0;
for (DSPConnection dsp : availableDsp) {
items[i] = dsp.getProviderName();
i++;
}
builder.setItems(items, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
addEffectToChain(availableDsp.get(i));
updateDspChain();
dialogInterface.dismiss();
}
});
builder.setIcon(R.drawable.ic_nav_listen_now);
builder.setCancelable(true);
builder.setNegativeButton(getString(R.string.cancel), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.dismiss();
}
});
builder.show();
} else {
Utils.shortToast(getActivity(), R.string.all_dsp_in_use);
}
}
public void addEffectToChain(DSPConnection dsp) {
final List<ProviderIdentifier> chain = PlaybackProxy.getDSPChain();
chain.add(dsp.getIdentifier());
PlaybackProxy.setDSPChain(chain);
}
}