Formatting fixes.

- add braces to if/for
- indent with tabs instead of spaces
- remove trailing whitespaces
This commit is contained in:
Felix Ableitner 2014-05-05 16:19:06 +02:00
parent 59df28b2bd
commit 105bb9de94
30 changed files with 980 additions and 913 deletions

View file

@ -27,17 +27,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.github.nutomic.controldlna.gui; package com.github.nutomic.controldlna.gui;
import java.util.List;
import org.teleal.cling.support.model.item.Item;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.WifiManager; import android.net.wifi.WifiManager;
import android.os.Bundle; import android.os.Bundle;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
@ -50,17 +43,16 @@ import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBar.Tab; import android.support.v7.app.ActionBar.Tab;
import android.support.v7.app.ActionBar.TabListener; import android.support.v7.app.ActionBar.TabListener;
import android.support.v7.app.ActionBarActivity; import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.KeyEvent; import android.view.KeyEvent;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import com.github.nutomic.controldlna.R; import com.github.nutomic.controldlna.R;
import org.teleal.cling.support.model.item.Item;
import java.util.List;
/** /**
* Main activity, with tabs for media servers and media routes. * Main activity, with tabs for media servers and media routes.
* *
@ -114,8 +106,7 @@ public class MainActivity extends ActionBarActivity {
mViewPager = (ViewPager) findViewById(R.id.pager); mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter); mViewPager.setAdapter(mSectionsPagerAdapter);
mViewPager.setOnPageChangeListener( mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
new ViewPager.SimpleOnPageChangeListener() {
@Override @Override
public void onPageSelected(int position) { public void onPageSelected(int position) {
actionBar.setSelectedNavigationItem(position); actionBar.setSelectedNavigationItem(position);
@ -144,7 +135,7 @@ public class MainActivity extends ActionBarActivity {
.setTabListener(tabListener)); .setTabListener(tabListener));
final WifiManager wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE); final WifiManager wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
if (!wifi.isWifiEnabled()){ if (!wifi.isWifiEnabled()) {
String value = PreferenceManager.getDefaultSharedPreferences(this) String value = PreferenceManager.getDefaultSharedPreferences(this)
.getString(PreferencesActivity.KEY_ENABLE_WIFI_ON_START, "ask"); .getString(PreferencesActivity.KEY_ENABLE_WIFI_ON_START, "ask");
if (value.equals("yes")) { if (value.equals("yes")) {
@ -204,7 +195,7 @@ public class MainActivity extends ActionBarActivity {
*/ */
@Override @Override
protected void onNewIntent(Intent intent) { protected void onNewIntent(Intent intent) {
if (intent.getAction().equals("showRouteFragment")) { if (intent.getAction() != null && intent.getAction().equals("showRouteFragment")) {
mViewPager.setCurrentItem(1); mViewPager.setCurrentItem(1);
mRouteFragment.scrollToCurrent(); mRouteFragment.scrollToCurrent();
} }
@ -233,9 +224,10 @@ public class MainActivity extends ActionBarActivity {
public void onBackPressed() { public void onBackPressed() {
OnBackPressedListener currentFragment = (OnBackPressedListener) OnBackPressedListener currentFragment = (OnBackPressedListener)
mSectionsPagerAdapter.getItem(mViewPager.getCurrentItem()); mSectionsPagerAdapter.getItem(mViewPager.getCurrentItem());
if (!currentFragment.onBackPressed()) if (!currentFragment.onBackPressed()) {
super.onBackPressed(); super.onBackPressed();
} }
}
/** /**
* Changes volume on key press (via RouteFragment). * Changes volume on key press (via RouteFragment).
@ -244,12 +236,14 @@ public class MainActivity extends ActionBarActivity {
public boolean dispatchKeyEvent(KeyEvent event) { public boolean dispatchKeyEvent(KeyEvent event) {
switch (event.getKeyCode()) { switch (event.getKeyCode()) {
case KeyEvent.KEYCODE_VOLUME_UP: case KeyEvent.KEYCODE_VOLUME_UP:
if (event.getAction() == KeyEvent.ACTION_DOWN) if (event.getAction() == KeyEvent.ACTION_DOWN) {
mRouteFragment.increaseVolume(); mRouteFragment.increaseVolume();
}
return true; return true;
case KeyEvent.KEYCODE_VOLUME_DOWN: case KeyEvent.KEYCODE_VOLUME_DOWN:
if (event.getAction() == KeyEvent.ACTION_DOWN) if (event.getAction() == KeyEvent.ACTION_DOWN) {
mRouteFragment.decreaseVolume(); mRouteFragment.decreaseVolume();
}
return true; return true;
default: default:
return super.dispatchKeyEvent(event); return super.dispatchKeyEvent(event);

View file

@ -95,9 +95,8 @@ public class PreferencesActivity extends PreferenceActivity
public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen,
Preference preference) { Preference preference) {
if (preference == mContactDev) { if (preference == mContactDev) {
Intent i = new Intent(Intent.ACTION_SENDTO, Uri.fromParts( startActivity(new Intent(Intent.ACTION_SENDTO, Uri.fromParts(
"mailto", getString(R.string.contact_mail, "@", "."), null)); "mailto", getString(R.string.contact_mail, "@", "."), null)));
startActivity(i);
return true; return true;
} }
return super.onPreferenceTreeClick(preferenceScreen, preference); return super.onPreferenceTreeClick(preferenceScreen, preference);

View file

@ -27,10 +27,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.github.nutomic.controldlna.gui; package com.github.nutomic.controldlna.gui;
import java.util.List;
import org.teleal.cling.support.model.item.Item;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.content.ComponentName; import android.content.ComponentName;
import android.content.Context; import android.content.Context;
@ -49,7 +45,6 @@ import android.support.v7.media.MediaRouter;
import android.support.v7.media.MediaRouter.Callback; import android.support.v7.media.MediaRouter.Callback;
import android.support.v7.media.MediaRouter.ProviderInfo; import android.support.v7.media.MediaRouter.ProviderInfo;
import android.support.v7.media.MediaRouter.RouteInfo; import android.support.v7.media.MediaRouter.RouteInfo;
import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.View.OnClickListener; import android.view.View.OnClickListener;
@ -73,6 +68,10 @@ import com.github.nutomic.controldlna.mediarouter.MediaRouterPlayServiceBinder;
import com.github.nutomic.controldlna.utility.FileArrayAdapter; import com.github.nutomic.controldlna.utility.FileArrayAdapter;
import com.github.nutomic.controldlna.utility.RouteAdapter; import com.github.nutomic.controldlna.utility.RouteAdapter;
import org.teleal.cling.support.model.item.Item;
import java.util.List;
/** /**
* Controls media playback by showing a list of routes, and after selecting one, * Controls media playback by showing a list of routes, and after selecting one,
* the current playlist and playback controls. * the current playlist and playback controls.
@ -81,8 +80,8 @@ import com.github.nutomic.controldlna.utility.RouteAdapter;
* *
*/ */
public class RouteFragment extends MediaRouteDiscoveryFragment implements public class RouteFragment extends MediaRouteDiscoveryFragment implements
OnBackPressedListener, OnItemClickListener, OnClickListener, OnBackPressedListener, OnItemClickListener, OnClickListener,
OnSeekBarChangeListener, OnScrollListener { OnSeekBarChangeListener, OnScrollListener {
private ListView mListView; private ListView mListView;
@ -93,6 +92,7 @@ OnSeekBarChangeListener, OnScrollListener {
private ImageButton mRepeat; private ImageButton mRepeat;
private TextView mCurrentTimeView; private TextView mCurrentTimeView;
private TextView mTotalTimeView; private TextView mTotalTimeView;
private TextView mEmptyView;
private View mCurrentTrackView; private View mCurrentTrackView;
@ -126,9 +126,10 @@ OnSeekBarChangeListener, OnScrollListener {
mPlaylistAdapter.add(mMediaRouterPlayService.getPlaylist()); mPlaylistAdapter.add(mMediaRouterPlayService.getPlaylist());
applyColors(); applyColors();
RouteInfo currentRoute = mMediaRouterPlayService.getCurrentRoute(); RouteInfo currentRoute = mMediaRouterPlayService.getCurrentRoute();
if (currentRoute != null) if (currentRoute != null) {
playlistMode(currentRoute); playlistMode(currentRoute);
} }
}
public void onServiceDisconnected(ComponentName className) { public void onServiceDisconnected(ComponentName className) {
mMediaRouterPlayService = null; mMediaRouterPlayService = null;
@ -168,7 +169,9 @@ OnSeekBarChangeListener, OnScrollListener {
mListView.setAdapter(mRouteAdapter); mListView.setAdapter(mRouteAdapter);
mListView.setOnItemClickListener(this); mListView.setOnItemClickListener(this);
mListView.setOnScrollListener(this); mListView.setOnScrollListener(this);
mListView.setEmptyView(getView().findViewById(android.R.id.empty));
mEmptyView = (TextView) getView().findViewById(android.R.id.empty);
mListView.setEmptyView(mEmptyView);
mControls = getView().findViewById(R.id.controls); mControls = getView().findViewById(R.id.controls);
mProgressBar = (SeekBar) getView().findViewById(R.id.progressBar); mProgressBar = (SeekBar) getView().findViewById(R.id.progressBar);
@ -201,19 +204,17 @@ OnSeekBarChangeListener, OnScrollListener {
new Intent(getActivity(), MediaRouterPlayService.class)); new Intent(getActivity(), MediaRouterPlayService.class));
getActivity().getApplicationContext().bindService( getActivity().getApplicationContext().bindService(
new Intent(getActivity(), MediaRouterPlayService.class), new Intent(getActivity(), MediaRouterPlayService.class),
mPlayServiceConnection, mPlayServiceConnection, Context.BIND_AUTO_CREATE);
Context.BIND_AUTO_CREATE
);
if (savedInstanceState != null) if (savedInstanceState != null) {
mListView.onRestoreInstanceState(savedInstanceState.getParcelable("list_state")); mListView.onRestoreInstanceState(savedInstanceState.getParcelable("list_state"));
} }
}
@Override @Override
public void onSaveInstanceState(Bundle outState) { public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState); super.onSaveInstanceState(outState);
//outState.putBoolean("route_selected", mSelectedRoute != null);
outState.putParcelable("list_state", mListView.onSaveInstanceState()); outState.putParcelable("list_state", mListView.onSaveInstanceState());
} }
@ -229,8 +230,8 @@ OnSeekBarChangeListener, OnScrollListener {
*/ */
@Override @Override
public int onPrepareCallbackFlags() { public int onPrepareCallbackFlags() {
return MediaRouter.CALLBACK_FLAG_REQUEST_DISCOVERY return MediaRouter.CALLBACK_FLAG_REQUEST_DISCOVERY |
| MediaRouter.CALLBACK_FLAG_PERFORM_ACTIVE_SCAN; MediaRouter.CALLBACK_FLAG_PERFORM_ACTIVE_SCAN;
} }
@Override @Override
@ -238,17 +239,19 @@ OnSeekBarChangeListener, OnScrollListener {
return new MediaRouter.Callback() { return new MediaRouter.Callback() {
@Override @Override
public void onRouteAdded(MediaRouter router, RouteInfo route) { public void onRouteAdded(MediaRouter router, RouteInfo route) {
for (int i = 0; i < mRouteAdapter.getCount(); i++) for (int i = 0; i < mRouteAdapter.getCount(); i++) {
if (mRouteAdapter.getItem(i).getId().equals(route.getId())) { if (mRouteAdapter.getItem(i).getId().equals(route.getId())) {
mRouteAdapter.remove(mRouteAdapter.getItem(i)); mRouteAdapter.remove(mRouteAdapter.getItem(i));
break; break;
} }
}
mRouteAdapter.add(route); mRouteAdapter.add(route);
RouteInfo current = mMediaRouterPlayService.getCurrentRoute(); RouteInfo current = mMediaRouterPlayService.getCurrentRoute();
if (current != null && route.getId().equals(current.getId())) if (current != null && route.getId().equals(current.getId())) {
playlistMode(current); playlistMode(current);
} }
}
@Override @Override
public void onRouteChanged(MediaRouter router, RouteInfo route) { public void onRouteChanged(MediaRouter router, RouteInfo route) {
@ -301,8 +304,9 @@ OnSeekBarChangeListener, OnScrollListener {
*/ */
@Override @Override
public void onItemClick(AdapterView<?> a, View v, final int position, long id) { public void onItemClick(AdapterView<?> a, View v, final int position, long id) {
if (mListView.getAdapter() == mRouteAdapter) if (mListView.getAdapter() == mRouteAdapter) {
playlistMode(mRouteAdapter.getItem(position)); playlistMode(mRouteAdapter.getItem(position));
}
else { else {
mMediaRouterPlayService.play(position); mMediaRouterPlayService.play(position);
changePlayPauseState(true); changePlayPauseState(true);
@ -317,8 +321,7 @@ OnSeekBarChangeListener, OnScrollListener {
mListView.setAdapter(mRouteAdapter); mListView.setAdapter(mRouteAdapter);
disableTrackHighlight(); disableTrackHighlight();
mSelectedRoute = null; mSelectedRoute = null;
TextView emptyView = (TextView) mListView.getEmptyView(); mEmptyView.setText(R.string.route_list_empty);
emptyView.setText(R.string.route_list_empty);
} }
/** /**
@ -334,8 +337,7 @@ OnSeekBarChangeListener, OnScrollListener {
changePlayPauseState(true); changePlayPauseState(true);
mStartPlayingOnSelect = -1; mStartPlayingOnSelect = -1;
} }
TextView emptyView = (TextView) mListView.getEmptyView(); mEmptyView.setText(R.string.playlist_empty);
emptyView.setText(R.string.playlist_empty);
mListView.post(new Runnable() { mListView.post(new Runnable() {
@Override @Override
public void run() { public void run() {
@ -348,24 +350,27 @@ OnSeekBarChangeListener, OnScrollListener {
* Sets colored background on the item that is currently playing. * Sets colored background on the item that is currently playing.
*/ */
private void enableTrackHighlight() { private void enableTrackHighlight() {
if (mListView.getAdapter() == mRouteAdapter || mMediaRouterPlayService == null || !isVisible()) if (mListView.getAdapter() == mRouteAdapter ||
mMediaRouterPlayService == null || !isVisible())
return; return;
disableTrackHighlight(); disableTrackHighlight();
mCurrentTrackView = mListView.getChildAt(mMediaRouterPlayService.getCurrentTrack() mCurrentTrackView = mListView.getChildAt(mMediaRouterPlayService.getCurrentTrack()
- mListView.getFirstVisiblePosition() + mListView.getHeaderViewsCount()); - mListView.getFirstVisiblePosition() + mListView.getHeaderViewsCount());
if (mCurrentTrackView != null) if (mCurrentTrackView != null) {
mCurrentTrackView.setBackgroundColor( mCurrentTrackView.setBackgroundColor(
getResources().getColor(R.color.currently_playing_background)); getResources().getColor(R.color.currently_playing_background));
} }
}
/** /**
* Removes highlight from the item that was last highlighted. * Removes highlight from the item that was last highlighted.
*/ */
private void disableTrackHighlight() { private void disableTrackHighlight() {
if (mCurrentTrackView != null) if (mCurrentTrackView != null) {
mCurrentTrackView.setBackgroundColor(Color.TRANSPARENT); mCurrentTrackView.setBackgroundColor(Color.TRANSPARENT);
} }
}
/** /**
* Unselects current media renderer if one is selected (with dialog). * Unselects current media renderer if one is selected (with dialog).
@ -373,12 +378,11 @@ OnSeekBarChangeListener, OnScrollListener {
@Override @Override
public boolean onBackPressed() { public boolean onBackPressed() {
if (mListView.getAdapter() == mPlaylistAdapter) { if (mListView.getAdapter() == mPlaylistAdapter) {
if (mPlaying) if (mPlaying) {
new AlertDialog.Builder(getActivity()) new AlertDialog.Builder(getActivity())
.setMessage(R.string.exit_renderer) .setMessage(R.string.exit_renderer)
.setPositiveButton(android.R.string.yes, .setPositiveButton(android.R.string.yes,
new DialogInterface.OnClickListener() { new DialogInterface.OnClickListener() {
@Override @Override
public void onClick(DialogInterface dialog, public void onClick(DialogInterface dialog,
int which) { int which) {
@ -389,8 +393,10 @@ OnSeekBarChangeListener, OnScrollListener {
}) })
.setNegativeButton(android.R.string.no, null) .setNegativeButton(android.R.string.no, null)
.show(); .show();
else }
else {
deviceListMode(); deviceListMode();
}
return true; return true;
} }
return false; return false;
@ -470,9 +476,10 @@ OnSeekBarChangeListener, OnScrollListener {
@Override @Override
public void onProgressChanged(SeekBar seekBar, int progress, public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) { boolean fromUser) {
if (fromUser) if (fromUser) {
mMediaRouterPlayService.seek(progress); mMediaRouterPlayService.seek(progress);
} }
}
@Override @Override
public void onStartTrackingTouch(SeekBar seekBar) { public void onStartTrackingTouch(SeekBar seekBar) {
@ -514,7 +521,8 @@ OnSeekBarChangeListener, OnScrollListener {
if (mSelectedRoute != null) { if (mSelectedRoute != null) {
mMediaRouterPlayService.play(start); mMediaRouterPlayService.play(start);
changePlayPauseState(true); changePlayPauseState(true);
} else { }
else {
Toast.makeText(getActivity(), R.string.select_route, Toast.LENGTH_SHORT) Toast.makeText(getActivity(), R.string.select_route, Toast.LENGTH_SHORT)
.show(); .show();
mStartPlayingOnSelect = start; mStartPlayingOnSelect = start;
@ -528,17 +536,18 @@ OnSeekBarChangeListener, OnScrollListener {
* @return Formatted time string. * @return Formatted time string.
*/ */
private String generateTimeString(int time) { private String generateTimeString(int time) {
assert(time >= 0);
int seconds = time % 60; int seconds = time % 60;
int minutes = time / 60; int minutes = time / 60;
if (minutes > 99) if (minutes > 99) {
return "99:99"; return "99:99";
else }
else {
return Integer.toString(minutes) + ":" + return Integer.toString(minutes) + ":" +
((seconds > 9) ((seconds > 9)
? seconds ? seconds
: "0" + Integer.toString(seconds)); : "0" + Integer.toString(seconds));
} }
}
/** /**
* Receives information from MediaRouterPlayService about playback status. * Receives information from MediaRouterPlayService about playback status.
@ -559,14 +568,17 @@ OnSeekBarChangeListener, OnScrollListener {
if (status.getPlaybackState() == MediaItemStatus.PLAYBACK_STATE_PLAYING || if (status.getPlaybackState() == MediaItemStatus.PLAYBACK_STATE_PLAYING ||
status.getPlaybackState() == MediaItemStatus.PLAYBACK_STATE_BUFFERING || status.getPlaybackState() == MediaItemStatus.PLAYBACK_STATE_BUFFERING ||
status.getPlaybackState() == MediaItemStatus.PLAYBACK_STATE_PENDING) status.getPlaybackState() == MediaItemStatus.PLAYBACK_STATE_PENDING) {
changePlayPauseState(true); changePlayPauseState(true);
else }
else {
changePlayPauseState(false); changePlayPauseState(false);
}
if (mListView.getAdapter() == mPlaylistAdapter) if (mListView.getAdapter() == mPlaylistAdapter) {
enableTrackHighlight(); enableTrackHighlight();
} }
}
/** /**
* Changes the state of mPlayPause button to pause/resume according to * Changes the state of mPlayPause button to pause/resume according to

View file

@ -27,24 +27,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.github.nutomic.controldlna.gui; package com.github.nutomic.controldlna.gui;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
import org.teleal.cling.android.AndroidUpnpService;
import org.teleal.cling.android.AndroidUpnpServiceImpl;
import org.teleal.cling.model.action.ActionInvocation;
import org.teleal.cling.model.message.UpnpResponse;
import org.teleal.cling.model.meta.Device;
import org.teleal.cling.model.meta.Service;
import org.teleal.cling.model.types.ServiceType;
import org.teleal.cling.model.types.UDN;
import org.teleal.cling.support.contentdirectory.callback.Browse;
import org.teleal.cling.support.model.BrowseFlag;
import org.teleal.cling.support.model.DIDLContent;
import org.teleal.cling.support.model.container.Container;
import org.teleal.cling.support.model.item.Item;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
import android.content.ComponentName; import android.content.ComponentName;
import android.content.Context; import android.content.Context;
@ -70,6 +52,24 @@ import com.github.nutomic.controldlna.gui.MainActivity.OnBackPressedListener;
import com.github.nutomic.controldlna.utility.DeviceArrayAdapter; import com.github.nutomic.controldlna.utility.DeviceArrayAdapter;
import com.github.nutomic.controldlna.utility.FileArrayAdapter; import com.github.nutomic.controldlna.utility.FileArrayAdapter;
import org.teleal.cling.android.AndroidUpnpService;
import org.teleal.cling.android.AndroidUpnpServiceImpl;
import org.teleal.cling.model.action.ActionInvocation;
import org.teleal.cling.model.message.UpnpResponse;
import org.teleal.cling.model.meta.Device;
import org.teleal.cling.model.meta.Service;
import org.teleal.cling.model.types.ServiceType;
import org.teleal.cling.model.types.UDN;
import org.teleal.cling.support.contentdirectory.callback.Browse;
import org.teleal.cling.support.model.BrowseFlag;
import org.teleal.cling.support.model.DIDLContent;
import org.teleal.cling.support.model.container.Container;
import org.teleal.cling.support.model.item.Item;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
/** /**
* Shows a list of media servers, upon selecting one, allows browsing their * Shows a list of media servers, upon selecting one, allows browsing their
* directories. * directories.
@ -107,6 +107,8 @@ public class ServerFragment extends ListFragment implements OnBackPressedListene
*/ */
private Stack<String> mCurrentPath = new Stack<String>(); private Stack<String> mCurrentPath = new Stack<String>();
private TextView mEmptyView;
/** /**
* Holds the scroll position in the list view at each directory level. * Holds the scroll position in the list view at each directory level.
*/ */
@ -148,7 +150,6 @@ public class ServerFragment extends ListFragment implements OnBackPressedListene
@Override @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) { Bundle savedInstanceState) {
return inflater.inflate(R.layout.server_fragment, null); return inflater.inflate(R.layout.server_fragment, null);
}; };
@ -166,22 +167,24 @@ public class ServerFragment extends ListFragment implements OnBackPressedListene
setListAdapter(mServerAdapter); setListAdapter(mServerAdapter);
getActivity().getApplicationContext().bindService( getActivity().getApplicationContext().bindService(
new Intent(getActivity(), AndroidUpnpServiceImpl.class), new Intent(getActivity(), AndroidUpnpServiceImpl.class),
mUpnpServiceConnection, mUpnpServiceConnection, Context.BIND_AUTO_CREATE);
Context.BIND_AUTO_CREATE
);
IntentFilter filter = new IntentFilter(); IntentFilter filter = new IntentFilter();
filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION); filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
getActivity().registerReceiver(mWifiReceiver, filter); getActivity().registerReceiver(mWifiReceiver, filter);
mEmptyView = (TextView) getListView().getEmptyView();
if (savedInstanceState != null) { if (savedInstanceState != null) {
mRestoreServer = savedInstanceState.getString("current_server"); mRestoreServer = savedInstanceState.getString("current_server");
mCurrentPath.addAll(savedInstanceState.getStringArrayList("path")); mCurrentPath.addAll(savedInstanceState.getStringArrayList("path"));
mListState.addAll(savedInstanceState.getParcelableArrayList("list_state")); mListState.addAll(savedInstanceState.getParcelableArrayList("list_state"));
} else }
else {
mListState.push(getListView().onSaveInstanceState()); mListState.push(getListView().onSaveInstanceState());
} }
}
/** /**
* Stores current server and path/list state stacks. * Stores current server and path/list state stacks.
@ -210,20 +213,24 @@ public class ServerFragment extends ListFragment implements OnBackPressedListene
*/ */
@Override @Override
public void onListItemClick(ListView l, View v, int position, long id) { public void onListItemClick(ListView l, View v, int position, long id) {
if (getListAdapter() == mServerAdapter) if (getListAdapter() == mServerAdapter) {
browsingMode(mServerAdapter.getItem(position)); browsingMode(mServerAdapter.getItem(position));
else if (getListAdapter() == mFileAdapter) }
else if (getListAdapter() == mFileAdapter) {
if (mFileAdapter.getItem(position) instanceof Container) if (mFileAdapter.getItem(position) instanceof Container)
getFiles(((Container) mFileAdapter.getItem(position)).getId()); getFiles(((Container) mFileAdapter.getItem(position)).getId());
else { else {
List<Item> playlist = new ArrayList<Item>(); List<Item> playlist = new ArrayList<Item>();
for (int i = 0; i < mFileAdapter.getCount(); i++) for (int i = 0; i < mFileAdapter.getCount(); i++) {
if (mFileAdapter.getItem(i) instanceof Item) if (mFileAdapter.getItem(i) instanceof Item) {
playlist.add((Item) mFileAdapter.getItem(i)); playlist.add((Item) mFileAdapter.getItem(i));
}
}
MainActivity activity = (MainActivity) getActivity(); MainActivity activity = (MainActivity) getActivity();
activity.play(playlist, position); activity.play(playlist, position);
} }
} }
}
/** /**
* Displays available servers in the ListView. * Displays available servers in the ListView.
@ -231,8 +238,7 @@ public class ServerFragment extends ListFragment implements OnBackPressedListene
private void serverMode() { private void serverMode() {
setListAdapter(mServerAdapter); setListAdapter(mServerAdapter);
mCurrentServer = null; mCurrentServer = null;
TextView emptyView = (TextView) getListView().getEmptyView(); mEmptyView.setText(R.string.device_list_empty);
emptyView.setText(R.string.device_list_empty);
getListView().onRestoreInstanceState(mListState.pop()); getListView().onRestoreInstanceState(mListState.pop());
} }
@ -243,8 +249,7 @@ public class ServerFragment extends ListFragment implements OnBackPressedListene
setListAdapter(mFileAdapter); setListAdapter(mFileAdapter);
mCurrentServer = server; mCurrentServer = server;
getFiles(ROOT_DIRECTORY); getFiles(ROOT_DIRECTORY);
TextView emptyView = (TextView) getListView().getEmptyView(); mEmptyView.setText(R.string.folder_list_empty);
emptyView.setText(R.string.folder_list_empty);
} }
/** /**
@ -281,15 +286,19 @@ public class ServerFragment extends ListFragment implements OnBackPressedListene
@Override @Override
public void run() { public void run() {
mFileAdapter.clear(); mFileAdapter.clear();
for (Container c : didl.getContainers()) for (Container c : didl.getContainers()) {
mFileAdapter.add(c); mFileAdapter.add(c);
for (Item i : didl.getItems()) }
for (Item i : didl.getItems()) {
mFileAdapter.add(i); mFileAdapter.add(i);
if (restoreListState) }
if (restoreListState) {
getListView().onRestoreInstanceState(mListState.pop()); getListView().onRestoreInstanceState(mListState.pop());
else }
else {
getListView().setSelectionFromTop(0, 0); getListView().setSelectionFromTop(0, 0);
} }
}
}); });
} }
@ -317,10 +326,12 @@ public class ServerFragment extends ListFragment implements OnBackPressedListene
return false; return false;
mCurrentPath.pop(); mCurrentPath.pop();
if (mCurrentPath.empty()) if (mCurrentPath.empty()) {
serverMode(); serverMode();
else }
else {
getFiles(true); getFiles(true);
}
return true; return true;
} }
@ -340,11 +351,13 @@ public class ServerFragment extends ListFragment implements OnBackPressedListene
if (wifi.isConnected()) { if (wifi.isConnected()) {
if (mUpnpService != null) { if (mUpnpService != null) {
for (Device<?, ?, ?> d : mUpnpService.getControlPoint() for (Device<?, ?, ?> d : mUpnpService.getControlPoint()
.getRegistry().getDevices()) .getRegistry().getDevices()) {
mServerAdapter.deviceAdded(d); mServerAdapter.deviceAdded(d);
}
mUpnpService.getControlPoint().search(); mUpnpService.getControlPoint().search();
} }
} else }
else {
for (int i = 0; i < mServerAdapter.getCount(); i++) { for (int i = 0; i < mServerAdapter.getCount(); i++) {
Device<?, ?, ?> d = mServerAdapter.getItem(i); Device<?, ?, ?> d = mServerAdapter.getItem(i);
UDN udn = new UDN(d.getIdentity().getUdn().toString()); UDN udn = new UDN(d.getIdentity().getUdn().toString());
@ -359,6 +372,7 @@ public class ServerFragment extends ListFragment implements OnBackPressedListene
} }
} }
} }
}
}; };
} }

View file

@ -27,8 +27,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.github.nutomic.controldlna.localroute; package com.github.nutomic.controldlna.localroute;
import java.io.IOException;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.media.AudioManager; import android.media.AudioManager;
@ -41,6 +39,8 @@ import android.support.v7.media.MediaRouteProvider;
import android.support.v7.media.MediaRouter.ControlRequestCallback; import android.support.v7.media.MediaRouter.ControlRequestCallback;
import android.util.Log; import android.util.Log;
import java.io.IOException;
/** /**
* Receives control intents through media route and executes them on a MediaPlayer. * Receives control intents through media route and executes them on a MediaPlayer.
* *
@ -114,10 +114,12 @@ public class Controller extends MediaRouteProvider.RouteController implements
mState = MediaItemStatus.PLAYBACK_STATE_BUFFERING; mState = MediaItemStatus.PLAYBACK_STATE_BUFFERING;
getStatus(mItemId, mRouteId, callback); getStatus(mItemId, mRouteId, callback);
return true; return true;
} catch (IllegalArgumentException e) { }
catch (IllegalArgumentException e) {
mState = MediaItemStatus.PLAYBACK_STATE_ERROR; mState = MediaItemStatus.PLAYBACK_STATE_ERROR;
Log.d(TAG, "Failed to start playback", e); Log.d(TAG, "Failed to start playback", e);
} catch (IOException e) { }
catch (IOException e) {
mState = MediaItemStatus.PLAYBACK_STATE_ERROR; mState = MediaItemStatus.PLAYBACK_STATE_ERROR;
Log.d(TAG, "Failed to start playback", e); Log.d(TAG, "Failed to start playback", e);
} }
@ -161,14 +163,16 @@ public class Controller extends MediaRouteProvider.RouteController implements
.setContentPosition(mPlayer.getCurrentPosition()) .setContentPosition(mPlayer.getCurrentPosition())
.setContentDuration(mPlayer.getDuration()) .setContentDuration(mPlayer.getDuration())
.setTimestamp(SystemClock.elapsedRealtime()) .setTimestamp(SystemClock.elapsedRealtime())
.build().asBundle(); .build()
.asBundle();
status.putString(MediaControlIntent.EXTRA_SESSION_ID, mRouteId); status.putString(MediaControlIntent.EXTRA_SESSION_ID, mRouteId);
status.putString(MediaControlIntent.EXTRA_ITEM_ID, mItemId); status.putString(MediaControlIntent.EXTRA_ITEM_ID, mItemId);
} }
else else {
status = new MediaItemStatus.Builder(MediaItemStatus.PLAYBACK_STATE_INVALIDATED) status = new MediaItemStatus.Builder(MediaItemStatus.PLAYBACK_STATE_INVALIDATED)
.build().asBundle(); .build().asBundle();
}
callback.onResult(status); callback.onResult(status);
} }

View file

@ -74,7 +74,8 @@ final class Provider extends MediaRouteProvider {
private static void addDataTypeUnchecked(IntentFilter filter, String type) { private static void addDataTypeUnchecked(IntentFilter filter, String type) {
try { try {
filter.addDataType(type); filter.addDataType(type);
} catch (MalformedMimeTypeException ex) { }
catch (MalformedMimeTypeException ex) {
throw new RuntimeException(ex); throw new RuntimeException(ex);
} }
} }

View file

@ -36,8 +36,9 @@ public class ProviderService extends MediaRouteProviderService {
@Override @Override
public MediaRouteProvider onCreateMediaRouteProvider() { public MediaRouteProvider onCreateMediaRouteProvider() {
if (mProvider == null) if (mProvider == null) {
mProvider = new Provider(this); mProvider = new Provider(this);
}
return mProvider; return mProvider;
} }

View file

@ -27,17 +27,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.github.nutomic.controldlna.mediarouter; package com.github.nutomic.controldlna.mediarouter;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import org.teleal.cling.support.contentdirectory.DIDLParser;
import org.teleal.cling.support.model.DIDLContent;
import org.teleal.cling.support.model.DIDLObject;
import org.teleal.cling.support.model.item.Item;
import org.teleal.cling.support.model.item.MusicTrack;
import android.app.Notification; import android.app.Notification;
import android.app.PendingIntent; import android.app.PendingIntent;
import android.app.Service; import android.app.Service;
@ -66,6 +55,17 @@ import com.github.nutomic.controldlna.gui.PreferencesActivity;
import com.github.nutomic.controldlna.gui.RouteFragment; import com.github.nutomic.controldlna.gui.RouteFragment;
import com.github.nutomic.controldlna.utility.LoadImageTask; import com.github.nutomic.controldlna.utility.LoadImageTask;
import org.teleal.cling.support.contentdirectory.DIDLParser;
import org.teleal.cling.support.model.DIDLContent;
import org.teleal.cling.support.model.DIDLObject;
import org.teleal.cling.support.model.item.Item;
import org.teleal.cling.support.model.item.MusicTrack;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
/** /**
* Background service that handles media playback to a single UPNP media renderer. * Background service that handles media playback to a single UPNP media renderer.
* *
@ -120,12 +120,14 @@ public class MediaRouterPlayService extends Service {
new MediaRouter.Callback() { new MediaRouter.Callback() {
@Override @Override
public void onRouteRemoved(MediaRouter router, RouteInfo route) { public void onRouteRemoved(MediaRouter router, RouteInfo route) {
if (route.equals(mCurrentRoute)) if (route.equals(mCurrentRoute)) {
stopForeground(true); stopForeground(true);
}
if (!mBound && !mPollingStatus) if (!mBound && !mPollingStatus) {
stopSelf(); stopSelf();
} }
}
@Override @Override
public void onRouteAdded(MediaRouter router, RouteInfo route) { public void onRouteAdded(MediaRouter router, RouteInfo route) {
@ -150,10 +152,11 @@ public class MediaRouterPlayService extends Service {
title = mPlaylist.get(mCurrentTrack).getTitle(); title = mPlaylist.get(mCurrentTrack).getTitle();
if (mPlaylist.get(mCurrentTrack) instanceof MusicTrack) { if (mPlaylist.get(mCurrentTrack) instanceof MusicTrack) {
MusicTrack track = (MusicTrack) mPlaylist.get(mCurrentTrack); MusicTrack track = (MusicTrack) mPlaylist.get(mCurrentTrack);
if (track.getArtists().length > 0) if (track.getArtists().length > 0) {
artist = track.getArtists()[0].getName(); artist = track.getArtists()[0].getName();
} }
} }
}
Intent intent = new Intent(MediaRouterPlayService.this, MainActivity.class); Intent intent = new Intent(MediaRouterPlayService.this, MainActivity.class);
intent.setAction("showRouteFragment"); intent.setAction("showRouteFragment");
Notification notification = new NotificationCompat.Builder(MediaRouterPlayService.this) Notification notification = new NotificationCompat.Builder(MediaRouterPlayService.this)
@ -207,10 +210,9 @@ public class MediaRouterPlayService extends Service {
pollStatus(); pollStatus();
PhoneCallListener phoneListener = new PhoneCallListener(); PhoneCallListener phoneListener = new PhoneCallListener();
TelephonyManager telephonyManager = (TelephonyManager) this TelephonyManager telephonyManager =
.getSystemService(Context.TELEPHONY_SERVICE); (TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE);
telephonyManager.listen(phoneListener, telephonyManager.listen(phoneListener, PhoneStateListener.LISTEN_CALL_STATE);
PhoneStateListener.LISTEN_CALL_STATE);
} }
@Override @Override
@ -225,8 +227,9 @@ public class MediaRouterPlayService extends Service {
*/ */
@Override @Override
public boolean onUnbind(Intent intent) { public boolean onUnbind(Intent intent) {
if (!mPollingStatus) if (!mPollingStatus) {
stopSelf(); stopSelf();
}
mBound = false; mBound = false;
return super.onUnbind(intent); return super.onUnbind(intent);
} }
@ -287,9 +290,10 @@ public class MediaRouterPlayService extends Service {
new CreateNotificationTask().execute(mPlaylist.get(mCurrentTrack) new CreateNotificationTask().execute(mPlaylist.get(mCurrentTrack)
.getFirstPropertyValue(DIDLObject.Property.UPNP.ALBUM_ART_URI.class)); .getFirstPropertyValue(DIDLObject.Property.UPNP.ALBUM_ART_URI.class));
if (mRouterFragment.get() != null) if (mRouterFragment.get() != null) {
mRouterFragment.get().scrollToCurrent(); mRouterFragment.get().scrollToCurrent();
} }
}
}); });
} }
@ -347,8 +351,7 @@ public class MediaRouterPlayService extends Service {
intent.addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK); intent.addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK);
intent.putExtra(MediaControlIntent.EXTRA_SESSION_ID, mSessionId); intent.putExtra(MediaControlIntent.EXTRA_SESSION_ID, mSessionId);
intent.putExtra(MediaControlIntent.EXTRA_ITEM_ID, mItemId); intent.putExtra(MediaControlIntent.EXTRA_ITEM_ID, mItemId);
intent.putExtra(MediaControlIntent.EXTRA_ITEM_CONTENT_POSITION, intent.putExtra(MediaControlIntent.EXTRA_ITEM_CONTENT_POSITION, (long) seconds * 1000);
(long) seconds * 1000);
mMediaRouter.getSelectedRoute().sendControlRequest(intent, null); mMediaRouter.getSelectedRoute().sendControlRequest(intent, null);
} }
@ -358,6 +361,9 @@ public class MediaRouterPlayService extends Service {
* @param playlist The media files in the playlist. * @param playlist The media files in the playlist.
*/ */
public void setPlaylist(List<Item> playlist) { public void setPlaylist(List<Item> playlist) {
mPlaylist = playlist; mPlaylist = playlist;
} }
@ -389,8 +395,9 @@ public class MediaRouterPlayService extends Service {
else { else {
// Playlist over, stop playback. // Playlist over, stop playback.
stop(); stop();
if (!mBound) if (!mBound) {
stopSelf(); stopSelf();
}
mPollingStatus = false; mPollingStatus = false;
return false; return false;
} }
@ -404,12 +411,14 @@ public class MediaRouterPlayService extends Service {
if (mCurrentTrack == -1) if (mCurrentTrack == -1)
return; return;
if (mShuffle) if (mShuffle) {
// Play random item. // Play random item.
play(new Random().nextInt(mPlaylist.size())); play(new Random().nextInt(mPlaylist.size()));
else }
else {
play(mCurrentTrack - 1); play(mCurrentTrack - 1);
} }
}
/** /**
* Returns index of the track that is currently played (zero-based). * Returns index of the track that is currently played (zero-based).
@ -437,17 +446,20 @@ public class MediaRouterPlayService extends Service {
if (status == null) if (status == null)
return; return;
if (mRouterFragment.get() != null) if (mRouterFragment.get() != null) {
mRouterFragment.get().receivePlaybackStatus(status); mRouterFragment.get().receivePlaybackStatus(status);
}
if (status.getPlaybackState() != MediaItemStatus.PLAYBACK_STATE_PENDING && if (status.getPlaybackState() != MediaItemStatus.PLAYBACK_STATE_PENDING &&
status.getPlaybackState() != MediaItemStatus.PLAYBACK_STATE_BUFFERING && status.getPlaybackState() != MediaItemStatus.PLAYBACK_STATE_BUFFERING &&
status.getPlaybackState() != MediaItemStatus.PLAYBACK_STATE_PLAYING) status.getPlaybackState() != MediaItemStatus.PLAYBACK_STATE_PLAYING) {
stopForeground(true); stopForeground(true);
}
if (status.getPlaybackState() == MediaItemStatus.PLAYBACK_STATE_FINISHED || if (status.getPlaybackState() == MediaItemStatus.PLAYBACK_STATE_FINISHED ||
status.getPlaybackState() == MediaItemStatus.PLAYBACK_STATE_CANCELED) status.getPlaybackState() == MediaItemStatus.PLAYBACK_STATE_CANCELED) {
playNext(); playNext();
} }
}
}); });
} }

View file

@ -27,12 +27,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.github.nutomic.controldlna.upnp; package com.github.nutomic.controldlna.upnp;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map.Entry;
import java.util.Random;
import android.content.ComponentName; import android.content.ComponentName;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
@ -54,10 +48,17 @@ import android.support.v7.media.MediaRouteProvider;
import android.support.v7.media.MediaRouteProviderDescriptor.Builder; import android.support.v7.media.MediaRouteProviderDescriptor.Builder;
import android.support.v7.media.MediaRouter; import android.support.v7.media.MediaRouter;
import android.support.v7.media.MediaRouter.ControlRequestCallback; import android.support.v7.media.MediaRouter.ControlRequestCallback;
import android.util.Log;
import android.util.Pair; import android.util.Pair;
import android.util.SparseArray; import android.util.SparseArray;
import android.widget.Toast; import android.widget.Toast;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map.Entry;
import java.util.Random;
/** /**
* Allows playing to a DLNA renderer from a remote app. * Allows playing to a DLNA renderer from a remote app.
* *
@ -65,6 +66,8 @@ import android.widget.Toast;
*/ */
final class Provider extends MediaRouteProvider { final class Provider extends MediaRouteProvider {
private static final String TAG = "Provider";
// Device has been added. // Device has been added.
// param: Device device // param: Device device
public static final int MSG_RENDERER_ADDED = 1; public static final int MSG_RENDERER_ADDED = 1;
@ -93,8 +96,8 @@ final class Provider extends MediaRouteProvider {
public int volume; public int volume;
public int volumeMax; public int volumeMax;
public static final Parcelable.Creator<Device> CREATOR public static final Parcelable.Creator<Device> CREATOR =
= new Parcelable.Creator<Device>() { new Parcelable.Creator<Device>() {
public Device createFromParcel(Parcel in) { public Device createFromParcel(Parcel in) {
return new Device(in); return new Device(in);
} }
@ -187,20 +190,18 @@ final class Provider extends MediaRouteProvider {
@Override @Override
public void handleMessage(Message msg) { public void handleMessage(Message msg) {
if (mService.get() != null) if (mService.get() != null) {
mService.get().handleMessage(msg); mService.get().handleMessage(msg);
} }
} }
}
final Messenger mListener = new Messenger(new DeviceListener(this)); final Messenger mListener = new Messenger(new DeviceListener(this));
public Provider(Context context) { public Provider(Context context) {
super(context); super(context);
context.bindService( context.bindService(new Intent(context, RemotePlayService.class),
new Intent(context, RemotePlayService.class), mConnection, Context.BIND_AUTO_CREATE);
mConnection,
Context.BIND_AUTO_CREATE
);
} }
public void close() { public void close() {
@ -210,9 +211,11 @@ final class Provider extends MediaRouteProvider {
@Override @Override
public void onDiscoveryRequestChanged(MediaRouteDiscoveryRequest request) { public void onDiscoveryRequestChanged(MediaRouteDiscoveryRequest request) {
try { try {
if (request != null && request.isActiveScan() && mIRemotePlayService != null) if (request != null && request.isActiveScan() && mIRemotePlayService != null) {
mIRemotePlayService.startSearch(mListener); mIRemotePlayService.startSearch(mListener);
} catch (RemoteException e) { }
}
catch (RemoteException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
@ -259,7 +262,8 @@ final class Provider extends MediaRouteProvider {
public void onSelect() { public void onSelect() {
try { try {
mIRemotePlayService.selectRenderer(mRouteId); mIRemotePlayService.selectRenderer(mRouteId);
} catch (RemoteException e) { }
catch (RemoteException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
@ -268,7 +272,8 @@ final class Provider extends MediaRouteProvider {
public void onUnselect() { public void onUnselect() {
try { try {
mIRemotePlayService.unselectRenderer(mRouteId); mIRemotePlayService.unselectRenderer(mRouteId);
} catch (RemoteException e) { }
catch (RemoteException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
@ -280,7 +285,8 @@ final class Provider extends MediaRouteProvider {
try { try {
mIRemotePlayService.setVolume(volume); mIRemotePlayService.setVolume(volume);
} catch (RemoteException e) { }
catch (RemoteException e) {
e.printStackTrace(); e.printStackTrace();
} }
mDevices.get(mRouteId).volume = volume; mDevices.get(mRouteId).volume = volume;
@ -323,10 +329,8 @@ final class Provider extends MediaRouteProvider {
} }
else if (intent.getAction().equals(MediaControlIntent.ACTION_SEEK)) { else if (intent.getAction().equals(MediaControlIntent.ACTION_SEEK)) {
mIRemotePlayService.seek(mRouteId, mIRemotePlayService.seek(mRouteId,
intent.getStringExtra( intent.getStringExtra(MediaControlIntent.EXTRA_ITEM_ID),
MediaControlIntent.EXTRA_ITEM_ID), intent.getLongExtra(MediaControlIntent.EXTRA_ITEM_CONTENT_POSITION, 0));
intent.getLongExtra(
MediaControlIntent.EXTRA_ITEM_CONTENT_POSITION, 0));
getItemStatus(intent, callback); getItemStatus(intent, callback);
return true; return true;
} }
@ -334,8 +338,9 @@ final class Provider extends MediaRouteProvider {
getItemStatus(intent, callback); getItemStatus(intent, callback);
return true; return true;
} }
} catch (RemoteException e) { }
e.printStackTrace(); catch (RemoteException e) {
Log.w(TAG, "Failed to execute control request", e);
} }
return false; return false;
} }
@ -357,8 +362,7 @@ final class Provider extends MediaRouteProvider {
mRequests.put(r, pair); mRequests.put(r, pair);
mIRemotePlayService.getItemStatus( mIRemotePlayService.getItemStatus(
intent.getStringExtra(MediaControlIntent.EXTRA_SESSION_ID), intent.getStringExtra(MediaControlIntent.EXTRA_SESSION_ID),
intent.getStringExtra(MediaControlIntent.EXTRA_ITEM_ID), intent.getStringExtra(MediaControlIntent.EXTRA_ITEM_ID), r);
r);
} }
/** /**
@ -382,12 +386,14 @@ final class Provider extends MediaRouteProvider {
mRequests.get(data.getInt("hash")); mRequests.get(data.getInt("hash"));
Bundle status = data.getBundle("media_item_status"); Bundle status = data.getBundle("media_item_status");
if (pair.first.hasExtra(MediaControlIntent.EXTRA_SESSION_ID)) if (pair.first.hasExtra(MediaControlIntent.EXTRA_SESSION_ID)) {
status.putString(MediaControlIntent.EXTRA_SESSION_ID, status.putString(MediaControlIntent.EXTRA_SESSION_ID,
pair.first.getStringExtra(MediaControlIntent.EXTRA_SESSION_ID)); pair.first.getStringExtra(MediaControlIntent.EXTRA_SESSION_ID));
if (pair.first.hasExtra(MediaControlIntent.EXTRA_ITEM_ID)) }
if (pair.first.hasExtra(MediaControlIntent.EXTRA_ITEM_ID)) {
status.putString(MediaControlIntent.EXTRA_ITEM_ID, status.putString(MediaControlIntent.EXTRA_ITEM_ID,
pair.first.getStringExtra(MediaControlIntent.EXTRA_ITEM_ID)); pair.first.getStringExtra(MediaControlIntent.EXTRA_ITEM_ID));
}
pair.second.onResult(status); pair.second.onResult(status);
break; break;
case MSG_ERROR: case MSG_ERROR:

View file

@ -36,8 +36,9 @@ public class ProviderService extends MediaRouteProviderService {
@Override @Override
public MediaRouteProvider onCreateMediaRouteProvider() { public MediaRouteProvider onCreateMediaRouteProvider() {
if (mProvider == null) if (mProvider == null) {
mProvider = new Provider(this); mProvider = new Provider(this);
}
return mProvider; return mProvider;
} }

View file

@ -87,11 +87,14 @@ public class RemotePlayService extends Service implements RegistryListener {
public void onServiceConnected(ComponentName className, IBinder service) { public void onServiceConnected(ComponentName className, IBinder service) {
mUpnpService = (AndroidUpnpService) service; mUpnpService = (AndroidUpnpService) service;
mUpnpService.getRegistry().addListener(RemotePlayService.this); mUpnpService.getRegistry().addListener(RemotePlayService.this);
for (Device<?, ?, ?> d : mUpnpService.getControlPoint().getRegistry().getDevices()) for (Device<?, ?, ?> d : mUpnpService.getControlPoint().getRegistry().getDevices()) {
if (d instanceof LocalDevice) if (d instanceof LocalDevice) {
localDeviceAdded(mUpnpService.getRegistry(), (LocalDevice) d); localDeviceAdded(mUpnpService.getRegistry(), (LocalDevice) d);
else }
else {
remoteDeviceAdded(mUpnpService.getRegistry(), (RemoteDevice) d); remoteDeviceAdded(mUpnpService.getRegistry(), (RemoteDevice) d);
}
}
mUpnpService.getControlPoint().search(); mUpnpService.getControlPoint().search();
} }
@ -119,11 +122,8 @@ public class RemotePlayService extends Service implements RegistryListener {
@Override @Override
public void onCreate() { public void onCreate() {
super.onCreate(); super.onCreate();
bindService( bindService(new Intent(this, AndroidUpnpServiceImpl.class),
new Intent(this, AndroidUpnpServiceImpl.class), mUpnpServiceConnection, Context.BIND_AUTO_CREATE);
mUpnpServiceConnection,
Context.BIND_AUTO_CREATE
);
IntentFilter filter = new IntentFilter(); IntentFilter filter = new IntentFilter();
filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION); filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
@ -144,7 +144,8 @@ public class RemotePlayService extends Service implements RegistryListener {
void sendMessage(Message msg) { void sendMessage(Message msg) {
try { try {
mListener.send(msg); mListener.send(msg);
} catch (RemoteException e) { }
catch (RemoteException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
@ -173,22 +174,29 @@ public class RemotePlayService extends Service implements RegistryListener {
if (wifi.isConnected()) { if (wifi.isConnected()) {
if (mUpnpService != null) { if (mUpnpService != null) {
for (Device<?, ?, ?> d : mUpnpService.getControlPoint().getRegistry().getDevices()) for (Device<?, ?, ?> d :
mUpnpService.getControlPoint().getRegistry().getDevices()) {
deviceAdded(d); deviceAdded(d);
}
mUpnpService.getControlPoint().search(); mUpnpService.getControlPoint().search();
} }
} else }
for (Entry<String, Device<?, ?, ?>> d : mDevices.entrySet()) else {
for (Entry<String, Device<?, ?, ?>> d : mDevices.entrySet()) {
if (mUpnpService.getControlPoint().getRegistry() if (mUpnpService.getControlPoint().getRegistry()
.getDevice(new UDN(d.getKey()), false) == null) { .getDevice(new UDN(d.getKey()), false) == null) {
deviceRemoved(d.getValue()); deviceRemoved(d.getValue());
for (RemotePlayServiceBinder b : mBinders.keySet()) for (RemotePlayServiceBinder b : mBinders.keySet()) {
if (b.mCurrentRenderer != null && b.mCurrentRenderer.equals(d.getValue())) { if (b.mCurrentRenderer != null &&
b.mCurrentRenderer.equals(d.getValue())) {
b.mSubscriptionCallback.end(); b.mSubscriptionCallback.end();
b.mCurrentRenderer = null; b.mCurrentRenderer = null;
} }
} }
} }
}
}
}
}; };
/** /**
@ -196,8 +204,7 @@ public class RemotePlayService extends Service implements RegistryListener {
*/ */
org.teleal.cling.model.meta.Service<?, ?> getService( org.teleal.cling.model.meta.Service<?, ?> getService(
Device<?, ?, ?> device, String name) { Device<?, ?, ?> device, String name) {
return device.findService( return device.findService(new ServiceType("schemas-upnp-org", name));
new ServiceType("schemas-upnp-org", name));
} }
/** /**
@ -207,8 +214,7 @@ public class RemotePlayService extends Service implements RegistryListener {
if (mDevices.containsValue(device)) if (mDevices.containsValue(device))
return; return;
final org.teleal.cling.model.meta.Service<?, ?> rc = final org.teleal.cling.model.meta.Service<?, ?> rc = getService(device, "RenderingControl");
getService(device, "RenderingControl");
if (rc == null || mListener == null) if (rc == null || mListener == null)
return; return;
@ -233,7 +239,8 @@ public class RemotePlayService extends Service implements RegistryListener {
int maxVolume = 100; int maxVolume = 100;
if (rc.getStateVariable("Volume") != null) { if (rc.getStateVariable("Volume") != null) {
StateVariableAllowedValueRange volumeRange = StateVariableAllowedValueRange volumeRange =
rc.getStateVariable("Volume").getTypeDetails().getAllowedValueRange(); rc.getStateVariable("Volume")
.getTypeDetails().getAllowedValueRange();
maxVolume = (int) volumeRange.getMaximum(); maxVolume = (int) volumeRange.getMaximum();
} }

View file

@ -83,25 +83,26 @@ public class RemotePlayServiceBinder extends IRemotePlayService.Stub {
private RemotePlayService mRps; private RemotePlayService mRps;
private boolean mStartingPlayback = false; private boolean mStartingPlayback = false;
public RemotePlayServiceBinder(RemotePlayService rps) { public RemotePlayServiceBinder(RemotePlayService rps) {
mRps = rps; mRps = rps;
} }
@Override @Override
public void startSearch(Messenger listener) public void startSearch(Messenger listener) throws RemoteException {
throws RemoteException {
mRps.mListener = listener; mRps.mListener = listener;
} }
@Override @Override
public void selectRenderer(String id) throws RemoteException { public void selectRenderer(String id) throws RemoteException {
mCurrentRenderer = mRps.mDevices.get(id); mCurrentRenderer = mRps.mDevices.get(id);
for (RemotePlayServiceBinder b : mRps.mBinders.keySet()) for (RemotePlayServiceBinder b : mRps.mBinders.keySet()) {
if (b != this && mCurrentRenderer.equals(b.mCurrentRenderer)) if (b != this && mCurrentRenderer.equals(b.mCurrentRenderer)) {
b.unselectRenderer(""); b.unselectRenderer("");
}
}
mSubscriptionCallback = new SubscriptionCallback( mSubscriptionCallback = new SubscriptionCallback(mCurrentRenderer.findService(
mCurrentRenderer.findService(
new ServiceType("schemas-upnp-org", "AVTransport")), 600) { new ServiceType("schemas-upnp-org", "AVTransport")), 600) {
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
@ -111,8 +112,7 @@ public class RemotePlayServiceBinder extends IRemotePlayService.Stub {
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
@Override @Override
protected void ended(GENASubscription sub, CancelReason reason, protected void ended(GENASubscription sub, CancelReason reason, UpnpResponse response) {
UpnpResponse response) {
} }
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
@ -121,16 +121,14 @@ public class RemotePlayServiceBinder extends IRemotePlayService.Stub {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
Map<String, StateVariableValue> m = sub.getCurrentValues(); Map<String, StateVariableValue> m = sub.getCurrentValues();
try { try {
LastChange lastChange = new LastChange( LastChange lastChange = new LastChange(new AVTransportLastChangeParser(),
new AVTransportLastChangeParser(),
m.get("LastChange").toString()); m.get("LastChange").toString());
if (mStartingPlayback || lastChange.getEventedValue(0, if (mStartingPlayback || lastChange.getEventedValue(0,
AVTransportVariable.TransportState.class) == null) AVTransportVariable.TransportState.class) == null)
return; return;
switch (lastChange.getEventedValue(0, switch (lastChange.getEventedValue(0,
AVTransportVariable.TransportState.class) AVTransportVariable.TransportState.class).getValue()) {
.getValue()) {
case PLAYING: case PLAYING:
mPlaybackState = MediaItemStatus.PLAYBACK_STATE_PLAYING; mPlaybackState = MediaItemStatus.PLAYBACK_STATE_PLAYING;
break; break;
@ -149,7 +147,8 @@ public class RemotePlayServiceBinder extends IRemotePlayService.Stub {
default: default:
} }
} catch (Exception e) { }
catch (Exception e) {
Log.w(TAG, "Failed to parse UPNP event", e); Log.w(TAG, "Failed to parse UPNP event", e);
mRps.sendError("Failed to parse UPNP event"); mRps.sendError("Failed to parse UPNP event");
} }
@ -157,8 +156,7 @@ public class RemotePlayServiceBinder extends IRemotePlayService.Stub {
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
@Override @Override
protected void eventsMissed(GENASubscription sub, protected void eventsMissed(GENASubscription sub, int numberOfMissedEvents) {
int numberOfMissedEvents) {
} }
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
@ -177,10 +175,12 @@ public class RemotePlayServiceBinder extends IRemotePlayService.Stub {
*/ */
@Override @Override
public void unselectRenderer(String sessionId) throws RemoteException { public void unselectRenderer(String sessionId) throws RemoteException {
if (mRps.mDevices.get(sessionId) != null) if (mRps.mDevices.get(sessionId) != null) {
stop(sessionId); stop(sessionId);
if (mSubscriptionCallback != null) }
if (mSubscriptionCallback != null) {
mSubscriptionCallback.end(); mSubscriptionCallback.end();
}
mCurrentRenderer = null; mCurrentRenderer = null;
} }
@ -284,8 +284,10 @@ public class RemotePlayServiceBinder extends IRemotePlayService.Stub {
// Sometimes stop works even though pause does not. // Sometimes stop works even though pause does not.
try { try {
stop(sessionId); stop(sessionId);
} catch (RemoteException e) { }
e.printStackTrace(); catch (RemoteException e) {
Log.w(TAG, "Calling stop failed", e);
mRps.sendError("Calling stop failed: " + e.toString());
} }
} }
}); });
@ -372,6 +374,7 @@ public class RemotePlayServiceBinder extends IRemotePlayService.Stub {
public void failure(ActionInvocation invocation, public void failure(ActionInvocation invocation,
UpnpResponse operation, String defaultMessage) { UpnpResponse operation, String defaultMessage) {
Log.w(TAG, "Get position failed: " + defaultMessage); Log.w(TAG, "Get position failed: " + defaultMessage);
mRps.sendError("Get position failed: " + defaultMessage);
} }
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
@ -382,7 +385,8 @@ public class RemotePlayServiceBinder extends IRemotePlayService.Stub {
Builder status = null; Builder status = null;
status = new MediaItemStatus.Builder(mPlaybackState); status = new MediaItemStatus.Builder(mPlaybackState);
if (positionInfo.getTrackURI() != null && positionInfo.getTrackURI().equals(itemId)) { if (positionInfo.getTrackURI() != null &&
positionInfo.getTrackURI().equals(itemId)) {
try { try {
status.setContentPosition(positionInfo.getTrackElapsedSeconds() * 1000) status.setContentPosition(positionInfo.getTrackElapsedSeconds() * 1000)
.setContentDuration(positionInfo.getTrackDurationSeconds() * 1000) .setContentDuration(positionInfo.getTrackDurationSeconds() * 1000)
@ -390,6 +394,8 @@ public class RemotePlayServiceBinder extends IRemotePlayService.Stub {
} }
catch (NumberFormatException e) { catch (NumberFormatException e) {
Log.d(TAG, "Failed to read track position or duration", e); Log.d(TAG, "Failed to read track position or duration", e);
mRps.sendError("Failed to read track position or duration: " +
e.toString());
} }
} }

View file

@ -27,16 +27,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.github.nutomic.controldlna.utility; package com.github.nutomic.controldlna.utility;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Comparator;
import org.teleal.cling.model.meta.Device;
import org.teleal.cling.model.meta.LocalDevice;
import org.teleal.cling.model.meta.RemoteDevice;
import org.teleal.cling.registry.Registry;
import org.teleal.cling.registry.RegistryListener;
import android.app.Activity; import android.app.Activity;
import android.content.Context; import android.content.Context;
import android.util.Log; import android.util.Log;
@ -48,6 +38,16 @@ import android.widget.TextView;
import com.github.nutomic.controldlna.R; import com.github.nutomic.controldlna.R;
import org.teleal.cling.model.meta.Device;
import org.teleal.cling.model.meta.LocalDevice;
import org.teleal.cling.model.meta.RemoteDevice;
import org.teleal.cling.registry.Registry;
import org.teleal.cling.registry.RegistryListener;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Comparator;
/** /**
* Displays the devices that are inserted through the RegistryListener (either * Displays the devices that are inserted through the RegistryListener (either
* of type RENDERER or SERVER). * of type RENDERER or SERVER).
@ -60,8 +60,6 @@ public class DeviceArrayAdapter extends ArrayAdapter<Device<?, ?, ?>>
private static final String TAG = "DeviceArrayAdapter"; private static final String TAG = "DeviceArrayAdapter";
public static final String RENDERER = "MediaRenderer";
public static final String SERVER = "MediaServer"; public static final String SERVER = "MediaServer";
private Activity mActivity; private Activity mActivity;
@ -91,15 +89,16 @@ public class DeviceArrayAdapter extends ArrayAdapter<Device<?, ?, ?>>
if (getItem(position).hasIcons()) { if (getItem(position).hasIcons()) {
URI uri = getItem(position).getIcons()[0].getUri(); URI uri = getItem(position).getIcons()[0].getUri();
if (getItem(position) instanceof RemoteDevice) if (getItem(position) instanceof RemoteDevice) {
try { try {
RemoteDevice device = (RemoteDevice) getItem(position); RemoteDevice device = (RemoteDevice) getItem(position);
uri = device.normalizeURI(uri).toURI(); uri = device.normalizeURI(uri).toURI();
} catch (URISyntaxException e) { }
catch (URISyntaxException e) {
Log.w(TAG, "Failed to get device icon URI", e); Log.w(TAG, "Failed to get device icon URI", e);
} }
RemoteImageView icon = }
(RemoteImageView) convertView.findViewById(R.id.image); RemoteImageView icon = (RemoteImageView) convertView.findViewById(R.id.image);
icon.setImageUri(uri); icon.setImageUri(uri);
} }
@ -110,9 +109,11 @@ public class DeviceArrayAdapter extends ArrayAdapter<Device<?, ?, ?>>
* Adds a new device to the list if its type equals mDeviceType. * Adds a new device to the list if its type equals mDeviceType.
*/ */
public void deviceAdded(final Device<?, ?, ?> device) { public void deviceAdded(final Device<?, ?, ?> device) {
for (int i = 0; i < getCount(); i++) for (int i = 0; i < getCount(); i++) {
if (getItem(i).equals(device)) if (getItem(i).equals(device)) {
return; return;
}
}
mActivity.runOnUiThread(new Runnable() { mActivity.runOnUiThread(new Runnable() {
@ -141,9 +142,10 @@ public class DeviceArrayAdapter extends ArrayAdapter<Device<?, ?, ?>>
@Override @Override
public void run() { public void run() {
if (getPosition(device) != -1) if (getPosition(device) != -1) {
remove(device); remove(device);
} }
}
}); });
} }

View file

@ -80,30 +80,36 @@ public class FileArrayAdapter extends ArrayAdapter<DIDLObject> {
? Integer.toString(track.getOriginalTrackNumber()) + ". " ? Integer.toString(track.getOriginalTrackNumber()) + ". "
: ""; : "";
title.setText(trackNumber + item.getTitle()); title.setText(trackNumber + item.getTitle());
if (track.getArtists().length > 0) if (track.getArtists().length > 0) {
artist.setText(track.getArtists()[0].getName()); artist.setText(track.getArtists()[0].getName());
} }
else }
else {
title.setText(item.getTitle()); title.setText(item.getTitle());
}
RemoteImageView image = (RemoteImageView) convertView.findViewById(R.id.image); RemoteImageView image = (RemoteImageView) convertView.findViewById(R.id.image);
URI icon = item.getFirstPropertyValue( URI icon = item.getFirstPropertyValue(DIDLObject.Property.UPNP.ALBUM_ART_URI.class);
DIDLObject.Property.UPNP.ALBUM_ART_URI.class);
if (icon != null) { if (icon != null) {
image.setImageUri(icon); image.setImageUri(icon);
} }
else { else {
int resId; int resId;
if (item instanceof AudioItem) if (item instanceof AudioItem) {
resId = R.drawable.ic_doc_audio_am; resId = R.drawable.ic_doc_audio_am;
else if (item instanceof VideoItem) }
else if (item instanceof VideoItem) {
resId = R.drawable.ic_doc_video_am; resId = R.drawable.ic_doc_video_am;
else if (item instanceof ImageItem) }
else if (item instanceof ImageItem) {
resId = R.drawable.ic_doc_image; resId = R.drawable.ic_doc_image;
else if (item instanceof PlaylistItem) }
else if (item instanceof PlaylistItem) {
resId = R.drawable.ic_doc_album; resId = R.drawable.ic_doc_album;
else }
else {
resId = R.drawable.ic_root_folder_am; resId = R.drawable.ic_root_folder_am;
}
image.setImageResource(resId); image.setImageResource(resId);
} }
@ -114,8 +120,9 @@ public class FileArrayAdapter extends ArrayAdapter<DIDLObject> {
* Replacement for addAll, which is not implemented on lower API levels. * Replacement for addAll, which is not implemented on lower API levels.
*/ */
public void add(List<Item> playlist) { public void add(List<Item> playlist) {
for (DIDLObject d : playlist) for (DIDLObject d : playlist) {
add(d); add(d);
} }
}
} }

View file

@ -40,7 +40,7 @@ import android.os.AsyncTask;
import android.util.Log; import android.util.Log;
/** /**
* Handles background task of loading a bitmap by URI. * Loads an image by URI in the background and returns it.
* *
* @author Felix Ableitner * @author Felix Ableitner
* *
@ -56,15 +56,15 @@ public class LoadImageTask extends AsyncTask<URI, Void, Bitmap> {
Bitmap bm = null; Bitmap bm = null;
try { try {
URLConnection conn = new URL(uri[0].toString()) URLConnection conn = new URL(uri[0].toString()).openConnection();
.openConnection();
conn.connect(); conn.connect();
InputStream is = conn.getInputStream(); InputStream is = conn.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is); BufferedInputStream bis = new BufferedInputStream(is);
bm = BitmapFactory.decodeStream(bis); bm = BitmapFactory.decodeStream(bis);
bis.close(); bis.close();
is.close(); is.close();
} catch (IOException e) { }
catch (IOException e) {
Log.w(TAG, "Failed to load artwork image", e); Log.w(TAG, "Failed to load artwork image", e);
} }
return bm; return bm;

View file

@ -52,9 +52,10 @@ public class RemoteImageView extends ImageView {
@Override @Override
protected void onPostExecute(Bitmap bm) { protected void onPostExecute(Bitmap bm) {
if (bm != null) if (bm != null) {
setImageBitmap(bm); setImageBitmap(bm);
} }
}
}; };